initial commit

This commit is contained in:
josch 2014-07-05 00:39:15 +02:00
commit 55ebab1701
8 changed files with 66230 additions and 0 deletions

25
README.md Normal file
View file

@ -0,0 +1,25 @@
`script` and `scriptreplay` are part of the `bsdutils` package in Debian and
Ubuntu, `util-linux-ng` in Fedora and `util-linux` in SUSE. They allow to
capture a terminal or script output and replay it, respectively.
This page uses the vt100 emulator by Frank Bi and adds code of my own to read
typescript and timing files to make it possible to replay captured scripts a
web browser.
By adding an upload facility to this it would be possible to have a youtube or
pastebin for terminal sessions. Due to laziness this remains a proof of concept
for now though.
- This javascript terminal window is 80x24 characters, so it might be
best to adjust your terminal window to that size as well using the
following to check:
$ watch "tput cols; tput lines"
- Start recording:
$ SHELL=/bin/sh TERM=vt100 script -t typescript 2> timingfile
- Do your stuff and when done exit script with `exit`, `logout` or
ctrl-d.
- To test how your recorded session looks like, use:
$ scriptreplay timingfile typescript
- Enter `timingfile` and `typescript` into form above and hit the play
button.

649
VT100.js Normal file
View file

@ -0,0 +1,649 @@
// VT100.js -- a text terminal emulator in JavaScript with a ncurses-like
// interface and a POSIX-like interface. (The POSIX-like calls are
// implemented on top of the ncurses-like calls, not the other way round.)
//
// Released under the GNU LGPL v2.1, by Frank Bi <bi@zompower.tk>
//
// 2007-08-12 - refresh():
// - factor out colour code to html_colours_()
// - fix handling of A_REVERSE | A_DIM
// - simplify initial <br> output code
// - fix underlining colour
// - fix attron() not to turn off attributes
// - decouple A_STANDOUT and A_BOLD
// 2007-08-11 - getch() now calls refresh()
// 2007-08-06 - Safari compat fix -- turn '\r' into '\n' for onkeypress
// 2007-08-05 - Opera compat fixes for onkeypress
// 2007-07-30 - IE compat fixes:
// - change key handling code
// - add <br>...<br>&nbsp; so that 1st and last lines align
// 2007-07-28 - change wrapping behaviour -- writing at the right edge no
// longer causes the cursor to immediately wrap around
// - add <b>...</b> to output to make A_STANDOUT stand out more
// - add handling of backspace, tab, return keys
// - fix doc. of VT100() constructor
// - change from GPL to LGPL
// 2007-07-09 - initial release
//
// class VT100
// A_NORMAL, A_UNDERLINE, A_REVERSE, A_BLINK, A_DIM, A_BOLD, A_STANDOUT
// =class constants=
// Attribute constants.
// VT100(wd, ht, scr_id) =constructor=
// Creates a virtual terminal with width `wd', and
// height `ht'. The terminal will be displayed between
// <pre>...</pre> tags which have element ID `scr_id'.
// addch(ch [, attr])
// Writes out the character `ch'. If `attr' is given,
// it specifies the attributes for the character,
// otherwise the current attributes are used.
// addstr(stuff) Writes out the string `stuff' using the current
// attributes.
// attroff(a) Turns off any current attributes given in `a'.
// attron(a) Turns on any attributes given in `a'.
// attrset(a) Sets the current attributes to `a'.
// bkgdset(a) Sets the background attributes to `a'.
// clear() Clears the terminal using the background attributes,
// and homes the cursor.
// clrtobol() Clears the portion of the terminal from the cursor
// to the bottom.
// clrtoeol() Clears the portion of the current line after the
// cursor.
// COLOR_PAIR(pn) Converts a colour pair number `pn' into an
// attribute.
// curs_set(vis [, grab])
// If `vis' is 0, makes the cursor invisible; otherwise
// make it visible. If `grab' is given and true, starts
// capturing keyboard events (for `getch()'); if given
// and false, stops capturing events.
// echo() Causes key strokes to be automatically echoed on the
// terminal.
// erase() Same as `clear()'.
// getch(isr) Arranges to call `isr' when a key stroke is
// received. The received character and the terminal
// object are passed as arguments to `isr'.
// getmaxyx() Returns an associative array with the maximum row
// (`y') and column (`x') numbers for the terminal.
// getyx() Returns an associative array with the current row
// (`y') and column (`x') of the cursor.
// move(r, c) Moves the cursor to row `r', column `c'.
// noecho() Stops automatically echoing key strokes.
// pair_content(pn)
// Returns an associative array with the foreground
// (`f') and background (`b') colour numbers for the
// colour pair `pn'.
// PAIR_NUMBER(a) Returns the colour pair number in the attributes
// `a'.
// refresh() Updates the display.
// scroll() Scrolls the terminal up one line.
// standend() Same as `attrset(VT100.A_NORMAL)'.
// standout() Same as `attron(VT100.A_STANDOUT)'.
// write(stuff) Writes `stuff' to the terminal and immediately
// updates the display; (some) escape sequences are
// interpreted and acted on.
// constructor
function VT100(wd, ht, scr_id)
{
var r;
var c;
var scr = document.getElementById(scr_id);
this.wd_ = wd;
this.ht_ = ht;
this.c_attr_ = this.bkgd_ = this.COLOR_PAIR(0) | VT100.A_NORMAL;
this.color_pair_ = new Array(VT100.COLOR_PAIRS);
this.color_pair_[0] = { f: VT100.COLOR_WHITE, b: VT100.COLOR_BLACK };
this.text_ = new Array(ht);
this.attr_ = new Array(ht);
for (r = 0; r < ht; ++r) {
this.text_[r] = new Array(wd);
this.attr_[r] = new Array(wd);
}
this.scr_ = scr;
this.cursor_vis_ = true;
this.grab_events_ = false;
this.getch_isr_ = undefined;
this.key_buf_ = [];
this.echo_ = true;
this.esc_state_ = 0;
this.clear();
this.refresh();
}
// public constants -- colours and colour pairs
VT100.COLOR_BLACK = 0;
VT100.COLOR_BLUE = 1;
VT100.COLOR_GREEN = 2;
VT100.COLOR_CYAN = 3;
VT100.COLOR_RED = 4;
VT100.COLOR_MAGENTA = 5;
VT100.COLOR_YELLOW = 6;
VT100.COLOR_WHITE = 7;
VT100.COLOR_PAIRS = 256;
VT100.COLORS = 8;
// public constants -- attributes
VT100.A_NORMAL = 0;
VT100.A_UNDERLINE = 1;
VT100.A_REVERSE = 2;
VT100.A_BLINK = 4;
VT100.A_DIM = 8;
VT100.A_BOLD = 16;
VT100.A_STANDOUT = 32;
VT100.A_PROTECT = VT100.A_INVIS = 0; // ?
// other public constants
VT100.TABSIZE = 8;
// private constants
VT100.ATTR_FLAGS_ = VT100.A_UNDERLINE | VT100.A_REVERSE | VT100.A_BLINK |
VT100.A_DIM | VT100.A_BOLD | VT100.A_STANDOUT |
VT100.A_PROTECT | VT100.A_INVIS;
VT100.COLOR_SHIFT_ = 6;
VT100.browser_ie_ = (navigator.appName.indexOf("Microsoft") != -1);
VT100.browser_opera_ = (navigator.appName.indexOf("Opera") != -1);
// class variables
VT100.the_vt_ = undefined;
// class methods
// this is actually an event handler
VT100.handle_onkeypress_ = function(e)
{
var vt = VT100.the_vt_, ch;
if (vt === undefined)
return true;
if (VT100.browser_ie_ || VT100.browser_opera_) {
ch = event.keyCode;
if (ch == 13)
ch = 10;
else if (ch > 255 || (ch < 32 && ch != 8))
return true;
ch = String.fromCharCode(ch);
} else {
ch = e.charCode;
if (ch) {
if (ch > 255)
return true;
ch = String.fromCharCode(ch);
if (ch == '\r')
ch = '\n';
} else
switch (e.keyCode) {
case e.DOM_VK_BACK_SPACE:
ch = '\b'; break;
case e.DOM_VK_TAB:
ch = '\t'; break;
case e.DOM_VK_RETURN:
case e.DOM_VK_ENTER:
ch = '\n'; break;
default:
return true;
}
}
vt.key_buf_.push(ch);
setTimeout(VT100.go_getch_, 0);
return false;
}
// this is actually an event handler
VT100.handle_onkeydown_ = function()
{
var vt = VT100.the_vt_, ch;
switch (event.keyCode) {
case 8:
ch = '\b'; break;
default:
return true;
}
vt.key_buf_.push(ch);
setTimeout(VT100.go_getch_, 0);
return false;
}
VT100.go_getch_ = function()
{
var vt = VT100.the_vt_;
if (vt === undefined)
return;
var isr = vt.getch_isr_;
vt.getch_isr_ = undefined;
if (isr === undefined)
return;
var ch = vt.key_buf_.shift();
if (ch === undefined) {
vt.getch_isr_ = isr;
return;
}
if (vt.echo_)
vt.addch(ch);
isr(ch, vt);
}
// object methods
VT100.prototype.may_scroll_ = function()
{
var ht = this.ht_, cr = this.row_;
while (cr >= ht) {
this.scroll();
--cr;
}
this.row_ = cr;
}
VT100.prototype.html_colours_ = function(attr)
{
var pair, fg, bg, co0, co1;
pair = this.pair_content(this.PAIR_NUMBER(attr));
fg = pair.f;
bg = pair.b;
switch (attr & (VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD)) {
case 0:
case VT100.A_DIM | VT100.A_BOLD:
co0 = '00'; co1 = 'c0'; break;
case VT100.A_BOLD:
co0 = '00'; co1 = 'ff'; break;
case VT100.A_DIM:
if (fg == VT100.COLOR_BLACK)
co0 = '40';
else
co0 = '00';
co1 = '40';
break;
case VT100.A_REVERSE:
case VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD:
co0 = 'c0'; co1 = '40'; break;
case VT100.A_REVERSE | VT100.A_BOLD:
co0 = 'c0'; co1 = '00'; break;
default:
if (fg == VT100.COLOR_BLACK)
co0 = '80';
else
co0 = 'c0';
co1 = 'c0';
}
return {
f: '#' + (fg & 4 ? co1 : co0) +
(fg & 2 ? co1 : co0) +
(fg & 1 ? co1 : co0),
b: '#' + (bg & 4 ? co1 : co0) +
(bg & 2 ? co1 : co0) +
(bg & 1 ? co1 : co0)
};
}
VT100.prototype.addch = function(ch, attr)
{
var cc = this.col_;
switch (ch) {
case '\b':
if (cc != 0)
--cc;
break;
case '\n':
++this.row_;
cc = 0;
this.clrtoeol();
this.may_scroll_();
break;
case '\r':
this.may_scroll_();
cc = 0;
break;
case '\t':
this.may_scroll_();
cc += VT100.TABSIZE - cc % VT100.TABSIZE;
if (cc >= this.wd_) {
++this.row_;
cc -= this.wd_;
}
break;
default:
if (attr === undefined)
attr = this.c_attr_;
if (cc >= this.wd_) {
++this.row_;
cc = 0;
}
this.may_scroll_();
this.text_[this.row_][cc] = ch;
this.attr_[this.row_][cc] = attr;
++cc;
}
this.col_ = cc;
}
VT100.prototype.addstr = function(stuff)
{
for (var i = 0; i < stuff.length; ++i)
this.addch(stuff.charAt(i));
}
VT100.prototype.attroff = function(a)
{
a &= VT100.ATTR_FLAGS_;
this.c_attr_ &= ~a;
}
VT100.prototype.attron = function(a)
{
a &= VT100.ATTR_FLAGS_;
this.c_attr_ |= a;
}
VT100.prototype.attrset = function(a)
{
this.c_attr_ = a;
}
VT100.prototype.bkgdset = function(a)
{
this.bkgd_ = a;
}
VT100.prototype.clear = function()
{
this.row_ = this.col_ = 0;
for (r = 0; r < this.ht_; ++r) {
for (c = 0; c < this.wd_; ++c) {
this.text_[r][c] = ' ';
this.attr_[r][c] = this.bkgd_;
}
}
}
VT100.prototype.clrtobot = function()
{
var ht = this.ht_;
var wd = this.wd_;
this.clrtoeol();
for (var r = this.row_ + 1; r < ht; ++r) {
for (var c = 0; c < wd; ++c) {
this.text_[r][c] = ' ';
this.attr_[r][c] = this.bkgd_;
}
}
}
VT100.prototype.clrtoeol = function()
{
var r = this.row_;
if (r >= this.ht_)
return;
for (var c = this.col_; c < this.wd_; ++c) {
this.text_[r][c] = ' ';
this.attr_[r][c] = this.bkgd_;
}
}
VT100.prototype.COLOR_PAIR = function(pn)
{
return pn << VT100.COLOR_SHIFT_;
}
VT100.prototype.curs_set = function(vis, grab)
{
if (vis !== undefined)
this.cursor_vis_ = (vis > 0);
if (grab === true || grab === false) {
if (grab === this.grab_events_)
return;
if (grab) {
this.grab_events_ = true;
VT100.the_vt_ = this;
document.onkeypress = VT100.handle_onkeypress_;
if (VT100.browser_ie_)
document.onkeydown = VT100.handle_onkeydown_;
} else {
document.onkeypress = undefined;
if (VT100.browser_ie_)
document.onkeydown = VT100.handle_onkeydown_;
this.grab_events_ = false;
VT100.the_vt_ = undefined;
}
}
}
VT100.prototype.echo = function()
{
this.echo_ = true;
}
VT100.prototype.erase = VT100.prototype.clear;
VT100.prototype.getch = function(isr)
{
this.refresh();
this.getch_isr_ = isr;
setTimeout(VT100.go_getch_, 0);
}
VT100.prototype.getmaxyx = function()
{
return { y: this.ht_ - 1, x: this.wd_ - 1 };
}
VT100.prototype.getyx = function()
{
return { y: this.row_, x: this.col_ };
}
VT100.prototype.move = function(r, c)
{
if (r < 0)
r = 0;
else if (r >= this.ht_)
r = this.ht_ - 1;
if (c < 0)
c = 0;
else if (c >= this.wd_)
c = this.wd_ - 1;
this.row_ = r;
this.col_ = c;
}
VT100.prototype.noecho = function()
{
this.echo_ = false;
}
VT100.prototype.pair_content = function(pn)
{
return this.color_pair_[pn];
}
VT100.prototype.PAIR_NUMBER = function(at)
{
return at >> VT100.COLOR_SHIFT_;
}
VT100.prototype.refresh = function()
{
var r, c, stuff = "", end_tag = "", at = -1, n_at, ch,
pair, cr, cc, ht, wd, cv;
ht = this.ht_;
wd = this.wd_;
cr = this.row_;
cc = this.col_;
cv = this.cursor_vis_;
if (cc >= wd)
cc = wd - 1;
for (r = 0; r < ht; ++r) {
stuff += '<br>';
for (c = 0; c < wd; ++c) {
n_at = this.attr_[r][c];
if (cv && r == cr && c == cc)
n_at ^= VT100.A_REVERSE;
if (n_at != at) {
stuff += end_tag;
end_tag = "";
if (n_at & VT100.A_BLINK) {
stuff += "<blink>";
end_tag = "</blink>" + end_tag;
}
if (n_at & VT100.A_STANDOUT)
n_at |= VT100.A_BOLD;
pair = this.html_colours_(n_at);
stuff += '<span style="color:' + pair.f +
';background-color:' + pair.b;
if (n_at & VT100.A_UNDERLINE)
stuff += ';text-decoration:underline';
stuff += ';">';
end_tag = "</span>" + end_tag;
at = n_at;
}
ch = this.text_[r][c];
switch (ch) {
case '&':
stuff += '&amp;'; break;
case '<':
stuff += '&lt;'; break;
case '>':
stuff += '&gt;'; break;
case ' ':
stuff += '&nbsp;'; break;
default:
stuff += ch;
}
}
}
this.scr_.innerHTML = "&nbsp;<b>" + stuff + end_tag + "</b><br>&nbsp;";
}
VT100.prototype.scroll = function()
{
var n_text = this.text_[0], n_attr = this.attr_[0],
ht = this.ht_, wd = this.wd_;
for (var r = 1; r < ht; ++r) {
this.text_[r - 1] = this.text_[r];
this.attr_[r - 1] = this.attr_[r];
}
this.text_[ht - 1] = n_text;
this.attr_[ht - 1] = n_attr;
for (var c = 0; c < wd; ++c) {
n_text[c] = ' ';
n_attr[c] = this.bkgd_;
}
}
VT100.prototype.standend = function()
{
this.attrset(0);
}
VT100.prototype.standout = function()
{
this.attron(VT100.A_STANDOUT);
}
VT100.prototype.write = function(stuff)
{
var ch, x, r, c, i, j, yx, myx;
for (i = 0; i < stuff.length; ++i) {
ch = stuff.charAt(i);
switch (ch) {
case '\x00':
case '\x7f':
continue;
case '\a':
case '\b':
case '\t':
case '\r':
this.addch(ch);
continue;
case '\n':
case '\v':
case '\f': // what a mess
yx = this.getyx();
myx = this.getmaxyx();
if (yx.y >= myx.y) {
this.scroll();
this.move(myx.y, 0);
} else
this.move(yx.y + 1, 0);
continue;
case '\x18':
case '\x1a':
this.esc_state_ = 0;
continue;
case '\x1b':
this.esc_state_ = 1;
continue;
case '\x9b':
this.esc_state_ = 2;
continue;
}
// not a recognized control character
switch (this.esc_state_) {
case 0: // not in escape sequence
this.addch(ch);
break;
case 1: // just saw ESC
switch (ch) {
case '[':
this.esc_state_ = 2;
break;
}
break;
case 2: // just saw CSI
this.csi_parms_ = [0];
this.esc_state_ = 3;
case 3: // saw CSI and parameters
switch (ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
x = this.csi_parms_.pop();
this.csi_parms_.push(x * 10 + ch * 1);
continue;
case ';':
if (this.csi_parms_.length < 17)
this.csi_parms_.push(0);
case '?': // ?!?
continue;
}
this.esc_state_ = 0;
switch (ch) {
case 'H':
this.esc_state_ = 0;
this.csi_parms_.push(0);
this.move(this.csi_parms_[0] - 1,
this.csi_parms_[1] - 1);
break;
case 'J':
switch (this.csi_parms_[0]) {
case 0:
this.clrtobot();
break;
case 2:
this.clear();
this.move(0, 0);
}
break;
case 'm':
for (j=0; j<this.csi_parms_.length; ++j) {
x = this.csi_parms_[j];
switch (x) {
case 0:
this.standend();
break;
case 1:
this.attron(VT100.A_BOLD);
break;
}
}
case '[':
this.esc_state_ = 4;
}
break;
case 4: // saw CSI [
this.esc_state_ = 0; // gobble char.
}
}
this.refresh();
}

105
index.html Normal file
View file

@ -0,0 +1,105 @@
<html>
<head>
<title>scriptreplay in javascript</title>
<script type="text/javascript" src="./VT100.js" ></script>
<script type="text/javascript" src="./scriptreplay.js" ></script>
<script type="text/javascript"><!--
window.addEventListener("load", function(evt) {
vt = new VT100(80, 24, "term");
vt.clear();
vt.refresh();
vt.write(
"\n\n\n" +
" * This javascript terminal window is 80x24 characters, so it might be\n" +
" best to adjust your terminal window to that size as well using the\n" +
" following to check:\n" +
" $ watch \"tput cols; tput lines\"\n" +
" * Start recording:\n" +
" $ SHELL=/bin/sh TERM=vt100 script -t typescript 2> timingfile\n" +
" * Do your stuff and when done exit script with `exit`, `logout` or\n" +
" ctrl-d.\n" +
" * To test how your recorded session looks like, use:\n" +
" $ scriptreplay timingfile typescript\n" +
" * Enter `timingfile` and `typescript` into form above and hit the play\n" +
" button.\n");
document.getElementById("stop").addEventListener("click", stop, false);
document.getElementById("speed").addEventListener('change', set_speed, false);
document.getElementById("fontsize").addEventListener('change', set_fontsize, false);
document.getElementById("play").addEventListener("click", play, false);
var samples = document.querySelectorAll("ul#sample>li>a[id^=\"sample_\"]");
for (var i = 0; i < samples.length; i++) {
samples[i].addEventListener('click', function(evt) {
play_file(evt.target.id.substr(7));
}, false);
}
}, false);
--></script>
</head>
<body>
<h2>scriptreplay in javascript</h2>
<p><tt>script</tt> and <tt>scriptreplay</tt> are part of the <tt>bsdutils</tt>
package in debian and ubuntu, <tt>util-linux-ng</tt> in fedora and
<tt>util-linux</tt> in suse. They allow to capture a terminal or script output
and replay it.</p>
<p>This page uses the <a href="./VT100.js">vt100 emulator</a> by
<a href="http://fzort.org/bi/o.php#vt100_js">frank bi</a> and adds
<a href="./scriptreplay.js">code of my own</a> to read typescript and timing
files to make it possible to replay captured scripts a web browser.</p>
<p>By adding an upload facility to this it would be possible to have a youtube
or pastebin for terminal sessions. Due to laziness this remains a proof of
concept for now though.</p>
<p>(C) 2011 Johannes 'josch' Schauer &lt;j [dot] schauer [at] email [dot] de&gt;</p>
<fieldset>
<legend>file input</legend>
typescript: <input type="file" id="typescript" name="typescript" /><br />
timingfile: <input type="file" id="timingfile" name="typescript" /><br />
</fieldset>
<fieldset>
<legend>samples</legend>
<ul id="sample">
<li><a href="javascript:void()" id="sample_qemu">qemu boot</a></li>
<li><a href="javascript:void()" id="sample_starwars">star wars</a></li>
</ul>
</fieldset>
<tt><pre id=term></pre></tt>
<fieldset>
<legend>play control</legend>
<button id="play">play</button>
<button id="stop">stop</button>
</fieldset>
<fieldset>
<legend>output properties</legend>
Font size
<select id="fontsize">
<option value="8">8</option>
<option value="10">10</option>
<option value="12" selected="selected">12</option>
<option value="14">14</option>
<option value="16">16</option>
<option value="18">18</option>
</select>
Speed
<select id="speed">
<option value="0.25">slowest</option>
<option value="0.5">slower</option>
<option value="0.75">slow</option>
<option value="1.0" selected="selected">normal</option>
<option value="1.5">fast</option>
<option value="2.0">faster</option>
<option value="4.0">fastest</option>
</select>
</fieldset>
</body>
</html>

262
qemu.script Normal file
View file

@ -0,0 +1,262 @@
Script started on Mon 04 Jul 2011 10:53:10 AM CEST
$ qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda hda.img -append "root=/dev/sda1 console=ttyS0" -nographic
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 2.6.32-5-4kc-malta (Debian 2.6.32-35) (dannf@debian.org) (gcc version 4.3.5 (Debian 4.3.5-4) ) #1 Tue Jun 14 18:46:39 UTC 2011
[ 0.000000]
[ 0.000000] LINUX started...
[ 0.000000] bootconsole [early0] enabled
[ 0.000000] CPU revision is: 00019300 (MIPS 24Kc)
[ 0.000000] FPU revision is: 00000000
[ 0.000000] Determined physical RAM map:
[ 0.000000] memory: 00001000 @ 00000000 (reserved)
[ 0.000000] memory: 000ef000 @ 00001000 (ROM data)
[ 0.000000] memory: 005b2000 @ 000f0000 (reserved)
[ 0.000000] memory: 0795e000 @ 006a2000 (usable)
[ 0.000000] Wasting 54336 bytes for tracking 1698 unused pages
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Zone PFN ranges:
[ 0.000000] DMA 0x00000000 -> 0x00001000
[ 0.000000] Normal 0x00001000 -> 0x00008000
[ 0.000000] Movable zone start PFN for each node
[ 0.000000] early_node_map[1] active PFN ranges
[ 0.000000] 0: 0x00000000 -> 0x00008000
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 32512
[ 0.000000] Kernel command line: root=/dev/sda1 console=ttyS0
[ 0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Primary instruction cache 2kB, VIPT, 2-way, linesize 16 bytes.
[ 0.000000] Primary data cache 2kB, 2-way, VIPT, no aliases, linesize 16 bytes
[ 0.000000] Writing ErrCtl register=00000000
[ 0.000000] Readback ErrCtl register=00000000
[ 0.000000] Memory: 122972k/124280k available (3979k kernel code, 1128k reserved, 1088k data, 208k init, 0k highmem)
[ 0.000000] SLUB: Genslabs=7, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Hierarchical RCU implementation.
[ 0.000000] NR_IRQS:256
[ 0.000000] CPU frequency 200.00 MHz
[ 0.000000] Console: colour dummy device 80x25
[ 0.008000] Calibrating delay loop... 784.38 BogoMIPS (lpj=1568768)
[ 0.088000] Security Framework initialized
[ 0.088000] SELinux: Disabled at boot.
[ 0.088000] Mount-cache hash table entries: 512
[ 0.096000] Initializing cgroup subsys ns
[ 0.096000] Initializing cgroup subsys cpuacct
[ 0.096000] Initializing cgroup subsys devices
[ 0.096000] Initializing cgroup subsys freezer
[ 0.096000] Initializing cgroup subsys net_cls
[ 0.108000] devtmpfs: initialized
[ 0.120000] regulator: core version 0.5
[ 0.120000] NET: Registered protocol family 16
[ 0.136000] bio: create slab <bio-0> at 0
[ 0.140000] vgaarb: loaded
[ 0.140000] SCSI subsystem initialized
[ 0.144000] pci 0000:00:0a.3: BAR 14: address space collision on of bridge [0x1100-0x110f]
[ 0.144000] pci 0000:00:0a.3: quirk: region 1100-110f claimed by PIIX4 SMB
[ 0.148000] vgaarb: device added: PCI:0000:00:12.0,decodes=io+mem,owns=none,locks=none
[ 0.148000] pci 0000:00:0a.3: BAR 14: bogus alignment [0x1100-0x110f] flags 0x100
[ 0.156000] Switching to clocksource MIPS
[ 0.180000] NET: Registered protocol family 2
[ 0.180000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.184000] TCP established hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.184000] TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.184000] TCP: Hash tables configured (established 4096 bind 4096)
[ 0.184000] TCP reno registered
[ 0.184000] NET: Registered protocol family 1
[ 0.188000] RPC: Registered udp transport module.
[ 0.188000] RPC: Registered tcp transport module.
[ 0.188000] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.196000] audit: initializing netlink socket (disabled)
[ 0.200000] type=2000 audit(1309769597.200:1): initialized
[ 0.212000] VFS: Disk quotas dquot_6.5.2
[ 0.212000] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[ 0.220000] msgmni has been set to 240
[ 0.228000] alg: No test for stdrng (krng)
[ 0.228000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[ 0.228000] io scheduler noop registered
[ 0.232000] io scheduler anticipatory registered
[ 0.232000] io scheduler deadline registered
[ 0.232000] io scheduler cfq registered (default)
[ 0.232000] PCI: Enabling device 0000:00:12.0 (0000 -> 0002)
[ 0.232000] cirrusfb 0000:00:12.0: Cirrus Logic chipset on PCI bus, RAM (4096 kB) at 0x10000000
[ 0.448000] Console: switching to colour frame buffer device 80x30
[ 0.468000] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 0.472000] serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 0.472000] console [ttyS0] enabled, bootconsole disabled
[ 0.472000] console [ttyS0] enabled, bootconsole disabled
[ 0.476000] serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[ 0.476000] serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 18) is a 16550A
[ 0.484000] brd: module loaded
[ 0.488000] PCI: Enabling device 0000:00:0a.1 (0000 -> 0001)
[ 0.492000] scsi0 : ata_piix
[ 0.492000] scsi1 : ata_piix
[ 0.492000] ata1: PATA max UDMA/33 cmd 0x1f0 ctl 0x3f6 bmdma 0x1040 irq 14
[ 0.492000] ata2: PATA max UDMA/33 cmd 0x170 ctl 0x376 bmdma 0x1048 irq 15
[ 0.496000] pcnet32.c:v1.35 21.Apr.2008 tsbogend@alpha.franken.de
[ 0.500000] PCI: Enabling device 0000:00:0b.0 (0000 -> 0003)
[ 0.500000] pcnet32: PCnet/PCI II 79C970A at 0x1020, 52:54:00:12:34:56 assigned IRQ 10.
[ 0.500000] eth0: registered as PCnet/PCI II 79C970A
[ 0.500000] pcnet32: 1 cards_found.
[ 0.504000] serio: i8042 KBD port at 0x60,0x64 irq 1
[ 0.504000] serio: i8042 AUX port at 0x60,0x64 irq 12
[ 0.508000] mice: PS/2 mouse device common for all mice
[ 0.508000] rtc_cmos rtc_cmos: rtc core: registered rtc_cmos as rtc0
[ 0.508000] rtc0: alarms up to one day, 242 bytes nvram
[ 0.512000] TCP cubic registered
[ 0.512000] NET: Registered protocol family 17
[ 0.512000] registered taskstats version 1
[ 0.516000] rtc_cmos rtc_cmos: setting system clock to 2011-07-04 08:35:13 UTC (1309768513)
[ 0.516000] Initalizing network drop monitor service
[ 0.612000] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
[ 0.660000] ata2.00: ATAPI: QEMU DVD-ROM, 0.12.5, max UDMA/100
[ 0.664000] ata1.00: ATA-7: QEMU HARDDISK, 0.12.5, max UDMA/100
[ 0.664000] ata1.00: 8192000 sectors, multi 16: LBA48
[ 0.664000] ata1.00: configured for UDMA/33
[ 0.672000] ata2.00: configured for UDMA/33
[ 0.676000] scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK 0.12 PQ: 0 ANSI: 5
[ 0.680000] sd 0:0:0:0: [sda] 8192000 512-byte logical blocks: (4.19 GB/3.90 GiB)
[ 0.680000] sd 0:0:0:0: [sda] Write Protect is off
[ 0.684000] scsi 1:0:0:0: CD-ROM QEMU QEMU DVD-ROM 0.12 PQ: 0 ANSI: 5
[ 0.684000] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 0.688000] sda: sda1 sda2 < sda5 >
[ 0.704000] sd 0:0:0:0: [sda] Attached SCSI disk
[ 0.712000] kjournald starting. Commit interval 5 seconds
[ 0.716000] EXT3-fs: mounted filesystem with ordered data mode.
[ 0.716000] VFS: Mounted root (ext3 filesystem) readonly on device 8:1.
[ 0.720000] Freeing prom memory: 956k freed
[ 0.732000] Freeing unused kernel memory: 208k freed
INIT: version 2.88 booting
Using makefile-style concurrent boot in runlevel S.
.udev/ already exists on the static /dev! ... (warning).
Starting the hotplug events dispatcher: udevd.
Synthesizing the initial hotplug events...done.
Waiting for /dev to be fully populated...[ 5.612000] usbcore: registered new interface driver usbfs
[ 5.612000] usbcore: registered new interface driver hub
[ 5.664000] piix4_smbus 0000:00:0a.3: SMBus Host Controller at 0x1100, revision 0
[ 5.664000] usbcore: registered new device driver usb
[ 5.864000] sr0: scsi3-mmc drive: 4x/4x xa/form2 tray
[ 5.864000] Uniform CD-ROM driver Revision: 3.20
[ 5.976000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 6.060000] physmap platform flash device: 00400000 at 1e000000
[ 6.108000] uhci_hcd: USB Universal Host Controller Interface driver
[ 6.108000] PCI: Enabling device 0000:00:0a.2 (0000 -> 0001)
[ 6.108000] uhci_hcd 0000:00:0a.2: UHCI Host Controller
[ 6.112000] uhci_hcd 0000:00:0a.2: new USB bus registered, assigned bus number 1
[ 6.128000] uhci_hcd 0000:00:0a.2: irq 11, io base 0x00001000
[ 6.160000] usb usb1: New USB device found, idVendor=1d6b, idProduct=0001
[ 6.160000] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 6.160000] usb usb1: Product: UHCI Host Controller
[ 6.160000] usb usb1: Manufacturer: Linux 2.6.32-5-4kc-malta uhci_hcd
[ 6.160000] usb usb1: SerialNumber: 0000:00:0a.2
[ 6.216000] usb usb1: configuration #1 chosen from 1 choice
[ 6.220000] hub 1-0:1.0: USB hub found
[ 6.220000] hub 1-0:1.0: 2 ports detected
[ 6.236000] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input1
[ 6.308000] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 6.312000] sr 1:0:0:0: Attached scsi generic sg1 type 5
[ 6.976000] physmap-flash.0: PFOW string at 0x0 is not found
[ 7.056000] cmdlinepart partition parsing not available
[ 7.084000] RedBoot partition parsing not available
[ 7.084000] Using physmap partition information
[ 7.084000] Creating 3 MTD partitions on "physmap-flash.0":
[ 7.084000] 0x000000000000-0x000000100000 : "YAMON"
[ 7.092000] 0x000000100000-0x0000003e0000 : "User FS"
[ 7.096000] 0x0000003e0000-0x000000400000 : "Board Config"
done.
Activating swap...[ 8.312000] Adding 219128k swap on /dev/sda5. Priority:-1 extents:1 across:219128k
done.
Checking root file system...fsck from util-linux-ng 2.17.2
/dev/sda1: clean, 41254/242400 files, 285212/968448 blocks
done.
[ 8.988000] EXT3 FS on sda1, internal journal
Cleaning up ifupdown....
Setting up networking....
Loading kernel modules...[ 9.980000] loop: module loaded
done.
Activating lvm and md swap...done.
Checking file systems...fsck from util-linux-ng 2.17.2
done.
Mounting local filesystems...done.
Activating swapfile swap...done.
Cleaning up temporary files....
Configuring network interfaces...done.
Starting portmap daemon....
Starting NFS common utilities: statd.
Cleaning up temporary files...[ 14.824000] eth0: link up
.
Setting kernel variables ...done.
INIT: Entering runlevel: 2
Using makefile-style concurrent boot in runlevel 2.
Starting NFS common utilities: statd.
Starting portmap daemon...Already running..
Starting enhanced syslogd: rsyslogd.
Starting deferred execution scheduler: atd.
Starting periodic command scheduler: cron.
Starting system message bus: dbus.
Starting MTA: exim4.
[ 28.976000] NET: Registered protocol family 10
Debian GNU/Linux 6.0 debian ttyS0
debian login: root
Password:
Last login: Mon Jul 4 09:33:06 CEST 2011 on ttyS0
Linux debian 2.6.32-5-4kc-malta #1 Tue Jun 14 18:46:39 UTC 2011 mips
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@debian:~# uname -a
Linux debian 2.6.32-5-4kc-malta #1 Tue Jun 14 18:46:39 UTC 2011 mips GNU/Linux
root@debian:~# cat /proc/cpuinfo
system type : MIPS Malta
processor : 0
cpu model : MIPS 24Kc V0.0 FPU V0.0
BogoMIPS : 784.38
wait instruction : yes
microsecond timers : yes
tlb_entries : 16
extra interrupt vector : yes
hardware watchpoint : yes, count: 1, address/irw mask: [0x0ff8]
ASEs implemented :
shadow register sets : 1
core : 0
VCED exceptions : not available
VCEI exceptions : not available
root@debian:~# halt

Broadcast message from root@debian (ttyS0) (Mon Jul 4 10:36:14 2011):
The system is going down for system halt NOW!
INIT: Switching to runlevel: 0
root@debian:~# INIT: Sending processes the TERM signal
Using makefile-style concurrent boot in runlevel 0.
Stopping deferred execution scheduler: atd.
Stopping MTA: exim4_listener.
Asking all remaining processes to terminate...done.
All processes ended within 2 seconds....done.
Stopping enhanced syslogd: rsyslogd.
Stopping portmap daemon....
Stopping NFS common utilities: statd.
Bad SWSTYLE=0x04
Deconfiguring network interfaces...Internet Systems Consortium DHCP Client 4.1.1-P1
Copyright 2004-2010 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/eth0/52:54:00:12:34:56
Sending on LPF/eth0/52:54:00:12:34:56
Sending on Socket/fallback
DHCPRELEASE on eth0 to 10.0.2.2 port 67
done.
Cleaning up ifupdown....
Saving the system clock.
Deactivating swap...done.
Will now halt.
$ exit
Script done on Mon 04 Jul 2011 10:54:33 AM CEST

198
qemu.time Normal file
View file

@ -0,0 +1,198 @@
0.596415 2
0.015173 125
5.780041 2
1.039932 793
0.049982 358
0.010029 651
0.009955 289
0.010026 94
2.939978 41
0.009958 32
0.070038 401
0.010057 39
0.019968 97
0.009996 47
0.010002 252
0.010000 226
0.009973 399
0.030011 236
0.010025 127
0.009969 122
0.009994 44
0.010029 506
0.009990 72
0.219995 271
0.019997 151
0.010009 330
0.009992 359
0.010024 23
0.000017 5
0.000012 393
0.009949 155
0.010019 93
0.090023 197
0.049982 98
0.009962 437
0.010017 37
0.009987 59
0.010005 133
0.010040 126
0.009964 58
0.009994 27
0.180012 4
0.010035 51
0.129993 3
0.045599 45
0.424369 27
0.140006 45
0.270003 4
0.290000 42
0.130012 8
0.479987 41
0.380031 126
2.399973 87
0.049983 59
0.010009 113
0.190004 76
0.120004 69
0.080005 287
0.067802 67
0.000037 349
0.032161 156
0.059996 103
0.019999 124
0.070005 67
0.669997 61
0.079992 32
0.019996 14
0.000019 5
0.000013 4
0.000016 2
0.000012 234
0.009944 64
0.010001 8
0.370023 18
0.779984 90
0.059988 8
0.010016 28
0.129994 33
0.200000 58
0.119996 3
0.010008 8
0.039999 51
0.170013 23
0.370015 4
0.159999 24
0.069972 4
0.159990 25
0.100006 37
0.130004 8
0.300000 29
1.310011 8
0.039991 24
0.039991 30
0.130006 3
0.000021 8
0.039982 29
0.089997 8
0.059996 27
0.019991 8
0.040015 30
0.099998 4
0.459992 33
0.180006 8
0.240004 26
0.049996 4
0.210005 36
0.219998 4
0.620003 30
0.350055 28
0.339933 3
0.000033 4
0.300007 28
0.269964 8
0.060055 7
0.879942 24
0.010045 54
0.109966 40
1.599991 46
0.030000 39
1.170010 46
1.279981 41
0.020009 4
0.460008 37
1.040004 13
0.019993 6
6.320004 4
0.279992 52
0.299999 3
1.230074 39
0.009964 14
0.009961 1
5.940003 1
0.129993 1
0.160008 1
0.110012 3
0.240002 10
0.189996 3
1.370004 424
0.359983 15
8.180054 1
1.659965 1
0.119988 1
0.160018 1
0.059981 1
0.400005 1
0.190007 1
0.149992 1
0.179992 3
0.180015 81
0.050017 15
0.010008 1
1.520035 1
0.099976 1
0.039946 1
0.100034 1
0.220008 1
0.189971 1
0.110026 1
0.100004 2
0.389977 1
0.020018 1
0.470004 1
0.099966 5
0.440017 3
0.620020 409
0.039985 15
0.009990 1
6.040066 1
0.049927 1
0.130006 1
0.120011 3
0.310013 133
0.119961 50
0.600002 44
0.009997 54
1.170033 46
0.899968 28
0.010002 4
0.100023 46
0.579972 8
0.159989 48
1.310007 35
0.039996 4
0.220008 30
0.619996 40
0.050000 18
0.940034 388
0.130012 27
0.449955 27
0.020000 20
0.389991 8
0.090015 17
0.840000 2
0.970052 1
1.709937 1
0.080006 1
0.089997 1
0.160021 2

133
scriptreplay.js Normal file
View file

@ -0,0 +1,133 @@
var vt, timer;
var speed = 1.0;
function Timer(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= new Date() - start;
};
this.resume = function() {
start = new Date();
timerId = window.setTimeout(callback, remaining);
};
this.resume();
}
function get_file_contents(filename, callback) {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
req.open("GET", filename, false);
req.onreadystatechange = function() {
// status is 0 for local files
if (req.readyState==4 && ( req.status==200 || req.status==0)) {
callback(req.responseText);
}
}
req.send(null);
}
function play_file(name) {
get_file_contents(name+".script", function(typescript_data) {
get_file_contents(name+".time", function(timing_data) {
run_typescript(typescript_data, timing_data);
});
});
}
function set_speed(evt) {
var value = evt.target.options[evt.target.selectedIndex].value;
speed = parseFloat(value);
}
function set_fontsize(evt) {
var value = evt.target.options[evt.target.selectedIndex].value;
document.getElementById("term").style.fontSize=value;
}
function play(evt) {
if (evt.target.textContent == "play") {
readBlob('typescript', reader_onloadend);
} else if (evt.target.textContent == "resume") {
evt.target.textContent = "pause";
timer.resume();
} else if (evt.target.textContent == "pause") {
evt.target.textContent = "resume";
timer.pause();
}
}
function stop(evt) {
document.getElementById("play").textContent = "play";
timer.pause();
vt.clear();
vt.refresh();
}
function run_typescript(typescript_data, timing_data) {
if (timer) timer.pause();
document.getElementById("play").textContent = "pause";
vt.clear();
vt.refresh();
var where = 0;
var linenum = 0;
var timings = timing_data.split("\n");
var firstlinelen = typescript_data.indexOf("\n") + 1;
var text = typescript_data.substr(0, firstlinelen);
var newtext = "";
where += firstlinelen;
timer = new Timer(
function() {
vt.write(text);
text = newtext;
var me = arguments.callee;
var line = timings[linenum].split(" ");
var time = parseFloat(line[0]);
var bytes = parseInt(line[1]);
if (isFinite(time) && isFinite(bytes)) {
newtext = typescript_data.substr(where, bytes);
where += bytes;
linenum += 1;
timer = new Timer(me, time*1000*1/speed);
} else {
vt.write(typescript_data.substr(where, typescript_data.length-where));
document.getElementById("play").textContent = "play";
}
}, 0);
}
function reader_onloadend(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
typescript_data = evt.target.result;
readBlob('timingfile',
function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
timing_data = evt.target.result;
run_typescript(typescript_data, timing_data);
}
});
}
}
function readBlob(id, onload_handler) {
var files = document.getElementById(id).files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var blob = file.slice(0, file.size);
var reader = new FileReader();
reader.onloadend = onload_handler;
reader.onerror = function(evt) {alert(evt);};
reader.readAsBinaryString(blob);
}

61441
starwars.script Normal file

File diff suppressed because it is too large Load diff

3417
starwars.time Normal file

File diff suppressed because it is too large Load diff