Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'incoming'

  • Loading branch information...
commit b614f2bc5d9fc421565824b1ceb9a3384f26f35f 2 parents c70758e + 7eaa780
@kripken authored
Showing with 11,177 additions and 63 deletions.
  1. +2 −1  AUTHORS
  2. +36 −2 emcc
  3. +23 −8 src/compiler.js
  4. +18 −1 src/jsifier.js
  5. +118 −1 src/library.js
  6. +7 −2 src/library_browser.js
  7. +4 −6 src/library_glut.js
  8. +1 −2  src/library_sdl.js
  9. +1 −2  src/library_xlib.js
  10. +5 −0 src/modules.js
  11. +9 −1 src/settings.js
  12. +4 −0 system/include/net/arpa/inet.h
  13. +2 −0  system/include/sys/ioctl.h
  14. +1 −0  system/include/sys/socket.h
  15. +1 −0  system/lib/dlmalloc.c
  16. +254 −5 tests/runner.py
  17. +3 −0  tests/socket_server.sh
  18. +125 −0 tests/websockets.c
  19. +10 −0 third_party/websockify/.gitignore
  20. +18 −0 third_party/websockify/CHANGES.txt
  21. +11 −0 third_party/websockify/LICENSE.txt
  22. +1 −0  third_party/websockify/MANIFEST.in
  23. +11 −0 third_party/websockify/Makefile
  24. +155 −0 third_party/websockify/README.md
  25. +39 −0 third_party/websockify/Windows/Windows Service Readme.txt
  26. +24 −0 third_party/websockify/Windows/noVNC Websocket Service Project/Program.cs
  27. +61 −0 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.Designer.cs
  28. +19 −0 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.cs
  29. +129 −0 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.resx
  30. +36 −0 third_party/websockify/Windows/noVNC Websocket Service Project/Properties/AssemblyInfo.cs
  31. +37 −0 third_party/websockify/Windows/noVNC Websocket Service Project/Service1.Designer.cs
  32. +41 −0 third_party/websockify/Windows/noVNC Websocket Service Project/Service1.cs
  33. +75 −0 third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.csproj
  34. +20 −0 third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.sln
  35. +621 −0 third_party/websockify/docs/LICENSE.GPL-3
  36. +165 −0 third_party/websockify/docs/LICENSE.LGPL-3
  37. +9 −0 third_party/websockify/docs/TODO
  38. +4 −0 third_party/websockify/docs/flash_policy.txt
  39. +114 −0 third_party/websockify/docs/latency_results.txt
  40. +17 −0 third_party/websockify/docs/notes
  41. +9 −0 third_party/websockify/docs/release.txt
  42. +110 −0 third_party/websockify/docs/websockify.1
  43. +919 −0 third_party/websockify/include/VT100.js
  44. +147 −0 third_party/websockify/include/base64.js
  45. +99 −0 third_party/websockify/include/keysym.js
  46. +303 −0 third_party/websockify/include/util.js
  47. +109 −0 third_party/websockify/include/web-socket-js/README.txt
  48. BIN  third_party/websockify/include/web-socket-js/WebSocketMain.swf
  49. +4 −0 third_party/websockify/include/web-socket-js/swfobject.js
  50. +391 −0 third_party/websockify/include/web-socket-js/web_socket.js
  51. +427 −0 third_party/websockify/include/websock.js
  52. +148 −0 third_party/websockify/include/webutil.js
  53. +235 −0 third_party/websockify/include/wsirc.js
  54. +335 −0 third_party/websockify/include/wstelnet.js
  55. +14 −0 third_party/websockify/other/Makefile
  56. +51 −0 third_party/websockify/other/README.md
  57. +108 −0 third_party/websockify/other/launch.sh
  58. +13 −0 third_party/websockify/other/project.clj
  59. +802 −0 third_party/websockify/other/websocket.c
  60. +84 −0 third_party/websockify/other/websocket.h
  61. +456 −0 third_party/websockify/other/websocket.rb
  62. +385 −0 third_party/websockify/other/websockify.c
  63. +233 −0 third_party/websockify/other/websockify.clj
  64. +141 −0 third_party/websockify/other/websockify.js
  65. +171 −0 third_party/websockify/other/websockify.rb
  66. +22 −0 third_party/websockify/other/wswrap
  67. +18 −0 third_party/websockify/rebind
  68. +94 −0 third_party/websockify/rebind.c
  69. +5 −0 third_party/websockify/run
  70. +30 −0 third_party/websockify/setup.py
  71. +29 −0 third_party/websockify/tests/b64_vs_utf8.py
  72. +91 −0 third_party/websockify/tests/base64.html
  73. +12 −0 third_party/websockify/tests/base64.js
  74. +148 −0 third_party/websockify/tests/echo.html
  75. +75 −0 third_party/websockify/tests/echo.py
  76. +62 −0 third_party/websockify/tests/echo.rb
  77. +1 −0  third_party/websockify/tests/include
  78. +290 −0 third_party/websockify/tests/latency.html
  79. +1 −0  third_party/websockify/tests/latency.py
  80. +250 −0 third_party/websockify/tests/load.html
  81. +167 −0 third_party/websockify/tests/load.py
  82. +168 −0 third_party/websockify/tests/plain_echo.html
  83. +68 −0 third_party/websockify/tests/simple.html
  84. +22 −0 third_party/websockify/tests/utf8-list.py
  85. +1 −0  third_party/websockify/websockify.py
  86. +2 −0  third_party/websockify/websockify/__init__.py
  87. +965 −0 third_party/websockify/websockify/websocket.py
  88. +390 −0 third_party/websockify/websockify/websocketproxy.py
  89. +99 −0 third_party/websockify/wsirc.html
  90. +74 −0 third_party/websockify/wstelnet.html
  91. +5 −2 tools/file_packager.py
  92. +23 −16 tools/js-optimizer.js
  93. +5 −5 tools/settings_template_readonly.py
  94. +41 −9 tools/shared.py
  95. +94 −0 tools/split.py
View
3  AUTHORS
@@ -26,7 +26,7 @@ a license to everyone to use it as detailed in LICENSE.)
* Jon Bardin <diclophis@gmail.com>
* Jukka Jyl�nki <jujjyl@gmail.com>
* Aleksander Guryanov <caiiiycuk@gmail.com>
-* Chad Austin <chad@chadaustin.me>
+* Chad Austin <chad@chadaustin.me> (copyright owned by IMVU)
* nandhp <nandhp@gmail.com>
* YeZhongWen <linghuye2.0@gmail.com>
* Xingxing Pan <forandom@gmail.com>
@@ -37,3 +37,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Benjamin Stover <benjamin.stover@gmail.com>
* Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
* Janus Troelsen <janus.troelsen@stud.tu-darmstadt.de>
+* Lars Schneider <lars.schneider@autodesk.com> (copyright owned by Autodesk, Inc.)
View
38 emcc
@@ -268,6 +268,27 @@ Options that are modified or new in %s include:
will not minify the code (closure does
that)
+ --split <size> Splits the resulting javascript file into pieces
+ to ease debugging. This option only works if
+ Javascript is generated (target -o <name>.js).
+ Files with function declarations must be loaded
+ before main file upon execution.
+
+ Without "-g" option:
+ Creates files with function declarations up
+ to the given size with the suffix
+ "_functions.partxxx.js" and a main file with
+ the suffix ".js".
+
+ With "-g" option:
+ Recreates the directory structure of the C
+ source files and stores function declarations
+ in their respective C files with the suffix
+ ".js". If such a file exceeds the given size,
+ files with the suffix ".partxxx.js" are created.
+ The main file resides in the base directory and
+ has the suffix ".js".
+
--ignore-dynamic-linking Normally emcc will treat dynamic linking like
static linking, by linking in the code from
the dynamic library. This fails if the same
@@ -471,6 +492,7 @@ try:
pre_js = ''
post_js = ''
minify_whitespace = None
+ split_js_file = None
preload_files = []
embed_files = []
compression = None
@@ -527,6 +549,11 @@ try:
minify_whitespace = int(newargs[i+1])
newargs[i] = ''
newargs[i+1] = ''
+ elif newargs[i].startswith('--split'):
+ check_bad_eq(newargs[i])
+ split_js_file = int(newargs[i+1])
+ newargs[i] = ''
+ newargs[i+1] = ''
elif newargs[i].startswith('--embed-file'):
check_bad_eq(newargs[i])
embed_files.append(newargs[i+1])
@@ -601,6 +628,9 @@ try:
newargs[i+1] = ''
newargs = [ arg for arg in newargs if arg is not '' ]
+ if split_js_file:
+ settings_changes.append("PRINT_SPLIT_FILE_MARKER=1")
+
# Find input files
input_files = []
@@ -1071,8 +1101,12 @@ try:
html.close()
else:
- # copy final JS to output
- shutil.move(final, target)
+ if split_js_file:
+ from tools.split import split_javascript_file
+ split_javascript_file(final, unsuffixed(target), split_js_file)
+ else:
+ # copy final JS to output
+ shutil.move(final, target)
finally:
if not TEMP_DIR:
View
31 src/compiler.js
@@ -31,15 +31,30 @@ if (ENVIRONMENT_IS_NODE) {
var nodeFS = require('fs');
var nodePath = require('path');
- read = function(filename) {
- filename = nodePath['normalize'](filename);
- var ret = nodeFS['readFileSync'](filename).toString();
- // The path is absolute if the normalized version is the same as the resolved.
- if (!ret && filename != nodePath['resolve'](filename)) {
- filename = path.join(__dirname, '..', 'src', filename);
- ret = nodeFS['readFileSync'](filename).toString();
+ if (!nodeFS.existsSync) {
+ nodeFS.existsSync = function(path) {
+ try {
+ return !!nodeFS.readFileSync(path);
+ } catch(e) {
+ return false;
+ }
+ }
+ }
+
+ function find(filename) {
+ var prefixes = [__dirname, process.cwd()];
+ for (var i = 0; i < prefixes.length; ++i) {
+ var combined = nodePath.join(prefixes[i], filename);
+ if (nodeFS.existsSync(combined)) {
+ return combined;
+ }
}
- return ret;
+ return filename;
+ }
+
+ read = function(filename) {
+ var absolute = find(filename);
+ return nodeFS['readFileSync'](absolute).toString();
};
load = function(f) {
View
19 src/jsifier.js
@@ -32,7 +32,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// else. This lets us not hold any strings in memory, we simply print
// things out as they are ready.
- var shellFile = BUILD_AS_SHARED_LIB ? 'shell_sharedlib.js' : 'shell.js';
+ var shellFile = SHELL_FILE ? SHELL_FILE : (BUILD_AS_SHARED_LIB ? 'shell_sharedlib.js' : 'shell.js');
var shellParts = read(shellFile).split('{{BODY}}');
print(shellParts[0]);
var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js';
@@ -522,6 +522,11 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += ' */\n';
}
+ if (PRINT_SPLIT_FILE_MARKER) {
+ func.JS += '\n//FUNCTION_BEGIN_MARKER\n'
+ var associatedSourceFile = "NO_SOURCE";
+ }
+
func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n';
if (PROFILE) {
@@ -572,6 +577,13 @@ function JSify(data, functionsOnly, givenFunctions) {
if (EXECUTION_TIMEOUT > 0) {
ret += indent + 'if (Date.now() - START_TIME >= ' + (EXECUTION_TIMEOUT*1000) + ') throw "Timed out!" + (new Error().stack);\n';
}
+
+ if (PRINT_SPLIT_FILE_MARKER && Debugging.on && Debugging.getAssociatedSourceFile(line.lineNum)) {
+ // Overwrite the associated source file for every line. The last line should contain the source file associated to
+ // the return value/address of outer most block (the marked function).
+ associatedSourceFile = Debugging.getAssociatedSourceFile(line.lineNum);
+ }
+
// for special labels we care about (for phi), mark that we visited them
return ret + label.lines.map(function(line) { return line.JS + (Debugging.on ? Debugging.getComment(line.lineNum) : '') })
.join('\n')
@@ -653,6 +665,11 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += ' return' + (func.returnType !== 'void' ? ' null' : '') + ';\n';
}
func.JS += '}\n';
+
+ if (PRINT_SPLIT_FILE_MARKER) {
+ func.JS += '\n//FUNCTION_END_MARKER_OF_SOURCE_FILE_' + associatedSourceFile + '\n';
+ }
+
if (func.ident in EXPORTED_FUNCTIONS) {
func.JS += 'Module["' + func.ident + '"] = ' + func.ident + ';';
}
View
119 src/library.js
@@ -4850,6 +4850,7 @@ LibraryManager.library = {
// RTTI hacks for exception handling, defining type_infos for common types.
// The values are dummies. We simply use the addresses of these statically
// allocated variables as unique identifiers.
+ _ZTIb: [0], // bool
_ZTIi: [0], // int
_ZTIj: [0], // unsigned int
_ZTIl: [0], // long
@@ -4863,7 +4864,7 @@ LibraryManager.library = {
_ZTIa: [0], // signed char
_ZTIh: [0], // unsigned char
_ZTIs: [0], // short
- _ZTIt: [0], // signed short
+ _ZTIt: [0], // unsigned short
_ZTIv: [0], // void
_ZTIPv: [0], // void*
@@ -6314,6 +6315,122 @@ LibraryManager.library = {
ntohl: 'htonl',
ntohs: 'htons',
+ inet_pton__deps: ['__setErrNo', '$ERRNO_CODES'],
+ inet_pton: function(af, src, dst) {
+ // int af, const char *src, void *dst
+ if ((af ^ {{{ cDefine("AF_INET") }}}) !== 0) { ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); return -1; }
+ var b = Pointer_stringify(src).split(".");
+ if (b.length !== 4) return 0;
+ var ret = Number(b[0]) | (Number(b[1]) << 8) | (Number(b[2]) << 16) | (Number(b[3]) << 24);
+ if (isNaN(ret)) return 0;
+ setValue(dst, ret, 'i32');
+ return 1;
+ },
+
+ _inet_ntop_raw: function(addr) {
+ return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff)
+ },
+
+ inet_ntop__deps: ['_inet_ntop_raw'],
+ inet_ntop: function(af, src, dst, size) {
+ var addr = getValue(src, 'i32');
+ var str = __inet_ntop_raw(addr);
+ writeStringToMemory(str.substr(0, size), dst, true);
+ return dst;
+ },
+
+ // ==========================================================================
+ // sockets
+ // ==========================================================================
+
+ $Sockets__deps: ['__setErrNo', '$ERRNO_CODES'],
+ $Sockets: {
+ BUFFER_SIZE: 10*1024,
+ nextFd: 1,
+ fds: {},
+ sockaddr_in_layout: Runtime.generateStructInfo([
+ ['i16', 'sin_family'],
+ ['i16', 'sin_port'],
+ ['i32', 'sin_addr'],
+ ['i64', 'sin_zero'],
+ ]),
+ },
+
+ socket__deps: ['$Sockets'],
+ socket: function(family, type, protocol) {
+ var fd = Sockets.nextFd++;
+ Sockets.fds[fd] = {
+ connected: false
+ };
+ return fd;
+ },
+
+ connect__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs'],
+ connect: function(fd, addr, addrlen) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ info.connected = true;
+ info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32');
+ info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16'));
+ info.host = __inet_ntop_raw(info.addr);
+ info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['arraybuffer']);
+ info.socket.binaryType = 'arraybuffer';
+ info.buffer = new Uint8Array(Sockets.BUFFER_SIZE);
+ info.bufferWrite = info.bufferRead = 0;
+ info.socket.onmessage = function (event) {
+ var data = event.data;
+ if (typeof data == 'string') {
+ var binaryString = window.atob(data);
+ var len = binaryString.length;
+ for (var i = 0; i < len; i++) {
+ info.buffer[info.bufferWrite++] = binaryString.charCodeAt(i);
+ if (info.bufferWrite == Sockets.BUFFER_SIZE) info.bufferWrite = 0;
+ if (info.bufferWrite == info.bufferRead) throw 'socket buffer overflow';
+ }
+ } else {
+ console.log('binary!');
+ }
+ }
+ return 0;
+ },
+
+ recv__deps: ['$Sockets'],
+ recv: function(fd, buf, len, flags) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ if (info.bufferWrite == info.bufferRead) {
+ ___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior
+ return 0; // should this be -1 like the spec says?
+ }
+ var ret = 0;
+ while (info.bufferWrite != info.bufferRead && len > 0) {
+ // write out a byte
+ {{{ makeSetValue('buf++', '0', 'info.buffer[info.bufferRead++]', 'i8') }}};
+ if (info.bufferRead == Sockets.BUFFER_SIZE) info.bufferRead = 0;
+ len--;
+ ret++;
+ }
+ return ret;
+ },
+
+ shutdown: function(fd, how) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ info.socket.close();
+ Sockets.fds[fd] = null;
+ },
+
+ ioctl: function(fd, request, varargs) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ var start = info.bufferRead;
+ var end = info.bufferWrite;
+ if (end < start) end += Sockets.BUFFER_SIZE;
+ var dest = {{{ makeGetValue('varargs', '0', 'i32') }}};
+ {{{ makeSetValue('dest', '0', 'end - start', 'i32') }}};
+ return 0;
+ },
+
// ==========================================================================
// emscripten.h
// ==========================================================================
View
9 src/library_browser.js
@@ -347,6 +347,12 @@ mergeInto(LibraryManager.library, {
});
addRunDependency('al ' + url);
},
+
+ setCanvasSize: function(width, height) {
+ var canvas = Module['canvas'];
+ canvas.width = width;
+ canvas.height = height;
+ }
},
emscripten_async_wget: function(url, file, onload, onerror) {
@@ -494,8 +500,7 @@ mergeInto(LibraryManager.library, {
},
emscripten_set_canvas_size: function(width, height) {
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
},
emscripten_get_now: function() {
View
10 src/library_glut.js
@@ -237,8 +237,7 @@ var LibraryGLUT = {
document.removeEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true);
document.removeEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true);
}
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
/* Can't call _glutReshapeWindow as that requests cancelling fullscreen. */
if (GLUT.reshapeFunc) {
// console.log("GLUT.reshapeFunc (from FS): " + width + ", " + height);
@@ -274,8 +273,8 @@ var LibraryGLUT = {
},
glutInitWindowSize: function(width, height) {
- Module['canvas'].width = GLUT.initWindowWidth = width;
- Module['canvas'].height = GLUT.initWindowHeight = height;
+ Browser.setCanvasSize( GLUT.initWindowWidth = width,
+ GLUT.initWindowHeight = height );
},
glutInitWindowPosition: function(x, y) {
@@ -371,8 +370,7 @@ var LibraryGLUT = {
glutReshapeWindow: function(width, height) {
GLUT.cancelFullScreen();
// console.log("glutReshapeWindow: " + width + ", " + height);
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
if (GLUT.reshapeFunc) {
// console.log("GLUT.reshapeFunc: " + width + ", " + height);
FUNCTION_TABLE[GLUT.reshapeFunc](width, height);
View
3  src/library_sdl.js
@@ -659,8 +659,7 @@ var LibrarySDL = {
['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) {
Module['canvas'].addEventListener(event, SDL.receiveEvent, true);
});
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
return SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen');
},
View
3  src/library_xlib.js
@@ -6,8 +6,7 @@ var LibraryXlib = {
XCreateWindow: function(display, parent, x, y, width, height, border_width, depth, class_, visual, valuemask, attributes) {
// All we can do is set the width and height
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
return 2;
},
View
5 src/modules.js
@@ -127,6 +127,11 @@ var Debugging = {
this.llvmLineToSourceFile[lineNum] + '"' : '';
},
+ getAssociatedSourceFile: function(lineNum) {
+ if (!this.on) return null;
+ return lineNum in this.llvmLineToSourceLine ? this.llvmLineToSourceFile[lineNum] : null;
+ },
+
getIdentifier: function(lineNum) {
if (!this.on) return null;
if (lineNum === undefined) {
View
10 src/settings.js
@@ -198,8 +198,12 @@ var INCLUDE_FULL_LIBRARY = 0; // Whether to include the whole library rather tha
// dynamically loading modules that make use of runtime
// library functions that are not used in the main module.
+var SHELL_FILE = 0; // set this to a string to override the shell file used
+
var SHOW_LABELS = 0; // Show labels in the generated code
+var PRINT_SPLIT_FILE_MARKER = 0; // Prints markers in Javascript generation to split the file later on. See emcc --split option.
+
var BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library, which
// must be loaded dynamically using dlopen().
// 0 here means this is not a shared lib: It is a main file.
@@ -1122,5 +1126,9 @@ var C_DEFINES = {'SI_MESGQ': '5',
'AT_FDCWD': '-2',
'SIGTTOU': '22',
'_CS_POSIX_V7_LP64_OFF64_LDFLAGS': '10',
- '_SC_TTY_NAME_MAX': '41'};
+ '_SC_TTY_NAME_MAX': '41',
+ 'AF_INET': '1',
+ 'AF_INET6': '6',
+ 'FIONREAD': '1'
+};
View
4 system/include/net/arpa/inet.h
@@ -7,6 +7,7 @@ extern "C" {
#endif
#include <stdint.h>
+#include <netdb.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
@@ -16,6 +17,9 @@ uint16_t ntohs(uint16_t netshort);
int inet_aton(const char *cp, struct in_addr *addr);
char *inet_ntoa(struct in_addr in);
+int inet_pton(int af, const char *src, void *dst);
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
+
typedef long in_addr_t;
in_addr_t inet_addr(const char *cp);
View
2  system/include/sys/ioctl.h
@@ -11,6 +11,8 @@ extern "C" {
#define TIOCGSIZE 80 // bogus
#define TIOCGWINSZ 80 // bogus
+#define FIONREAD 1
+
int ioctl(int d, int request, ...);
#define SO_RCVTIMEO 1000
View
1  system/include/sys/socket.h
@@ -23,6 +23,7 @@ extern "C" {
#define SO_RCVBUF 60
#define SO_LINGER 70
#define SO_NOSIGPIPE 80
+#define SO_KEEPALIVE 90
#define SHUT_RDWR 1
View
1  system/lib/dlmalloc.c
@@ -4141,6 +4141,7 @@ static int sys_trim(mstate m, size_t pad) {
sp->size >= extra &&
!has_segment_link(m, sp)) { /* can't shrink if pinned */
size_t newsize = sp->size - extra;
+ (void)newsize; // XXX EMSCRIPTEN
/* Prefer mremap, fall back to munmap */
if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
(CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
View
259 tests/runner.py
@@ -7707,6 +7707,10 @@ def test_crunch(self):
elif 'browser' in str(sys.argv):
# Browser tests.
+ print
+ print 'Running the browser tests. Make sure the browser allows popups from localhost.'
+ print
+
# Run a server and a web page. When a test runs, we tell the server about it,
# which tells the web page, which then opens a window with the test. Doing
# it this way then allows the page to close() itself when done.
@@ -7798,7 +7802,7 @@ def run_browser(self, html_file, message, expectedResult=None):
print '(moving on..)'
def with_report_result(self, code):
- return '''
+ return r'''
#define REPORT_RESULT_INTERNAL(sync) \
char output[1000]; \
sprintf(output, \
@@ -7883,6 +7887,189 @@ def build_native_lzma(self):
finally:
os.chdir(cwd)
+ def test_split(self):
+ # test HTML generation.
+ self.reftest(path_from_root('tests', 'htmltest.png'))
+ output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '--split', '100', '--pre-js', 'reftest.js']).communicate()
+ assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file'
+ assert os.path.exists(os.path.join(self.get_dir(), 'something_functions.js')), 'must be functions js file'
+ assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file'
+
+ open(os.path.join(self.get_dir(), 'something.html'), 'w').write('''
+
+ <!doctype html>
+ <html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Emscripten-Generated Code</title>
+ <style>
+ .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
+ canvas.emscripten { border: 1px solid black; }
+ textarea.emscripten { font-family: monospace; width: 80%; }
+ div.emscripten { text-align: center; }
+ </style>
+ </head>
+ <body>
+ <hr/>
+ <div class="emscripten" id="status">Downloading...</div>
+ <div class="emscripten">
+ <progress value="0" max="100" id="progress" hidden=1></progress>
+ </div>
+ <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
+ <hr/>
+ <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div>
+ <hr/>
+ <textarea class="emscripten" id="output" rows="8"></textarea>
+ <hr>
+ <script type='text/javascript'>
+ // connect to canvas
+ var Module = {
+ preRun: [],
+ postRun: [],
+ print: (function() {
+ var element = document.getElementById('output');
+ element.value = ''; // clear browser cache
+ return function(text) {
+ // These replacements are necessary if you render to raw HTML
+ //text = text.replace(/&/g, "&amp;");
+ //text = text.replace(/</g, "&lt;");
+ //text = text.replace(/>/g, "&gt;");
+ //text = text.replace('\\n', '<br>', 'g');
+ element.value += text + "\\n";
+ element.scrollTop = 99999; // focus on bottom
+ };
+ })(),
+ printErr: function(text) {
+ if (0) { // XXX disabled for safety typeof dump == 'function') {
+ dump(text + '\\n'); // fast, straight to the real console
+ } else {
+ console.log(text);
+ }
+ },
+ canvas: document.getElementById('canvas'),
+ setStatus: function(text) {
+ if (Module.setStatus.interval) clearInterval(Module.setStatus.interval);
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var statusElement = document.getElementById('status');
+ var progressElement = document.getElementById('progress');
+ if (m) {
+ text = m[1];
+ progressElement.value = parseInt(m[2])*100;
+ progressElement.max = parseInt(m[4])*100;
+ progressElement.hidden = false;
+ } else {
+ progressElement.value = null;
+ progressElement.max = null;
+ progressElement.hidden = true;
+ }
+ statusElement.innerHTML = text;
+ },
+ totalDependencies: 0,
+ monitorRunDependencies: function(left) {
+ this.totalDependencies = Math.max(this.totalDependencies, left);
+ Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
+ }
+ };
+ Module.setStatus('Downloading...');
+ </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + '''
+ </body>
+ </html>
+ ''')
+
+ self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0')
+
+ def test_split_in_source_filenames(self):
+ self.reftest(path_from_root('tests', 'htmltest.png'))
+ output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '-g', '--split', '100', '--pre-js', 'reftest.js']).communicate()
+ assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file'
+ assert os.path.exists(self.get_dir() + '/something/' + path_from_root('tests', 'hello_world_sdl.cpp.js')), 'must be functions js file'
+ assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file'
+
+ open(os.path.join(self.get_dir(), 'something.html'), 'w').write('''
+
+ <!doctype html>
+ <html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Emscripten-Generated Code</title>
+ <style>
+ .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
+ canvas.emscripten { border: 1px solid black; }
+ textarea.emscripten { font-family: monospace; width: 80%; }
+ div.emscripten { text-align: center; }
+ </style>
+ </head>
+ <body>
+ <hr/>
+ <div class="emscripten" id="status">Downloading...</div>
+ <div class="emscripten">
+ <progress value="0" max="100" id="progress" hidden=1></progress>
+ </div>
+ <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
+ <hr/>
+ <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div>
+ <hr/>
+ <textarea class="emscripten" id="output" rows="8"></textarea>
+ <hr>
+ <script type='text/javascript'>
+ // connect to canvas
+ var Module = {
+ preRun: [],
+ postRun: [],
+ print: (function() {
+ var element = document.getElementById('output');
+ element.value = ''; // clear browser cache
+ return function(text) {
+ // These replacements are necessary if you render to raw HTML
+ //text = text.replace(/&/g, "&amp;");
+ //text = text.replace(/</g, "&lt;");
+ //text = text.replace(/>/g, "&gt;");
+ //text = text.replace('\\n', '<br>', 'g');
+ element.value += text + "\\n";
+ element.scrollTop = 99999; // focus on bottom
+ };
+ })(),
+ printErr: function(text) {
+ if (0) { // XXX disabled for safety typeof dump == 'function') {
+ dump(text + '\\n'); // fast, straight to the real console
+ } else {
+ console.log(text);
+ }
+ },
+ canvas: document.getElementById('canvas'),
+ setStatus: function(text) {
+ if (Module.setStatus.interval) clearInterval(Module.setStatus.interval);
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var statusElement = document.getElementById('status');
+ var progressElement = document.getElementById('progress');
+ if (m) {
+ text = m[1];
+ progressElement.value = parseInt(m[2])*100;
+ progressElement.max = parseInt(m[4])*100;
+ progressElement.hidden = false;
+ } else {
+ progressElement.value = null;
+ progressElement.max = null;
+ progressElement.hidden = true;
+ }
+ statusElement.innerHTML = text;
+ },
+ totalDependencies: 0,
+ monitorRunDependencies: function(left) {
+ this.totalDependencies = Math.max(this.totalDependencies, left);
+ Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
+ }
+ };
+ Module.setStatus('Downloading...');
+ </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + '''
+ </body>
+ </html>
+ ''')
+
+ self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0')
+
def test_compression(self):
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r'''
#include <stdio.h>
@@ -8443,6 +8630,52 @@ def test_pre_run_deps(self):
''')
self.btest('pre_run_deps.cpp', expected='10', args=['--pre-js', 'pre.js'])
+ class WebsockHarness:
+ def __enter__(self):
+ self.pids = []
+
+ def server_func(q):
+ proc = Popen([path_from_root('tests', 'socket_server.sh')])
+ q.put(proc.pid)
+ proc.communicate()
+
+ server_queue = multiprocessing.Queue()
+ self.server = multiprocessing.Process(target=server_func, args=(server_queue,))
+ self.server.start()
+ self.pids.append(self.server.pid)
+ while True:
+ if not server_queue.empty():
+ self.pids.append(server_queue.get())
+ break
+ time.sleep(0.1)
+ print '[Socket server on processes %s]' % str(self.pids[-2:])
+
+ def websockify_func(q):
+ proc = Popen([path_from_root('third_party', 'websockify', 'other', 'websockify'), '-vvv', '8991', '127.0.0.1:8990'])
+ q.put(proc.pid)
+ proc.communicate()
+
+ websockify_queue = multiprocessing.Queue()
+ self.websockify = multiprocessing.Process(target=websockify_func, args=(websockify_queue,))
+ self.websockify.start()
+ self.pids.append(self.websockify.pid)
+ while True:
+ if not websockify_queue.empty():
+ self.pids.append(websockify_queue.get())
+ break
+ time.sleep(0.1)
+ print '[Websockify on processes %s]' % str(self.pids[-2:])
+
+ def __exit__(self, *args, **kwargs):
+ import signal
+ for pid in self.pids:
+ #os.kill(pid, signal.SIGTERM) # With this commented, we leave no children, but we hang the test harness on exit XXX
+ print '[%d should be cleaned up automatically]' % pid
+
+ def test_zz_websockets(self): # always run this test last
+ with self.WebsockHarness():
+ self.btest('websockets.c', expected='571')
+
elif 'benchmark' in str(sys.argv):
# Benchmarks. Run them with argument |benchmark|. To run a specific test, do
# |benchmark.test_X|.
@@ -8824,11 +9057,27 @@ def test_firstrun(self):
self.assertContained('Welcome to Emscripten!', output)
self.assertContained('This is the first time any of the Emscripten tools has been run.', output)
self.assertContained('A settings file has been copied to %s, at absolute path: %s' % (EM_CONFIG, CONFIG_FILE), output)
- self.assertContained('Please edit that file and change the paths to fit your system', output)
- self.assertContained('make sure LLVM_ROOT and NODE_JS are correct', output)
+ self.assertContained('It contains our best guesses for the important paths, which are:', output)
+ self.assertContained('LLVM_ROOT', output)
+ self.assertContained('NODE_JS', output)
+ self.assertContained('Please edit the file if any of those are incorrect', output)
self.assertContained('This command will now exit. When you are done editing those paths, re-run it.', output)
assert output.split()[-1].endswith('===='), 'We should have stopped: ' + output
- assert (open(CONFIG_FILE).read() == open(path_from_root('tools', 'settings_template_readonly.py')).read()), 'Settings should be copied from tools/settings_template_readonly.py'
+ config_file = open(CONFIG_FILE).read()
+ template_file = open(path_from_root('tools', 'settings_template_readonly.py')).read()
+ self.assertNotContained('~/.emscripten', config_file)
+ self.assertContained('~/.emscripten', template_file)
+ self.assertNotContained('{{{', config_file)
+ self.assertNotContained('}}}', config_file)
+ self.assertContained('{{{', template_file)
+ self.assertContained('}}}', template_file)
+ for content in ['EMSCRIPTEN_ROOT', 'LLVM_ROOT', 'NODE_JS', 'TEMP_DIR', 'COMPILER_ENGINE', 'JS_ENGINES']:
+ self.assertContained(content, config_file)
+
+ # The guessed config should be ok XXX This depends on your local system! it is possible `which` guesses wrong
+ try_delete('a.out.js')
+ output = Popen(['python', EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate()
+ self.assertContained('hello, world!', run_js('a.out.js'), output)
# Second run, with bad EM_CONFIG
for settings in ['blah', 'LLVM_ROOT="blarg"; JS_ENGINES=[]; COMPILER_ENGINE=NODE_JS=SPIDERMONKEY_ENGINE=[]']:
@@ -8876,7 +9125,7 @@ def test_llvm(self):
restore()
# Clang should report the version number we expect, and emcc should not warn
- assert ('clang version ' + '.'.join(map(str, EXPECTED_LLVM_VERSION))) in Popen([CLANG, '-v'], stderr=PIPE).communicate()[1]
+ assert check_clang_version()
output = self.check_working(EMCC)
assert LLVM_WARNING not in output, output
View
3  tests/socket_server.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+while true; do (/bin/echo -en "te\x01\xff\x79st\x02") | nc -vvvl 127.0.0.1 8990; done;
+
View
125 tests/websockets.c
@@ -0,0 +1,125 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+
+int SocketFD;
+
+unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
+{
+ int bytes;
+ if (ioctl(sock, FIONREAD, &bytes)) return 0;
+ if (bytes == 0) return 0;
+
+ char buffer[1024];
+ int n;
+ unsigned int offset = 0;
+ while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) ||
+ errno == EINTR) {
+ if(n>0)
+ {
+ if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); }
+ memcpy(output+offset, buffer, n);
+ offset += n;
+ }
+ }
+
+ if(n < 0) {
+ fprintf(stderr, "error in get_all_buf!");
+ exit(EXIT_FAILURE);
+ }
+ return offset;
+}
+
+int done = 0;
+
+void iter(void *arg) {
+ /* perform read write operations ... */
+ static char out[1024*2];
+ static int pos = 0;
+ int n = get_all_buf(SocketFD, out+pos, 1024-pos);
+ if (n) printf("read! %d\n", n);
+ pos += n;
+ if (pos >= EXPECTED_BYTES) {
+ int i, sum = 0;
+ for (i=0; i < pos; i++) {
+ printf("%x\n", out[i]);
+ sum += out[i];
+ }
+
+ shutdown(SocketFD, SHUT_RDWR);
+
+ close(SocketFD);
+
+ done = 1;
+
+ printf("sum: %d\n", sum);
+
+#if EMSCRIPTEN
+ int result = sum;
+ REPORT_RESULT();
+#endif
+ }
+}
+
+int main(void)
+{
+ struct sockaddr_in stSockAddr;
+ int Res;
+ SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (-1 == SocketFD)
+ {
+ perror("cannot create socket");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&stSockAddr, 0, sizeof(stSockAddr));
+
+ stSockAddr.sin_family = AF_INET;
+ stSockAddr.sin_port = htons(
+#if EMSCRIPTEN
+ 8991
+#else
+ 8990
+#endif
+ );
+ Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
+
+ if (0 > Res) {
+ perror("error: first parameter is not a valid address family");
+ close(SocketFD);
+ exit(EXIT_FAILURE);
+ } else if (0 == Res) {
+ perror("char string (second parameter does not contain valid ipaddress)");
+ close(SocketFD);
+ exit(EXIT_FAILURE);
+ }
+
+ if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) {
+ perror("connect failed");
+ close(SocketFD);
+ exit(EXIT_FAILURE);
+
+ }
+
+#if EMSCRIPTEN
+ emscripten_set_main_loop(iter, 0);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+}
+
View
10 third_party/websockify/.gitignore
@@ -0,0 +1,10 @@
+*.pyc
+*.o
+*.so
+other/.lein-deps-sum
+other/classes
+other/lib
+.project
+.pydevproject
+target.cfg
+target.cfg.d
View
18 third_party/websockify/CHANGES.txt
@@ -0,0 +1,18 @@
+Changes
+=======
+
+0.2.0 - Sep 17, 2012
+--------------------
+
+ * Binary data support in websock.js
+ * Target config file/dir and multiple targets with token selector
+ * IPv6 fixes
+ * SSL target support
+ * Proxy to/from unix socket
+
+
+0.1.0 - May 11, 2012
+--------------------
+
+ * Initial versioned release.
+
View
11 third_party/websockify/LICENSE.txt
@@ -0,0 +1,11 @@
+websockify is licensed under the LGPL version 3 (see docs/LICENSE.GPL-3 and
+docs/LICENSE.LGPL-3) with the following exceptions:
+
+ include/base64.js : Choice of MIT 1.1, GPL-2 or LGPL-2.1
+
+ include/web-socket-js/ : New BSD license. Source code at
+ https://github.com/gimite/web-socket-js
+
+ other/kumina.c : Simplified BSD license (2 clause).
+ Original source at
+ https://github.com/kumina/wsproxy
View
1  third_party/websockify/MANIFEST.in
@@ -0,0 +1 @@
+include CHANGES.txt *.py README.md LICENSE.txt
View
11 third_party/websockify/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
+
View
155 third_party/websockify/README.md
@@ -0,0 +1,155 @@
+## websockify: WebSockets support for any application/server
+
+websockify was formerly named wsproxy and was part of the
+[noVNC](https://github.com/kanaka/noVNC) project.
+
+At the most basic level, websockify just translates WebSockets traffic
+to normal socket traffic. Websockify accepts the WebSockets handshake,
+parses it, and then begins forwarding traffic between the client and
+the target in both directions.
+
+### WebSockets binary data
+
+Websockify supports all versions of the WebSockets protocol (Hixie and
+HyBI). The older Hixie versions of the protocol only support UTF-8
+text payloads. In order to transport binary data over UTF-8 an
+encoding must used to encapsulate the data within UTF-8. Websockify
+uses base64 to encode all traffic to and from the client. This does
+not affect the data between websockify and the server.
+
+### Encrypted WebSocket connections (wss://)
+
+To encrypt the traffic using the WebSocket 'wss://' URI scheme you
+need to generate a certificate for websockify to load. By default websockify
+loads a certificate file name `self.pem` but the `--cert=CERT` option can
+override the file name. You can generate a self-signed certificate using
+openssl. When asked for the common name, use the hostname of the server where
+the proxy will be running:
+
+```
+openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
+```
+
+
+### Websock Javascript library
+
+
+The `include/websock.js` Javascript library library provides a Websock
+object that is similar to the standard WebSocket object but Websock
+enables communication with raw TCP sockets (i.e. the binary stream)
+via websockify. This is accomplished by base64 encoding the data
+stream between Websock and websockify.
+
+Websock has built-in receive queue buffering; the message event
+does not contain actual data but is simply a notification that
+there is new data available. Several rQ* methods are available to
+read binary data off of the receive queue.
+
+The Websock API is documented on the [websock.js API wiki page](https://github.com/kanaka/websockify/wiki/websock.js)
+
+See the "Wrap a Program" section below for an example of using Websock
+and websockify as a browser telnet client (`wstelnet.html`).
+
+
+### Additional websockify features
+
+These are not necessary for the basic operation.
+
+* Daemonizing: When the `-D` option is specified, websockify runs
+ in the background as a daemon process.
+
+* SSL (the wss:// WebSockets URI): This is detected automatically by
+ websockify by sniffing the first byte sent from the client and then
+ wrapping the socket if the data starts with '\x16' or '\x80'
+ (indicating SSL).
+
+* Flash security policy: websockify detects flash security policy
+ requests (again by sniffing the first packet) and answers with an
+ appropriate flash security policy response (and then closes the
+ port). This means no separate flash security policy server is needed
+ for supporting the flash WebSockets fallback emulator.
+
+* Session recording: This feature that allows recording of the traffic
+ sent and received from the client to a file using the `--record`
+ option.
+
+* Mini-webserver: websockify can detect and respond to normal web
+ requests on the same port as the WebSockets proxy and Flash security
+ policy. This functionality is activate with the `--web DIR` option
+ where DIR is the root of the web directory to serve.
+
+* Wrap a program: see the "Wrap a Program" section below.
+
+
+### Implementations of websockify
+
+The primary implementation of websockify is in python. There are
+several alternate implementations in other languages (C, Node.js,
+Clojure, Ruby) in the `other/` subdirectory (with varying levels of
+functionality).
+
+In addition there are several other external projects that implement
+the websockify "protocol". See the alternate implementation [Feature
+Matrix](https://github.com/kanaka/websockify/wiki/Feature_Matrix) for
+more information.
+
+
+### Wrap a Program
+
+In addition to proxying from a source address to a target address
+(which may be on a different system), websockify has the ability to
+launch a program on the local system and proxy WebSockets traffic to
+a normal TCP port owned/bound by the program.
+
+The is accomplished with a small LD_PRELOAD library (`rebind.so`)
+which intercepts bind() system calls by the program. The specified
+port is moved to a new localhost/loopback free high port. websockify
+then proxies WebSockets traffic directed to the original port to the
+new (moved) port of the program.
+
+The program wrap mode is invoked by replacing the target with `--`
+followed by the program command line to wrap.
+
+ `./websockify 2023 -- PROGRAM ARGS`
+
+The `--wrap-mode` option can be used to indicate what action to take
+when the wrapped program exits or daemonizes.
+
+Here is an example of using websockify to wrap the vncserver command
+(which backgrounds itself) for use with
+[noVNC](https://github.com/kanaka/noVNC):
+
+ `./websockify 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1`
+
+Here is an example of wrapping telnetd (from krb5-telnetd).telnetd
+exits after the connection closes so the wrap mode is set to respawn
+the command:
+
+ `sudo ./websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023`
+
+The `wstelnet.html` page demonstrates a simple WebSockets based telnet
+client.
+
+
+### Building the Python ssl module (for python 2.5 and older)
+
+* Install the build dependencies. On Ubuntu use this command:
+
+ `sudo aptitude install python-dev bluetooth-dev`
+
+* Download, build the ssl module and symlink to it:
+
+ `cd websockify/`
+
+ `wget http://pypi.python.org/packages/source/s/ssl/ssl-1.15.tar.gz`
+
+ `tar xvzf ssl-1.15.tar.gz`
+
+ `cd ssl-1.15`
+
+ `make`
+
+ `cd ../`
+
+ `ln -sf ssl-1.15/build/lib.linux-*/ssl ssl`
+
View
39 third_party/websockify/Windows/Windows Service Readme.txt
@@ -0,0 +1,39 @@
+-----------------------------------
+Windows noVNC Websockify Service
+-----------------------------------
+
+The "noVNC Websocket Service.exe" file is a windows service wrapper created with Visual Studio 2010 to create a windows service to start stop the noVNC Websocket Server. All files used to create the wrapper can be found in 'noVNC Websocket Service Project' folder.
+
+To download the precompiled executables please grab the zip in the downloads section of websockify project:
+https://github.com/kanaka/websockify
+
+---------------------------
+Installation
+---------------------------
+
+1. This service requires websockify.exe be in the same directory. Instructions on how to compile websockify python script as a windows executable can be found here:
+https://github.com/kanaka/noVNC/wiki/Compiling-Websockify-to-Windows-Executable
+
+2.To add this service to a Windows PC you need to run the commandline as administrator and then run this line:
+
+sc create "noVNC Websocket Server" binPath= "PATH TO noVNC eg C:\noVNC\utils\Windows\Websocket Service.exe" DisplayName= "noVNC Websocket Server"
+
+3 .Once this is run you will be able to access the service via Control Panel > Admin Tools > Services. In here you can specify whether you want the service to run automatically and start at stop the service.
+
+---------------------------
+Configuration
+---------------------------
+The file noVNCConfig.ini must be in the same directory as "noVNC Websocket Service.exe".
+
+This file contains a single line which is the websockify.exe statup arguements. An example is:
+192.168.0.1:5901 192.168.0.1:5900
+
+All websockify supported arguements will work if added here.
+
+---------------------------
+Deletion
+---------------------------
+
+You can delete the service at any time by running the commandline as admin and using this command:
+sc delete "noVNC Websocket Server".
+
View
24 third_party/websockify/Windows/noVNC Websocket Service Project/Program.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.ServiceProcess;
+using System.Text;
+
+namespace MELT_Command_Websocket
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ static void Main()
+ {
+ ServiceBase[] ServicesToRun;
+ ServicesToRun = new ServiceBase[]
+ {
+ new Service1()
+ };
+ ServiceBase.Run(ServicesToRun);
+ }
+ }
+}
View
61 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.Designer.cs
@@ -0,0 +1,61 @@
+namespace MELT_Command_Websocket
+{
+ partial class ProjectInstaller
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
+ this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
+ //
+ // serviceProcessInstaller1
+ //
+ this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.NetworkService;
+ this.serviceProcessInstaller1.Installers.AddRange(new System.Configuration.Install.Installer[] {
+ this.serviceInstaller1});
+ this.serviceProcessInstaller1.Password = null;
+ this.serviceProcessInstaller1.Username = null;
+ //
+ // serviceInstaller1
+ //
+ this.serviceInstaller1.Description = "noVNC Websocket Service";
+ this.serviceInstaller1.DisplayName = "noVNC Websocket Service";
+ this.serviceInstaller1.ServiceName = "noVNC Websocket Service";
+ this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
+ //
+ // ProjectInstaller
+ //
+ this.Installers.AddRange(new System.Configuration.Install.Installer[] {
+ this.serviceProcessInstaller1});
+
+ }
+
+ #endregion
+
+ private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
+ private System.ServiceProcess.ServiceInstaller serviceInstaller1;
+ }
+}
View
19 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration.Install;
+using System.Linq;
+
+
+namespace MELT_Command_Websocket
+{
+ [RunInstaller(true)]
+ public partial class ProjectInstaller : System.Configuration.Install.Installer
+ {
+ public ProjectInstaller()
+ {
+ InitializeComponent();
+ }
+ }
+}
View
129 third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.resx
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 56</value>
+ </metadata>
+ <metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>196, 17</value>
+ </metadata>
+ <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>False</value>
+ </metadata>
+</root>
View
36 third_party/websockify/Windows/noVNC Websocket Service Project/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MELT Command Websocket")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("MELT Command Websocket")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5ab831cb-6852-4ce1-849c-b26725b0e10b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
37 third_party/websockify/Windows/noVNC Websocket Service Project/Service1.Designer.cs
@@ -0,0 +1,37 @@
+namespace MELT_Command_Websocket
+{
+ partial class Service1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ this.ServiceName = "Service1";
+ }
+
+ #endregion
+ }
+}
View
41 third_party/websockify/Windows/noVNC Websocket Service Project/Service1.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Linq;
+using System.ServiceProcess;
+using System.Text;
+using System.IO;
+
+namespace MELT_Command_Websocket
+{
+ public partial class Service1 : ServiceBase
+ {
+ Process websockify;
+ public Service1()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnStart(string[] args)
+ {
+
+ string configpath = AppDomain.CurrentDomain.BaseDirectory + "\\noVNCConfig.ini";
+ string sockifypath = AppDomain.CurrentDomain.BaseDirectory + "\\websockify.exe";
+ //Load commandline arguements from config file.
+ StreamReader streamReader = new StreamReader(configpath);
+ string arguements = streamReader.ReadLine();
+ streamReader.Close();
+
+ //Start websockify.
+ websockify = System.Diagnostics.Process.Start(sockifypath, arguements);
+ }
+
+ protected override void OnStop()
+ {
+ //Service stopped. Close websockify.
+ websockify.Kill();
+ }
+ }
+}
View
75 third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.csproj
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>noVNC_Websocket_Service</RootNamespace>
+ <AssemblyName>noVNC Websocket Service</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Configuration.Install" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Management" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.ServiceProcess" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ProjectInstaller.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="ProjectInstaller.Designer.cs">
+ <DependentUpon>ProjectInstaller.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Service1.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="Service1.Designer.cs">
+ <DependentUpon>Service1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="ProjectInstaller.resx">
+ <DependentUpon>ProjectInstaller.cs</DependentUpon>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
20 third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "noVNC Websocket", "noVNC Websocket.csproj", "{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Debug|x86.ActiveCfg = Debug|x86
+ {6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Debug|x86.Build.0 = Debug|x86
+ {6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Release|x86.ActiveCfg = Release|x86
+ {6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
View
621 third_party/websockify/docs/LICENSE.GPL-3
@@ -0,0 +1,621 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered