changeset 0:bd412f63ce0d

Put this project under version control, finally.
author John "Elwin" Edwards <elwin@sdf.org>
date Sun, 06 May 2012 08:45:40 -0700
parents
children 9bef0941c6dd
files bell.svg index-rlg.html index-sh.html ptyhelper.c quickrypt.c rlgterm.js shterm.js termemu.js tty.css webtty.js webttyd.js
diffstat 11 files changed, 3461 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bell.svg	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="16"
+   height="16"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="New document 1">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.2"
+     inkscape:cx="17.844259"
+     inkscape:cy="5.9285714"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="873"
+     inkscape:window-height="546"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1036.3622)">
+    <path
+       style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1"
+       d="m 4.2931485,1040.1868 c 0.8310158,-1.1611 2.3601954,-2 3.7880723,-2 1.4278768,0 2.9570562,0.8389 3.7880722,2 1.238121,1.73 0.404997,4.2608 1,6.3033 0.234101,0.8036 1,2.3033 1,2.3033 l -11.5761445,0 c 0,0 0.7658995,-1.4997 1,-2.3033 0.5950026,-2.0425 -0.2381208,-4.5733 1,-6.3033 z"
+       id="rect2985"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ssssccss" />
+    <path
+       sodipodi:type="arc"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path3762"
+       sodipodi:cx="11.696428"
+       sodipodi:cy="14.660714"
+       sodipodi:rx="1.25"
+       sodipodi:ry="1.25"
+       d="m 12.946428,14.660714 a 1.25,1.25 0 1 1 -2.5,0 1.25,1.25 0 1 1 2.5,0 z"
+       transform="translate(-1.25,1035.4693)" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index-rlg.html	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>WebTTY</title>
+<script type="text/javascript" src="termemu.js"></script>
+<script type="text/javascript" src="rlgterm.js"></script>
+<link rel="stylesheet" type="text/css" href="tty.css">
+</head>
+<body onload="setup()" onkeydown="sendkey(event)">
+<h1>WebTTY</h1>
+<div id ="top">
+  <span id="ttitle"></span>
+  <img src="/bell.png" alt="bell" id="bell">
+</div>
+<div id="termwrap">TERM</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey('`')">`</div>
+  <div class="key" onclick="vkey('1')">1</div>
+  <div class="key" onclick="vkey('2')">2</div>
+  <div class="key" onclick="vkey('3')">3</div>
+  <div class="key" onclick="vkey('4')">4</div>
+  <div class="key" onclick="vkey('5')">5</div>
+  <div class="key" onclick="vkey('6')">6</div>
+  <div class="key" onclick="vkey('7')">7</div>
+  <div class="key" onclick="vkey('8')">8</div>
+  <div class="key" onclick="vkey('9')">9</div>
+  <div class="key" onclick="vkey('0')">0</div>
+  <div class="key" onclick="vkey('-')">-</div>
+  <div class="key" onclick="vkey('=')">=</div>
+  <div class="key" onclick="vkey('\b')" style="width: 2.5em">Bksp</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey('\t')" style="width: 2.5em">Tab</div>
+  <div class="key" onclick="vkey('q')">Q</div>
+  <div class="key" onclick="vkey('w')">W</div>
+  <div class="key" onclick="vkey('e')">E</div>
+  <div class="key" onclick="vkey('r')">R</div>
+  <div class="key" onclick="vkey('t')">T</div>
+  <div class="key" onclick="vkey('y')">Y</div>
+  <div class="key" onclick="vkey('u')">U</div>
+  <div class="key" onclick="vkey('i')">I</div>
+  <div class="key" onclick="vkey('o')">O</div>
+  <div class="key" onclick="vkey('p')">P</div>
+  <div class="key" onclick="vkey('[')">[</div>
+  <div class="key" onclick="vkey(']')">]</div>
+  <div class="key" onclick="vkey('\\')">\</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="togglectrl()" id="ctrlkey">Ctrl</div>
+  <div class="key" onclick="vkey('a')">A</div>
+  <div class="key" onclick="vkey('s')">S</div>
+  <div class="key" onclick="vkey('d')">D</div>
+  <div class="key" onclick="vkey('f')">F</div>
+  <div class="key" onclick="vkey('g')">G</div>
+  <div class="key" onclick="vkey('h')">H</div>
+  <div class="key" onclick="vkey('j')">J</div>
+  <div class="key" onclick="vkey('k')">K</div>
+  <div class="key" onclick="vkey('l')">L</div>
+  <div class="key" onclick="vkey(';')">;</div>
+  <div class="key" onclick="vkey('\'')">'</div>
+  <div class="key" onclick="vkey('\n')" style="width: 4em">Ret</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="toggleshift()" id="shiftkey">Shift</div>
+  <div class="key" onclick="vkey('z')">Z</div>
+  <div class="key" onclick="vkey('x')">X</div>
+  <div class="key" onclick="vkey('c')">C</div>
+  <div class="key" onclick="vkey('v')">V</div>
+  <div class="key" onclick="vkey('b')">B</div>
+  <div class="key" onclick="vkey('n')">N</div>
+  <div class="key" onclick="vkey('m')">M</div>
+  <div class="key" onclick="vkey(',')">,</div>
+  <div class="key" onclick="vkey('.')">.</div>
+  <div class="key" onclick="vkey('/')">/</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey(' ')" id="spacebar"></div>
+</div>
+<div class="rbutton" onclick="stop()">Stop</div>
+<div class="rbutton">Font:
+<span onclick="textsize(false)">Smaller</span>
+<span onclick="textsize(true)">Larger</span>
+</div>
+<div>
+<form id="loginform" action="/login" method="post">
+<div>
+Name: <input type="text" name="name" id="input_name"> 
+Password: <input type="password" name="pw" id="input_pw">
+Choose game: <select name="game" id="input_game">
+  <option label="Rogue V3" value="rogue3">Rogue V3</option>
+  <option label="Rogue V4" value="rogue4">Rogue V4</option>
+  <option label="Rogue V5" value="rogue5">Rogue V5</option>
+  <option label="Super-Rogue" value="srogue">Super-Rogue</option>
+</select>
+<input type="submit" value="Play" onclick="formlogin(event)">
+</div>
+</form>
+</div>
+<div id="debug">
+<p>Debugging Output</p>
+</div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index-sh.html	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>WebTTY</title>
+<script type="text/javascript" src="termemu.js"></script>
+<script type="text/javascript" src="shterm.js"></script>
+<link rel="stylesheet" type="text/css" href="tty.css">
+</head>
+<body onload="setup()" onkeydown="sendkey(event)">
+<h1>WebTTY</h1>
+<div id ="top">
+  <span id="ttitle"></span>
+  <img src="/bell.png" alt="bell" id="bell">
+</div>
+<div id="termwrap">
+Browsing with Javascript turned off?  I sympathize.  I didn't want Javascript to be necessary for WebTerm.  Unfortunately, the only other way to make it work was Java applets.
+</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey('`')">`</div>
+  <div class="key" onclick="vkey('1')">1</div>
+  <div class="key" onclick="vkey('2')">2</div>
+  <div class="key" onclick="vkey('3')">3</div>
+  <div class="key" onclick="vkey('4')">4</div>
+  <div class="key" onclick="vkey('5')">5</div>
+  <div class="key" onclick="vkey('6')">6</div>
+  <div class="key" onclick="vkey('7')">7</div>
+  <div class="key" onclick="vkey('8')">8</div>
+  <div class="key" onclick="vkey('9')">9</div>
+  <div class="key" onclick="vkey('0')">0</div>
+  <div class="key" onclick="vkey('-')">-</div>
+  <div class="key" onclick="vkey('=')">=</div>
+  <div class="key" onclick="vkey('\b')" style="width: 2.5em">Bksp</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey('\t')" style="width: 2.5em">Tab</div>
+  <div class="key" onclick="vkey('q')">Q</div>
+  <div class="key" onclick="vkey('w')">W</div>
+  <div class="key" onclick="vkey('e')">E</div>
+  <div class="key" onclick="vkey('r')">R</div>
+  <div class="key" onclick="vkey('t')">T</div>
+  <div class="key" onclick="vkey('y')">Y</div>
+  <div class="key" onclick="vkey('u')">U</div>
+  <div class="key" onclick="vkey('i')">I</div>
+  <div class="key" onclick="vkey('o')">O</div>
+  <div class="key" onclick="vkey('p')">P</div>
+  <div class="key" onclick="vkey('[')">[</div>
+  <div class="key" onclick="vkey(']')">]</div>
+  <div class="key" onclick="vkey('\\')">\</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="togglectrl()" id="ctrlkey">Ctrl</div>
+  <div class="key" onclick="vkey('a')">A</div>
+  <div class="key" onclick="vkey('s')">S</div>
+  <div class="key" onclick="vkey('d')">D</div>
+  <div class="key" onclick="vkey('f')">F</div>
+  <div class="key" onclick="vkey('g')">G</div>
+  <div class="key" onclick="vkey('h')">H</div>
+  <div class="key" onclick="vkey('j')">J</div>
+  <div class="key" onclick="vkey('k')">K</div>
+  <div class="key" onclick="vkey('l')">L</div>
+  <div class="key" onclick="vkey(';')">;</div>
+  <div class="key" onclick="vkey('\'')">'</div>
+  <div class="key" onclick="vkey('\n')" style="width: 4em">Ret</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="toggleshift()" id="shiftkey">Shift</div>
+  <div class="key" onclick="vkey('z')">Z</div>
+  <div class="key" onclick="vkey('x')">X</div>
+  <div class="key" onclick="vkey('c')">C</div>
+  <div class="key" onclick="vkey('v')">V</div>
+  <div class="key" onclick="vkey('b')">B</div>
+  <div class="key" onclick="vkey('n')">N</div>
+  <div class="key" onclick="vkey('m')">M</div>
+  <div class="key" onclick="vkey(',')">,</div>
+  <div class="key" onclick="vkey('.')">.</div>
+  <div class="key" onclick="vkey('/')">/</div>
+</div>
+<div class="keyrow">
+  <div class="key" onclick="vkey(' ')" id="spacebar"></div>
+</div>
+<div class="rbutton" onclick="login()">Log in</div>
+<div class="rbutton" onclick="stop()">Stop</div>
+<div class="rbutton">Font:
+<span onclick="textsize(false)">Smaller</span>
+<span onclick="textsize(true)">Larger</span>
+</div>
+<div id="debug">
+<p>Debugging Output</p>
+</div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ptyhelper.c	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,149 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pty.h>
+#include <utmp.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/select.h>
+#include <termios.h>
+
+int got_sighup = 0;
+
+void handle_HUP(int signum) {
+  if (signum == SIGHUP)
+    got_sighup = 1;
+  return;
+}
+
+int main(int argc, char *argv[]) {
+
+  int ptymaster, ptyslave; /* File descriptors */
+  int child;
+  int status, selstatus;
+  int w = 80, h = 24, t;
+  struct sigaction sighup_act;
+  fd_set readset;
+  struct timeval select_time;
+  char buf[4096];
+  int nread;
+  char *penv, *ptmp;
+#if 0
+  struct termios ptysettings;
+#endif
+  struct winsize ptysize;
+
+  if (argc == 1) {
+    fprintf(stderr, "No command given.\n");
+    exit(1);
+  }
+
+  /* Set up the signal handler. */
+  sighup_act.sa_handler = &handle_HUP;
+  sighup_act.sa_flags = SA_RESTART;
+  sigaction(SIGHUP, &sighup_act, NULL);
+
+  /* Check the environment for configuration options. */
+  penv = getenv("PTYHELPER");
+  if (penv != NULL) {
+    t = strtol(penv, &ptmp, 10);
+    if (t > 0 && t < 256)
+      h = t;
+    if (*ptmp != '\0') {
+      penv = ptmp + 1;
+      t = strtol(penv, &ptmp, 10);
+      if (t > 0 && t < 256)
+        w = t;
+    }
+  }
+  /* Set up the size. */
+  ptysize.ws_row = h;
+  ptysize.ws_col = w;
+
+  /* Open a pty */
+  if (openpty(&ptymaster, &ptyslave, NULL, NULL, &ptysize)) {
+    return 1;
+  }
+#if 0
+  /* Put it into raw mode. */
+  tcgetattr(ptyslave, &ptysettings);
+  cfmakeraw(&ptysettings);
+  tcsetattr(ptyslave, TCSANOW, &ptysettings);
+#endif
+
+  /* Start the child */
+  /* forkpty() might be more convenient. */
+  if (!(child = fork())) {
+    /* Child process */
+    login_tty(ptyslave);
+    close(ptymaster);
+    execvp(argv[1], argv + 1);
+    perror("execvp() failed");
+    return 1;
+  }
+  close(ptyslave);
+
+  while (1) {
+    /* Now do a select() over stdin and ptymaster, and write anything that 
+     * appears to ptymaster and stdout respectively. */
+    FD_ZERO(&readset);
+    FD_SET(0, &readset);
+    FD_SET(ptymaster, &readset);
+    select_time.tv_sec = 1;
+    select_time.tv_usec = 0;
+    selstatus = select(ptymaster + 1, &readset, NULL, NULL, &select_time);
+    if (selstatus > 0) {
+      /* TODO make sure it all gets written if a signal interrupts write(). */
+      if (FD_ISSET(0, &readset)) {
+        nread = read(0, buf, 4096);
+        if (nread > 0) {
+          write(ptymaster, buf, nread);
+        }
+      }
+      if (FD_ISSET(ptymaster, &readset)) {
+        nread = read(ptymaster, buf, 4096);
+        if (nread > 0) {
+          write(1, buf, nread);
+        }
+      }
+    }
+
+    /* Periodically check to see if we're done. */
+    /* TODO: catch SIGCHLD and only wait() if it is delivered. */
+    if (waitpid(child, &status, WNOHANG)) {
+      break;
+    }
+
+    /* If node sighup's us, pass it along. */
+    if (got_sighup) {
+      kill(child, SIGHUP);
+    }
+  }
+
+  /* Get any leftover output and clean up. */
+  /* FIXME looping over select() is pointless if there's only one fd that
+   * nothing's writing to.  Just loop over read() until it's empty. */
+  while (1) {
+    FD_ZERO(&readset);
+    FD_SET(ptymaster, &readset);
+    select_time.tv_sec = 0;
+    select_time.tv_usec = 0;
+    if (select(ptymaster + 1, &readset, NULL, NULL, &select_time) > 0) {
+      nread = read(ptymaster, buf, 4096);
+      if (nread > 0) {
+        write(1, buf, nread);
+      }
+      else
+        break;
+    }
+    else
+      break;
+  }
+  close(ptymaster);
+
+  /* Return the child's exit status. */
+  if (WIFEXITED(status))
+    return WEXITSTATUS(status);
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/quickrypt.c	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <crypt.h>
+
+int main(int argc, char *argv[]) {
+  char clear[32], enc[120], *ptr;
+  fgets(&clear, 32, stdin);
+  if (!(ptr = strchr(&clear, '\n')))
+    return 1;
+  else
+    *ptr = '\0';
+  fgets(&enc, 120, stdin);
+  if (!(ptr = strchr(&enc, '\n')))
+    return 1;
+  else
+    *ptr = '\0';
+  ptr = crypt(clear, enc);
+  if (!strcmp(argv[argc - 1], "-s")) {
+    /* Option -s for "show": output the encrypted version. */
+    printf("%s\n", ptr);
+    return 0;
+  }
+  /* Otherwise this is a check. */
+  else if (!strcmp(ptr, enc))
+    return 0;
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rlgterm.js	Sun May 06 08:45:40 2012 -0700
@@ -0,0 +1,485 @@
+/* rlgterm.js: Roguelike Gallery's driver for termemu.js */
+
+// A state machine that keeps track of polling the server.
+var ajaxstate = {
+  state: 0,
+  timerID: null,
+  clear: function () {
+    if (this.timerID != null) {
+      window.clearTimeout(this.timerID);
+      this.timerID = null;
+    }
+  },
+  set: function (ms) {
+    this.clear();
+    this.timerID = window.setTimeout(getData, ms);
+  },
+  gotdata: function () {
+    this.set(100);
+    this.state = 0;
+  },
+  gotnothing: function () {
+    if (this.state == 0) {
+      this.set(100);
+      this.state = 1;
+    }
+    else if (this.state == 1) {
+      this.set(300);
+      this.state = 2;
+    }
+    else if (this.state == 2) {
+      this.set(1000);
+      this.state = 3;
+    }
+    else {
+      this.set(5000);
+      this.state = 3;
+    }
+  },
+  posted: function () {
+    this.set(100);
+    this.state = 0;
+  }
+};
+
+function writeData(hexstr) {
+  var codenum;
+  var codes = [];
+  var nc;
+  var u8wait = 0; /* Stores bits from previous bytes of multibyte sequences. */
+  var expect = 0; /* The number of 10------ bytes expected. */
+  /* UTF-8 translation. */
+  for (var i = 0; i < hexstr.length; i += 2) {
+    nc = Number("0x" + hexstr.substr(i, 2));
+    if (nc < 0x7F) {
+      /* 0------- */
+      codes.push(nc);
+      /* Any incomplete sequence will be discarded. */
+      u8wait = 0;
+      expect = 0;
+    }
+    else if (nc < 0xC0) {
+      /* 10------ : part of a multibyte sequence */
+      if (expect > 0) {
+        u8wait <<= 6;
+        u8wait += (nc & 0x3F);
+        expect--;
+        if (expect == 0) {
+          codes.push(u8wait);
+          u8wait = 0;
+        }
+      }
+      else {
+        /* Assume an initial byte was missed. */
+        u8wait = 0;
+      }
+    }
+    /* These will all discard any incomplete sequence. */
+    else if (nc < 0xE0) {