mirror of
https://github.com/sigmasternchen/Wish
synced 2025-03-14 23:28:53 +00:00
first commit
This commit is contained in:
commit
fbd7ede700
20 changed files with 2323 additions and 0 deletions
95
BIOS.js
Normal file
95
BIOS.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
var BIOS = function() {
|
||||
}
|
||||
BIOS.logo = "\033[32m" +
|
||||
" .__ .__ \n" +
|
||||
"__ _ _|__| _____| |__ \n" +
|
||||
"\\ \\/ \\/ / |/ ___/ | \\ \n" +
|
||||
" \\ /| |\\___ \\| Y \\\n" +
|
||||
" \\/\\_/ |__/____ >___| /\n" +
|
||||
" \\/ \\/ \033[31mBIOS\033[0m\n";
|
||||
BIOS.hdds;
|
||||
BIOS.lastKey;
|
||||
BIOS.tickid;
|
||||
BIOS.state;
|
||||
BIOS.bootDevice;
|
||||
BIOS.init = function() {
|
||||
console.log("BIOS: init");
|
||||
BIOS.lastKey = 0;
|
||||
console.log("BIOS: register key interrupt");
|
||||
Emulator.interrupts['key'] = BIOS.key;
|
||||
}
|
||||
BIOS.main = function() {
|
||||
console.log("BIOS: main");
|
||||
console.log("BIOS: register 100ms-timer");
|
||||
this.tickid = Emulator.registerTimer(100, BIOS.tick);
|
||||
console.log("BIOS: get hdds");
|
||||
this.hdds = Emulator.Devices.getHarddisks();
|
||||
var text = this.logo + "\n" +
|
||||
"Keyboard: found at name=" + Emulator.input.name + "\n" +
|
||||
"Monitor: found at id=" + Emulator.Output.screen.parentElement.id + "\n\n" +
|
||||
"Harddisks: \n";
|
||||
for (var i = 0; i < this.hdds.length; i++) {
|
||||
text += " " + i + ": "+ this.hdds[i].name + "\n";
|
||||
}
|
||||
Emulator.output(text);
|
||||
if (this.hdds.length == 0) {
|
||||
Emulator.output("No harddisks found. Please insert a bootable device and restart the computer..\n\n");
|
||||
Emulator.output("\033[31msystem halt\033[0m");
|
||||
console.log("BIOS: remove all event handlers");
|
||||
Emulator.interrupts = new Array();
|
||||
Emulator.unregisterTimer(this.tickid);
|
||||
return;
|
||||
}
|
||||
if (this.hdds.length > 1) {
|
||||
Emulator.output("\nPlease select booting device by pressing the device nr. ");
|
||||
this.state = 0;
|
||||
} else {
|
||||
this.state = 1;
|
||||
}
|
||||
}
|
||||
BIOS.key = function(keycode) {
|
||||
BIOS.lastKey = keycode;
|
||||
}
|
||||
BIOS.tick = function() {
|
||||
switch(BIOS.state) {
|
||||
case 0:
|
||||
if (isNumber(KeyCodes.normalKey(BIOS.lastKey))) {
|
||||
if (BIOS.hdds[BIOS.bootDevice = parseInt(KeyCodes.normalKey(BIOS.lastKey))])
|
||||
BIOS.state = 2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
BIOS.bootDevice = 0;
|
||||
BIOS.state = 2;
|
||||
break;
|
||||
case 2:
|
||||
Emulator.output("\n\nSearching for MBR on " + BIOS.hdds[BIOS.bootDevice].name + "...\n");
|
||||
if (!(mbr = BIOS.hdds[BIOS.bootDevice].mbr)) {
|
||||
console.log(mbr);
|
||||
Emulator.output("No MBR found. Please insert a bootable device and restart the computer...\n\n");
|
||||
Emulator.output("\033[31msystem halt\033[0m");
|
||||
console.log("BIOS: remove all event handlers");
|
||||
Emulator.interrupts = new Array();
|
||||
Emulator.unregisterTimer(BIOS.tickid);
|
||||
}
|
||||
Emulator.Request.include(BIOS.hdds[BIOS.bootDevice].name + "/" + mbr + "/init.js", BIOS.load);
|
||||
BIOS.state = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
BIOS.load = function() {
|
||||
console.log("BIOS: stop BIOS");
|
||||
console.log("BIOS: remove all event handlers");
|
||||
Emulator.interrupts = new Array();
|
||||
Emulator.unregisterTimer(BIOS.tickid);
|
||||
console.log("BIOS: start MBR");
|
||||
try {
|
||||
MBR.main(BIOS.hdds[BIOS.bootDevice]);
|
||||
} catch (exception) {
|
||||
console.dir(exception);
|
||||
Emulator.output("MBR is not bootable. Please insert a bootable device and restart the computer...\n\n");
|
||||
Emulator.output("\033[31msystem halt\033[0m");
|
||||
}
|
||||
}
|
603
Emulator.js
Normal file
603
Emulator.js
Normal file
|
@ -0,0 +1,603 @@
|
|||
var Emulator = function() {
|
||||
}
|
||||
Emulator.running = false;
|
||||
Emulator.startable = false;
|
||||
Emulator.input;
|
||||
Emulator.interrupts;
|
||||
Emulator.mainTickId;
|
||||
Emulator.init = function(output, input, xsize, ysize) {
|
||||
console.log("Emulator: define output screen");
|
||||
this.Output.screen = output;
|
||||
console.log("Emulator: init output");
|
||||
this.Output.init(xsize, ysize);
|
||||
console.log("Emulator: define input");
|
||||
this.input = input;
|
||||
console.log("Emulator: define interrupt array");
|
||||
this.interrupts = new Array();
|
||||
console.log("Emulator: adding event-handlers");
|
||||
this.addEventHandlers();
|
||||
console.log("Emulator: init finished");
|
||||
this.startable = true;
|
||||
}
|
||||
Emulator.main = function() {
|
||||
if (!Emulator.startable) {
|
||||
console.log("Emulator: not startable");
|
||||
return;
|
||||
}
|
||||
Emulator.running = true;
|
||||
Emulator.Output.cursorOn();
|
||||
console.log("Emulator: init bios");
|
||||
BIOS.init();
|
||||
console.log("Emulator: running bios");
|
||||
BIOS.main();
|
||||
}
|
||||
Emulator.kill = function() {
|
||||
console.log("Emulator: got hardware kill signal (powersw)");
|
||||
if (Emulator.interrupts['powersw'])
|
||||
Emulator.interrupts['powersw']();
|
||||
else {
|
||||
Emulator.running = false;
|
||||
Emulator.startable = false;
|
||||
console.log("Emulator: no powersw-event defined -> killing");
|
||||
Emulator.interrupts = new Array();
|
||||
Emulator.output("\n\n\033[31mPOWER BUTTON PRESSED - SYSTEM HALT\nKill in 5s");
|
||||
window.setTimeout(function(){Emulator.output("\033[2D4s");}, 1000);
|
||||
window.setTimeout(function(){Emulator.output("\033[2D3s");}, 2000);
|
||||
window.setTimeout(function(){Emulator.output("\033[2D2s");}, 3000);
|
||||
window.setTimeout(function(){Emulator.output("\033[2D1s");}, 4000);
|
||||
window.setTimeout(function(){Emulator.shutdown()}, 5000);
|
||||
}
|
||||
}
|
||||
Emulator.shutdown = function() {
|
||||
Emulator.running = false;
|
||||
Emulator.startable = true;
|
||||
Emulator.output("\033[0m\033[2J\033[0:0H");
|
||||
Emulator.Output.cursorOff()
|
||||
}
|
||||
Emulator.addEventHandlers = function() {
|
||||
console.log("Emulator: adding unfocus-event");
|
||||
this.input.onblur = this.refocus;
|
||||
console.log("Emulator: adding key-press-event");
|
||||
this.input.onkeypress = this.handleKeyPress;
|
||||
console.log("Emulator: adding key-down-event");
|
||||
this.input.onkeydown = this.handleKeyDown;
|
||||
var timerid = window.setInterval(function() {/*for (var i = 0; i < 10; i++)*/ Emulator.tick(0);}, 1);
|
||||
Emulator.mainTickId = timerid;
|
||||
console.log("Emulator: adding default 1ms (or cheated 0.1 ms) tick with tid=" + timerid);
|
||||
this.refocus();
|
||||
}
|
||||
Emulator.getKeyCode = function(e) {
|
||||
return window.event ? event.keyCode : e.which;
|
||||
}
|
||||
Emulator.genericKeyHandler = function(keycode) {
|
||||
if (Emulator.interrupts['key'])
|
||||
Emulator.interrupts['key'](keycode);
|
||||
}
|
||||
Emulator.handleKeyPress = function(e) {
|
||||
Emulator.genericKeyHandler(Emulator.getKeyCode(e));
|
||||
}
|
||||
Emulator.handleKeyDown = function(e) {
|
||||
var keycode = Emulator.getKeyCode(e);
|
||||
if (keycode == 8 || keycode == 46) {
|
||||
Emulator.handleKeyPress(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Emulator.refocus = function () {
|
||||
window.setTimeout(function() {Emulator.input.focus();}, 1);
|
||||
console.log("Emulator: refocus input")
|
||||
}
|
||||
Emulator.tick = function (time) {
|
||||
if (Emulator.interrupts[time])
|
||||
Emulator.interrupts[time]();
|
||||
}
|
||||
Emulator.registerTimer = function (time, routine) {
|
||||
var timerid = window.setInterval(routine, time);
|
||||
console.log("Emulator: timer startet t=" + time + " with tid=" + timerid);
|
||||
return timerid;
|
||||
}
|
||||
Emulator.unregisterTimer = function(timerid) {
|
||||
console.log("Emulator: timer cleared tid=" + timerid);
|
||||
window.clearInterval(timerid);
|
||||
}
|
||||
Emulator.output = function(text) {
|
||||
Emulator.ANSISequences.output(text);
|
||||
}
|
||||
Emulator.ANSISequences = function() {
|
||||
}
|
||||
Emulator.ANSISequences.ESC = "\033";
|
||||
Emulator.ANSISequences.output = function(text) {
|
||||
var normalText = "";
|
||||
var specialText = "";
|
||||
var specialText2 = "";
|
||||
var state = 0;
|
||||
for(var i = 0; i < text.length; i++) {
|
||||
switch(state) {
|
||||
case 0:
|
||||
specialText = "";
|
||||
speacielText2 = "";
|
||||
if (text[i] != Emulator.ANSISequences.ESC)
|
||||
normalText += text[i];
|
||||
else
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (text[i] == "[")
|
||||
state = 1;
|
||||
else {
|
||||
normalText += " " + text[i];
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (isNumber(text[i])) {
|
||||
specialText += text[i];
|
||||
break;
|
||||
} else {
|
||||
if (text[i] == '?') {
|
||||
state = 4;
|
||||
break;
|
||||
}
|
||||
if (text[i] == 's') {
|
||||
Emulator.Output.sxpos = Emulator.Output.xpos;
|
||||
Emulator.Output.sypos = Emulator.Output.ypos;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
if (text[i] == 'u') {
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = Emulator.Output.sxpos;
|
||||
Emulator.Output.ypos = Emulator.Output.sypos;
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
if (specialText.length < 1) {
|
||||
normalText += " [" + ((specialText2.length > 0) ? (specialText2 + ":") : "") + specialText;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
state = 2;
|
||||
}
|
||||
case 2:
|
||||
switch(text[i]) {
|
||||
case 'A':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.moveCursor(0, - parseInt(specialText), false);
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'B':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.moveCursor(0, parseInt(specialText), false);
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'C':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.moveCursor(parseInt(specialText), 0, false);
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'D':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.moveCursor(- parseInt(specialText), 0, false);
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'E':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.moveCursor(parseInt(specialText), 0, false);
|
||||
Emulator.Output.xpos = 0;
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'F':
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.moveCursor( - parseInt(specialText), 0, false);
|
||||
Emulator.Output.xpos = 0;
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'G':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = (parseInt(specialText) >= Emulator.Output.xsize) ? (Emulator.Output.xsize - 1) : parseInt(specialText);
|
||||
Emulator.Output.cursorOn();
|
||||
normalText = "";
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
case ':':
|
||||
// TODO Wrong!
|
||||
specialText2 = specialText;
|
||||
specialText = "";
|
||||
state = 1;
|
||||
break;
|
||||
case 'H':
|
||||
if (specialText2.length == 0) {
|
||||
normalText += " [" + specialText + 'G';
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = (parseInt(specialText2) >= Emulator.Output.xsize) ? (Emulator.Output.xsize - 1) : parseInt(specialText2);
|
||||
Emulator.Output.ypos = (parseInt(specialText) >= Emulator.Output.ysize) ? (Emulator.Output.ysize - 1) : parseInt(specialText);
|
||||
Emulator.Output.cursorOn();
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
normalText = "";
|
||||
state = 0;
|
||||
break;
|
||||
case 'J':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
normalText = "";
|
||||
switch(parseInt(specialText)) {
|
||||
case 0:
|
||||
var oldx = Emulator.Output.xpos;
|
||||
var oldy = Emulator.Output.ypos;
|
||||
var number = (Emulator.Output.ysize - oldy - 1) * Emulator.Output.xsize + (Emulator.Output.xsize - oldx - 1);
|
||||
var itext = "";
|
||||
for (var j = 0; j < number; j++)
|
||||
itext += " ";
|
||||
Emulator.Output.normalOutput(itext);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = oldx;
|
||||
Emulator.Output.ypos = oldy;
|
||||
Emulator.Output.cursorOn();
|
||||
break;
|
||||
case 1:
|
||||
var oldx = Emulator.Output.xpos;
|
||||
var oldy = Emulator.Output.ypos;
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = 0;
|
||||
Emulator.Output.ypos = 0;
|
||||
Emulator.Output.cursorOn();
|
||||
var number = (oldy) * Emulator.Output.xsize + oldx;
|
||||
var itext = "";
|
||||
for (var j = 0; j < number; j++)
|
||||
itext += " ";
|
||||
Emulator.Output.normalOutput(itext);
|
||||
break;
|
||||
case 2:
|
||||
var oldx = Emulator.Output.xpos;
|
||||
var oldy = Emulator.Output.ypos;
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = 0;
|
||||
Emulator.Output.ypos = 0;
|
||||
var itext = "";
|
||||
for (var j = 0; j < (Emulator.Output.xsize * Emulator.Output.ysize); j++)
|
||||
itext += " ";
|
||||
Emulator.Output.normalOutput(itext);
|
||||
Emulator.Output.cursorOff();
|
||||
Emulator.Output.xpos = oldx;
|
||||
Emulator.Output.ypos = oldy;
|
||||
Emulator.Output.cursorOn();
|
||||
break;
|
||||
default:
|
||||
normalText = " [" + ((specialText2.length > 0) ? (specialText2 + ":") : "") + specialText;
|
||||
break;
|
||||
}
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
// TODO
|
||||
case 'm':
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
normalText = "";
|
||||
|
||||
switch(parseInt(specialText)) {
|
||||
case 0:
|
||||
Emulator.Output.color = "#fff";
|
||||
Emulator.Output.backgroundColor = "#000";
|
||||
break;
|
||||
case 30:
|
||||
Emulator.Output.color = "#000";
|
||||
break;
|
||||
case 31:
|
||||
Emulator.Output.color = "#f00";
|
||||
break;
|
||||
case 32:
|
||||
Emulator.Output.color = "#0f0";
|
||||
break;
|
||||
case 33:
|
||||
Emulator.Output.color = "#ff0";
|
||||
break;
|
||||
case 34:
|
||||
Emulator.Output.color = "#00f";
|
||||
break;
|
||||
case 35:
|
||||
Emulator.Output.color = "#f0f";
|
||||
break;
|
||||
case 36:
|
||||
Emulator.Output.color = "#0ff";
|
||||
break;
|
||||
case 37:
|
||||
Emulator.Output.color = "#fff";
|
||||
break;
|
||||
|
||||
case 40:
|
||||
Emulator.Output.backgroundColor = "#000";
|
||||
break;
|
||||
case 41:
|
||||
Emulator.Output.backgroundColor = "#f00";
|
||||
break;
|
||||
case 42:
|
||||
Emulator.Output.backgroundColor = "#0f0";
|
||||
break;
|
||||
case 43:
|
||||
Emulator.Output.backgroundColor = "#ff0";
|
||||
break;
|
||||
case 44:
|
||||
Emulator.Output.backgroundColor = "#00f";
|
||||
break;
|
||||
case 45:
|
||||
Emulator.Output.backgroundColor = "#f0f";
|
||||
break;
|
||||
case 46:
|
||||
Emulator.Output.backgroundColor = "#0ff";
|
||||
break;
|
||||
case 47:
|
||||
Emulator.Output.backgroundColor = "#fff";
|
||||
break;
|
||||
default:
|
||||
normalText += " [" + ((specialText2.length > 0) ? (specialText2 + ":") : "") + specialText;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
specialText = "";
|
||||
specialText2 = "";
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
normalText += " [" + ((specialText2.length > 0) ? (specialText2 + ":") : "") + specialText;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (text[i] == '2')
|
||||
state = 5;
|
||||
else {
|
||||
normalText += " [?" + text[i];
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (text[i] == '5')
|
||||
state = 6;
|
||||
else {
|
||||
normalText += " [?2" + text[i];
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (text[i] == 'l') {
|
||||
Emulator.Output.displayCursor = false;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
if (text[i] == 'h') {
|
||||
Emulator.Output.displayCursor = true;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
normalText += " [25" + text[i];
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((specialText2.length || specialText.length) > 0)
|
||||
normalText += " [" + ((specialText2.length > 0) ? (specialText2 + ":") : "") + specialText;
|
||||
Emulator.Output.normalOutput(normalText);
|
||||
}
|
||||
|
||||
Emulator.Output = function() {
|
||||
}
|
||||
Emulator.Output.screen;
|
||||
Emulator.Output.xsize;
|
||||
Emulator.Output.ysize;
|
||||
Emulator.Output.xpos;
|
||||
Emulator.Output.ypos;
|
||||
Emulator.Output.sxpos;
|
||||
Emulator.Output.sypos;
|
||||
Emulator.Output.color;
|
||||
Emulator.Output.backgroundColor;
|
||||
Emulator.Output.displayCursor;
|
||||
Emulator.Output.shiftKey = 1;
|
||||
Emulator.Output.init = function(xsize, ysize) {
|
||||
console.log("Emulator: define matrix size");
|
||||
this.xsize = xsize;
|
||||
this.ysize = ysize;
|
||||
console.log("Emulator: reseting cursor position");
|
||||
this.xpos = 0;
|
||||
this.ypos = 0;
|
||||
this.displayCursor = true;
|
||||
console.log("Emulator: seting default colors");
|
||||
this.color = "#fff";
|
||||
this.backgroundColor = "#000";
|
||||
console.log("Emulator: generating matrix");
|
||||
this.generateMatrix();
|
||||
}
|
||||
Emulator.Output.generateMatrix = function() {
|
||||
var matrix = "<table id=\"matrix\">";
|
||||
for (var i = 0; i < this.ysize; i++) {
|
||||
matrix += "<tr>";
|
||||
for (var j = 0; j < this.xsize; j++) {
|
||||
matrix += "<td> </td>";
|
||||
}
|
||||
matrix += "</tr>";
|
||||
}
|
||||
matrix += "</table>";
|
||||
this.screen.innerHTML = matrix;
|
||||
this.screen = document.getElementById("matrix");
|
||||
}
|
||||
Emulator.Output.getCursor = function() {
|
||||
return Emulator.Output.screen.getElementsByTagName("tr")[Emulator.Output.ypos].getElementsByTagName("td")[Emulator.Output.xpos];
|
||||
}
|
||||
Emulator.Output.cursorOff = function() { // fix by Jonas
|
||||
if(document.getElementById("cursor") != undefined)
|
||||
document.getElementById("cursor").remove();
|
||||
}
|
||||
Emulator.Output.cursorOn = function() { // fix by Jonas
|
||||
if (Emulator.Output.displayCursor) {
|
||||
var cursorElement=document.createElement("div");
|
||||
var att=document.createAttribute("id");
|
||||
att.value = "cursor";
|
||||
cursorElement.setAttributeNode(att);
|
||||
cursorElement.style.background = "#000";
|
||||
cursorElement.style.height = "100%";
|
||||
cursorElement.style.border = "1px solid #fff";
|
||||
Emulator.Output.getCursor().appendChild(cursorElement);
|
||||
}
|
||||
}
|
||||
Emulator.Output.insert = function(char) {
|
||||
var cell = Emulator.Output.getCursor();
|
||||
cell.style.color = Emulator.Output.color;
|
||||
cell.style.backgroundColor = Emulator.Output.backgroundColor;
|
||||
Emulator.Output.getCursor().innerHTML = char;
|
||||
}
|
||||
Emulator.Output.moveCursor = function(x, y, lbreak) {
|
||||
Emulator.Output.xpos += x;
|
||||
Emulator.Output.ypos += y;
|
||||
if (lbreak) {
|
||||
if (Emulator.Output.xpos >= Emulator.Output.xsize)
|
||||
Emulator.Output.ypos++;
|
||||
if (Emulator.Output.xpos < 0)
|
||||
Emulator.Output.ypos--;
|
||||
Emulator.Output.xpos %= Emulator.Output.xsize;
|
||||
while (Emulator.Output.ypos >= Emulator.Output.ysize) {
|
||||
Emulator.Output.lineShift();
|
||||
}
|
||||
} else {
|
||||
if (Emulator.Output.xpos >= Emulator.Output.xsize)
|
||||
Emulator.Output.xpos = Emulator.Output.xsize - 1;
|
||||
if (Emulator.Output.xpos < 0)
|
||||
Emulator.Output.xpos = 0;
|
||||
if (Emulator.Output.ypos >= Emulator.Output.ysize)
|
||||
Emulator.Output.ypos = Emulator.Output.ysize - 1;
|
||||
if (Emulator.Output.ypos < 0)
|
||||
Emulator.Output.ypos = 0;
|
||||
}
|
||||
}
|
||||
Emulator.Output.lineShift = function() {
|
||||
for (var i = Emulator.Output.shiftKey; i < Emulator.Output.ysize; i++) {
|
||||
for (var j = 0; j < Emulator.Output.xsize; j++) {
|
||||
var to = Emulator.Output.screen.getElementsByTagName("tr")[i - 1].getElementsByTagName("td")[j];
|
||||
var from = Emulator.Output.screen.getElementsByTagName("tr")[i].getElementsByTagName("td")[j];
|
||||
to.innerHTML = from.innerHTML;
|
||||
to.style.color = from.style.color;
|
||||
to.style.backgroundColor = from.style.backgroundColor;
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < Emulator.Output.xsize; j++) {
|
||||
var to = Emulator.Output.screen.getElementsByTagName("tr")[Emulator.Output.ysize - 1].getElementsByTagName("td")[j];
|
||||
to.innerHTML = "";
|
||||
to.style.color = Emulator.Output.color;
|
||||
to.style.backgroundColor = Emulator.Output.backgroundColor;
|
||||
}
|
||||
if (--Emulator.Output.ypos < 0)
|
||||
Emulator.Output.ypos = 0;
|
||||
}
|
||||
Emulator.Output.normalOutput = function(text) {
|
||||
Emulator.Output.cursorOff();
|
||||
for(var i = 0; i < text.length; i++) {
|
||||
if (text[i] == "\n") {
|
||||
Emulator.Output.moveCursor(0, 1, true);
|
||||
Emulator.Output.xpos = 0;
|
||||
} else {
|
||||
Emulator.Output.insert(text[i]);
|
||||
Emulator.Output.moveCursor(1, 0, true);
|
||||
}
|
||||
}
|
||||
Emulator.Output.cursorOn();
|
||||
}
|
||||
|
||||
Emulator.Request = function() {
|
||||
}
|
||||
Emulator.Request.get = function(file, parameter, background, after) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open("GET", file + "?" + parameter, background);
|
||||
if (background) {
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
if (http.status != 200)
|
||||
after(http.status);
|
||||
else
|
||||
after(http.responseText);
|
||||
}
|
||||
};
|
||||
}
|
||||
http.send(null);
|
||||
if (!background)
|
||||
if (http.status != 200)
|
||||
return after(http.status);
|
||||
else
|
||||
return after(http.responseText);
|
||||
}
|
||||
Emulator.Request.post = function(file, getParameters, postParameters, background, after) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open("POST", file + "?" + getParameter, background);
|
||||
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
http.setRequestHeader("Content-length", postParameters.length);
|
||||
http.setRequestHeader("Connection", "close")
|
||||
if (background) {
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
after(http.responseText);
|
||||
}
|
||||
};
|
||||
}
|
||||
http.send(postParameters);
|
||||
if (!background)
|
||||
return after(http.responseText);
|
||||
}
|
||||
Emulator.Request.include = function(file, loaded) {
|
||||
console.log("Emulator: including file: " + file);
|
||||
var script = document.createElement("script");
|
||||
script.type = "text/javascript";
|
||||
script.onload = loaded;
|
||||
script.src = file;
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
Emulator.Devices = function() {
|
||||
}
|
||||
Emulator.Devices.getAll = function() {
|
||||
return JSON.parse(Emulator.Request.get("devices.json", "", false, ret));
|
||||
}
|
||||
Emulator.Devices.getHarddisks = function() {
|
||||
return Emulator.Devices.getAll().harddisks;
|
||||
}
|
20
KeyCodes.js
Normal file
20
KeyCodes.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
var KeyCodes = function() {
|
||||
}
|
||||
KeyCodes.normalKey = function(code) {
|
||||
return String.fromCharCode(code);
|
||||
}
|
||||
KeyCodes.isBackspace = function(code) {
|
||||
if (code == 8)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
KeyCodes.isDelete = function(code) {
|
||||
if (code == 46)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
KeyCodes.isEnter = function(code) {
|
||||
if (code == 13)
|
||||
return true;
|
||||
return false;
|
||||
}
|
0
README
Normal file
0
README
Normal file
15
devices.json
Normal file
15
devices.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"harddisks": [
|
||||
{
|
||||
"name": "wish-sys",
|
||||
"manufacturers": "wish-admin",
|
||||
"serialNr": 31415926545,
|
||||
"mbr": "mbr",
|
||||
"partitions": [
|
||||
{
|
||||
"name": "sys-part"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
41
index.html
Normal file
41
index.html
Normal file
|
@ -0,0 +1,41 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
table {
|
||||
border: 1px solid #fff;
|
||||
background-color: #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr {
|
||||
}
|
||||
td {
|
||||
width: 10px;
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
color: #fff;
|
||||
font-family: "Courier New", Courier, Monospace;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#input {
|
||||
z-index: -10;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
}
|
||||
#output {
|
||||
z-index: 1000;
|
||||
}
|
||||
</style>
|
||||
<script src="Emulator.js"></script>
|
||||
<script src="KeyCodes.js"></script>
|
||||
<script src="BIOS.js"></script>
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
<body onload="main()">
|
||||
<div id="output"></div>
|
||||
<input type="button" onclick="powerOn()" value="Power Button" />
|
||||
<input type="button" onclick="window.clearInterval(Emulator.mainTickId)" value="clear system timer" />
|
||||
<form id="form" name="form" onsubmit="return false;">
|
||||
<input type="text" name="input" id="input" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
33
main.js
Normal file
33
main.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
Array.prototype.diff = function(a) {
|
||||
return this.filter(function(i) {return !(a.indexOf(i) > -1);});
|
||||
}
|
||||
|
||||
String.prototype.reverse = function() {
|
||||
return this.split("").reverse().join("");
|
||||
}
|
||||
|
||||
Math.sign = function(x) {
|
||||
return (x > 0) ? 1 : (x < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
function nothing() {
|
||||
|
||||
}
|
||||
|
||||
function ret(v) {
|
||||
return v;
|
||||
}
|
||||
function isNumber(n) {
|
||||
return (parseInt(n) + "" == n);
|
||||
}
|
||||
|
||||
var main = function () {
|
||||
Emulator.init(document.getElementById("output"), document.forms['form'].elements['input'], 80, 24);
|
||||
}
|
||||
|
||||
var powerOn = function() {
|
||||
if (Emulator.running)
|
||||
Emulator.kill();
|
||||
else
|
||||
Emulator.main();
|
||||
}
|
13
wish-sys/mbr/config.json
Normal file
13
wish-sys/mbr/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"sleep": 10,
|
||||
"default": 0,
|
||||
"systems": [
|
||||
{
|
||||
"hdd": 0,
|
||||
"partition": 0,
|
||||
"label": "wish os",
|
||||
"kernel": "kernel0.1.js",
|
||||
"parameters": ""
|
||||
}
|
||||
]
|
||||
}
|
107
wish-sys/mbr/init.js
Normal file
107
wish-sys/mbr/init.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
var MBR = function() {
|
||||
}
|
||||
MBR.main = function(device) {
|
||||
console.log("MBR: main");
|
||||
console.log("MBR: start Boot Loader");
|
||||
Loader.main(device);
|
||||
}
|
||||
|
||||
var Loader = function() {
|
||||
}
|
||||
Loader.logo = "\033[32m" +
|
||||
" .__ .__ \n" +
|
||||
"__ _ _|__| _____| |__ \n" +
|
||||
"\\ \\/ \\/ / |/ ___/ | \\ \n" +
|
||||
" \\ /| |\\___ \\| Y \\\n" +
|
||||
" \\/\\_/ |__/____ >___| /\n" +
|
||||
" \\/ \\/ \033[31mLoader\033[0m\n";
|
||||
Loader.tickid;
|
||||
Loader.state;
|
||||
Loader.device;
|
||||
Loader.config;
|
||||
Loader.main = function(device) {
|
||||
console.log("Loader: main");
|
||||
console.log("Loader: register 100ms-timer");
|
||||
Loader.tickid = Emulator.registerTimer(100, Loader.tick);
|
||||
console.log("Loader: register key interrupt");
|
||||
Emulator.interrupts['key'] = Loader.key;
|
||||
Loader.device = device;
|
||||
var text = "\033[2J\033[0:0H\033[?25l" + Loader.logo + "\033[s";
|
||||
Emulator.output(text);
|
||||
Loader.state = 0;
|
||||
}
|
||||
Loader.key = function(keycode) {
|
||||
if (KeyCodes.isEnter(keycode)) {
|
||||
Loader.boot();
|
||||
return;
|
||||
}
|
||||
var char = KeyCodes.normalKey(keycode);
|
||||
if (char == 'w') Loader.selected--;
|
||||
if (char == 's') Loader.selected++;
|
||||
Loader.selected %= Loader.config.systems.length;
|
||||
if (Loader.selected < 0)
|
||||
Loader.selected += Loader.config.systems.length;
|
||||
Loader.outputSystems();
|
||||
}
|
||||
Loader.tick = function() {
|
||||
switch(Loader.state) {
|
||||
case 0:
|
||||
console.log("Loader: load config");
|
||||
Loader.config = JSON.parse(Emulator.Request.get(Loader.device.name + "/" + Loader.device.mbr + "/config.json", "", false, ret))
|
||||
Loader.selected = Loader.config.default;
|
||||
Loader.state++;
|
||||
break;
|
||||
case 1:
|
||||
Loader.outputSystems();
|
||||
Loader.state++;
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
Emulator.output(".");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loader.outputSystems = function() {
|
||||
console.log("Loader: display menu");
|
||||
var systems = Loader.config.systems;
|
||||
var text = "\033[u\n\n\n\n";
|
||||
for(var i = 0; i < systems.length; i++) {
|
||||
var string = "-> " + systems[i].label + " " + systems[i].kernel;
|
||||
var length = Emulator.Output.xsize - string.length - 10
|
||||
text += "\033[5C\033[46m\033[31m" + ((i == Loader.selected) ? "->" : " ") + " \033[30m" + systems[i].label + " \033[34m" + systems[i].kernel;
|
||||
for (var j = 0; j < length; j++)
|
||||
text += " ";
|
||||
text += "\033[0m\n";
|
||||
}
|
||||
text += "\n\nSelect OS to boot... [w, s]";
|
||||
Emulator.output(text);
|
||||
}
|
||||
Loader.boot = function() {
|
||||
var device = Emulator.Devices.getHarddisks();
|
||||
var system = Loader.config.systems[Loader.selected];
|
||||
device = device[system.hdd];
|
||||
var partition = device.partitions[system.partition];
|
||||
var loadstring = device.name + "/" + partition.name + "/" + system.kernel
|
||||
Emulator.output("\n\nTrying to boot " + loadstring + "..");
|
||||
Loader.state = 3;
|
||||
Emulator.Request.include(loadstring, Loader.finished);
|
||||
}
|
||||
Loader.finished = function() {
|
||||
console.log("Loader: stop BIOS");
|
||||
console.log("loader: remove all event handlers");
|
||||
Emulator.interrupts = new Array();
|
||||
Emulator.unregisterTimer(Loader.tickid);
|
||||
console.log("Loader: start OS");
|
||||
var system = Loader.config.systems[Loader.selected];
|
||||
try {
|
||||
OS.main(system);
|
||||
Emulator.output("\nKernel loaded successfully.");
|
||||
} catch (exception) {
|
||||
console.dir(exception);
|
||||
Emulator.output("\nFailed to load kernel...\n\n");
|
||||
Emulator.output("\033[31msystem halt\033[0m");
|
||||
}
|
||||
}
|
8
wish-sys/sys-part/bin/hallo.js
Normal file
8
wish-sys/sys-part/bin/hallo.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
var HalloClass = function() {
|
||||
}
|
||||
HalloClass.prototype = new Process();
|
||||
HalloClass.prototype.main = function() {
|
||||
var stdout = this.files['stdout'];
|
||||
stdout.write("Hallo Welt\n");
|
||||
this.exit(0);
|
||||
}
|
190
wish-sys/sys-part/bin/wsh.js
Normal file
190
wish-sys/sys-part/bin/wsh.js
Normal file
|
@ -0,0 +1,190 @@
|
|||
WshClass = function() {
|
||||
}
|
||||
WshClass.prototype = new Process();
|
||||
WshClass.prototype.state = 0;
|
||||
WshClass.prototype.Environment = function() {
|
||||
}
|
||||
WshClass.prototype.Environment.array = new Array();
|
||||
WshClass.prototype.input = new Array();
|
||||
WshClass.prototype.lastExitCode = 0;
|
||||
WshClass.prototype.childList = new Array();
|
||||
WshClass.prototype.main = function(args) {
|
||||
console.log("wsh: adding to scheduler job list");
|
||||
Kernel.Scheduler.add(this);
|
||||
this.username = args['1'];
|
||||
this.Environment.array['HOME'] = args[2];
|
||||
this.Environment.array['PWD'] = args[2];
|
||||
|
||||
}
|
||||
WshClass.prototype.tick = function() {
|
||||
var stdout = this.files['stdout'];
|
||||
var stdin = this.files['stdin'];
|
||||
switch(this.state) {
|
||||
case 0:
|
||||
stdout.write("Welcome to WishOS 0.1 (WOSKernel 0.1)\n\n");
|
||||
this.files['profile.d'] = new File("/etc/profile.d/env.json");
|
||||
var array = JSON.parse(this.files['profile.d'].read());
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
while(array[i][1].indexOf("\\033") != -1)
|
||||
array[i][1] = array[i][1].replace("\\033", "\033");
|
||||
this.Environment.array[array[i][0]] = array[i][1];
|
||||
}
|
||||
this.state++;
|
||||
break;
|
||||
case 1:
|
||||
var prompt = this.Environment.array['PS1'];
|
||||
while (prompt.indexOf("\\w") != -1)
|
||||
prompt = prompt.replace("\\w", (this.Environment.array['PWD'] == this.Environment.array['HOME']) ? "~" : this.Environment.array['PWD']);
|
||||
while (prompt.indexOf("\\u") != -1)
|
||||
prompt = prompt.replace("\\u", this.username);
|
||||
while (prompt.indexOf("\\u") != -1)
|
||||
prompt = prompt.replace("\\u", OS.hostname);
|
||||
while (prompt.indexOf("\\$") != -1)
|
||||
prompt = prompt.replace("\\$", (this.username == "root") ? "#" : "$");
|
||||
while (prompt.indexOf("\\#") != -1)
|
||||
prompt = prompt.replace("\\#", (this.lastExitCode == 0) ? "" : this.lastExitCode);
|
||||
stdout.write(prompt);
|
||||
this.state++;
|
||||
break;
|
||||
case 2:
|
||||
var code = stdin.read();
|
||||
if (!code)
|
||||
break;
|
||||
if (KeyCodes.isBackspace(code)) {
|
||||
if (!this.input.length)
|
||||
break;
|
||||
this.input.pop();
|
||||
stdout.write("\033[1D \033[1D");
|
||||
break;
|
||||
}
|
||||
if (KeyCodes.isEnter(code)) {
|
||||
stdout.write("\n");
|
||||
this.parseLine();
|
||||
break;
|
||||
}
|
||||
var char = KeyCodes.normalKey(code);
|
||||
this.input.push(char);
|
||||
stdout.write(char);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
this.state = 1;
|
||||
var params = this.input.join("").split(" ");
|
||||
for (var i = 0; i < params.length; i++)
|
||||
if (params[i].length == 0)
|
||||
params.splice(i, 1);
|
||||
stdout.write("wsh: command not found: " + params[0] + "\n");
|
||||
this.lastExitCode = 127;
|
||||
this.input = new Array();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
WshClass.prototype.parseLine = function() {
|
||||
this.state = 1;
|
||||
var command = this.input.join("");
|
||||
var params = command.split(" ");
|
||||
for(var i = 0; i < params.length; i++)
|
||||
if (params[i].length == 0)
|
||||
params.splice(i, 1);
|
||||
if (params.length == 0) {
|
||||
return;
|
||||
}
|
||||
var ok = false;
|
||||
var name = params[0];
|
||||
var file = "";
|
||||
if (name.substring(0, 1) == "/")
|
||||
file = name + ".js";
|
||||
else if (name.indexOf("/") != -1)
|
||||
file = this.Environment.array['PWD'] + name + ".js";
|
||||
else {
|
||||
var paths = this.Environment.array['PATH'].split(":");
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
file = paths[i] + "/" + name + ".js";
|
||||
console.log("wsh: trying: " + file);
|
||||
if (this.tryFile(file)) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (this.tryFile(file)) {
|
||||
console.log("wsh: files exists... yay....");
|
||||
ok = true;
|
||||
}
|
||||
if (!ok) {
|
||||
this.state = 4;
|
||||
return;
|
||||
}
|
||||
this.input = new Array();
|
||||
|
||||
this.state = 3;
|
||||
var pathArray = new Array();
|
||||
pathArray[0] = ["stdout", this.files['stdout'].path];
|
||||
pathArray[1] = ["stdin", this.files['stdin'].path];
|
||||
var s = "";
|
||||
s += "var func = function () { ";
|
||||
s += " try {";
|
||||
s += " var prog = new " + Kernel.ProcessManager.getClassNameFromFileName(command) + "();";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += " prog.init(" + this.pid + ");";
|
||||
s += " var paths = JSON.parse('" + JSON.stringify(pathArray) + "');";
|
||||
s += " for(var i = 0; i < paths.length; i++) {";
|
||||
s += " prog.files[paths[i][0]] = Kernel.Filesystem.getFile(paths[i][1]);";
|
||||
s += " }";
|
||||
s += " Kernel.ProcessManager.add(prog);";
|
||||
s += " console.log(\"wsh: start command '" + file + "'...\");";
|
||||
s += " try {";
|
||||
s += " prog.main(JSON.parse('" + JSON.stringify(params) + "'));";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += "}";
|
||||
eval(s);
|
||||
Kernel.ProcessManager.load(file, func);
|
||||
}
|
||||
WshClass.prototype.tryFile = function(name) {
|
||||
var file = new File(name);
|
||||
return file.exists();
|
||||
}
|
||||
WshClass.prototype.signalHandler = function(signal) {
|
||||
switch(signal) {
|
||||
case SIGCHLD:
|
||||
var newChildList = Kernel.ProcessManager.getAllChilds(this.pid);
|
||||
var oldChilds = this.childList.diff(newChildList);
|
||||
var newChilds = newChildList.diff(this.childList);
|
||||
if (newChilds.length)
|
||||
console.log("wsh: we got " + newChilds.length + " new kid(s)... : )")
|
||||
if (oldChilds.length) {
|
||||
console.log("wsh: we lost " + oldChilds.length + " kid(s)");
|
||||
this.state = 1;
|
||||
}
|
||||
for (var i = 0; i < oldChilds.length; i++) {
|
||||
this.lastExitCode = oldChilds[i].exitCode;
|
||||
Kernel.ProcessManager.remove(oldChilds[i]);
|
||||
}
|
||||
this.childList = newChildList;
|
||||
break;
|
||||
case SIGHUP:
|
||||
//break;
|
||||
case SIGALRM:
|
||||
//break;
|
||||
case SIGTERM:
|
||||
//break;
|
||||
case SIGXCPU:
|
||||
//break;
|
||||
case SIGUSR1:
|
||||
//break;
|
||||
case SIGUSR2:
|
||||
//break;
|
||||
default: //SIGKILL
|
||||
console.log("PID " + this.pid + " got Signal " + signal);
|
||||
this.exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
14
wish-sys/sys-part/etc/inittab.json
Normal file
14
wish-sys/sys-part/etc/inittab.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"initdefault": 3,
|
||||
"sysinit": [
|
||||
],
|
||||
"l3": [
|
||||
{
|
||||
"command": "/sbin/login.js",
|
||||
"files": [
|
||||
"stdout",
|
||||
"stdin"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
9
wish-sys/sys-part/etc/passwd.json
Normal file
9
wish-sys/sys-part/etc/passwd.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
[
|
||||
{
|
||||
"id": 0,
|
||||
"username": "root",
|
||||
"password": "ce5ca673d13b36118d54a7cf13aeb0ca012383bf771e713421b4d1fd841f539a",
|
||||
"home": "/root/",
|
||||
"shell": "/bin/wsh.js"
|
||||
}
|
||||
]
|
4
wish-sys/sys-part/etc/profile.d/env.json
Normal file
4
wish-sys/sys-part/etc/profile.d/env.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
["PATH", "/bin:/sbin:/usr/bin:/usr/sbin"],
|
||||
["PS1", "\\033[31m\\#\\033[36m\\w \\$\\033[0m "]
|
||||
]
|
414
wish-sys/sys-part/kernel0.1.js
Normal file
414
wish-sys/sys-part/kernel0.1.js
Normal file
|
@ -0,0 +1,414 @@
|
|||
const SIGHUP = 1;
|
||||
const SIGKILL = 9;
|
||||
const SIGALRM = 14;
|
||||
const SIGTERM = 15;
|
||||
const SIGCHLD = 20;
|
||||
const SIGXCPU = 24;
|
||||
const SIGUSR1 = 30;
|
||||
const SIGUSR2 = 31;
|
||||
|
||||
const APPND = 1;
|
||||
const OVWRT = 2;
|
||||
|
||||
const SYSHALT = 31415926
|
||||
|
||||
var OS = function() {
|
||||
}
|
||||
OS.system;
|
||||
OS.runlevel;
|
||||
OS.staticShift = 7;
|
||||
OS.hostname = "wish";
|
||||
OS.logo = "\033[32m" +
|
||||
" .__ .__ \n" +
|
||||
"__ _ _|__| _____| |__ \n" +
|
||||
"\\ \\/ \\/ / |/ ___/ | \\ \n" +
|
||||
" \\ /| |\\___ \\| Y \\\n" +
|
||||
" \\/\\_/ |__/____ >___| /\n" +
|
||||
" \\/ \\/ \033[31mOS\033[0m\n";
|
||||
OS.main = function(system) {
|
||||
console.log("OS: main");
|
||||
OS.system = system;
|
||||
console.log("OS: init Kernel");
|
||||
Kernel.init();
|
||||
}
|
||||
|
||||
var Kernel = function() {
|
||||
}
|
||||
Kernel.time;
|
||||
Kernel.state;
|
||||
Kernel.machineTimerId;
|
||||
Kernel.globalLog;
|
||||
Kernel.init = function() {
|
||||
console.log("Kernel: init");
|
||||
Kernel.state = 0;
|
||||
console.log("Kernel: main timer (100ms)");
|
||||
Kernel.machineTimerId = Emulator.registerTimer(100, Kernel.machine);
|
||||
Kernel.globalLog = "";
|
||||
}
|
||||
Kernel.machine = function() {
|
||||
switch(Kernel.state) {
|
||||
case 0:
|
||||
Emulator.Output.shiftKey = OS.staticShift;
|
||||
Emulator.output("\033[2J\033[0:0H" + OS.logo);
|
||||
Kernel.msgOut("reseting kernel timer", true);
|
||||
Kernel.time = 0;
|
||||
Kernel.msgOut("register main timer (100ms)", true); // pre
|
||||
Kernel.msgOut("init filesystem", true);
|
||||
Kernel.Filesystem.init();
|
||||
Kernel.msgOut("init process manager", true);
|
||||
Kernel.ProcessManager.init();
|
||||
Kernel.msgOut("init scheduler", true);
|
||||
Kernel.Scheduler.init();
|
||||
Kernel.msgOut("init kernel io", true);
|
||||
Kernel.IO.init();
|
||||
Kernel.msgOut(" register keyboard interrupt", true);
|
||||
Emulator.interrupts['key'] = Kernel.IO.key;
|
||||
Kernel.msgOut(" register power switch interrupt", true);
|
||||
Emulator.interrupts['powersw'] = Kernel.IO.powersw;
|
||||
Kernel.msgOut("loading /sbin/init.js");
|
||||
Kernel.ProcessManager.load("/sbin/init.js", Kernel.next);
|
||||
Kernel.state++;
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
Kernel.msgSuccess(true);
|
||||
Kernel.msgOut(" creating class instance", true);
|
||||
var init = new InitClass();
|
||||
init.init(1);
|
||||
Kernel.msgOut(" adding handler for stdio on /dev/tty1", true);
|
||||
init.files['stdin'] = Kernel.Filesystem.getFile("/dev/tty1/i");
|
||||
init.files['stdout'] = Kernel.Filesystem.getFile("/dev/tty1/o");
|
||||
Kernel.msgOut(" adding to process list", true);
|
||||
Kernel.ProcessManager.add(init);
|
||||
Kernel.msgOut(" starting init", true);
|
||||
init.main();
|
||||
Kernel.msgOut("register scheduler timer (1ms)", true);
|
||||
Kernel.msgOut("starting scheduler", true);
|
||||
Emulator.interrupts[0] = Kernel.Scheduler.tick;
|
||||
Kernel.state++;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Kernel.next = function() {
|
||||
Kernel.state++;
|
||||
}
|
||||
Kernel.msgOut = function(text, success, color) {
|
||||
while (text.length < Emulator.Output.xsize - 12)
|
||||
text += " ";
|
||||
text = "\n" + text;
|
||||
if (color) {
|
||||
text = color + text;
|
||||
text += "\033[0m"
|
||||
}
|
||||
Kernel.globalLog += text;
|
||||
Emulator.output(text);
|
||||
Kernel.msgSuccess(success);
|
||||
}
|
||||
Kernel.msgSuccess = function(success) {
|
||||
var text = "";
|
||||
if (success == true)
|
||||
text = "[ \033[32msuccess\033[0m ]";
|
||||
else if (success == false)
|
||||
text = "[ \033[31mfailed\033[0m ]";
|
||||
else
|
||||
text = "";
|
||||
Kernel.globalLog += text;
|
||||
Emulator.output(text);
|
||||
}
|
||||
|
||||
Kernel.Scheduler = function() {
|
||||
}
|
||||
Kernel.Scheduler.jobs;
|
||||
Kernel.Scheduler.activ;
|
||||
Kernel.Scheduler.working;
|
||||
Kernel.Scheduler.init = function() {
|
||||
Kernel.msgOut(" init job list", true);
|
||||
Kernel.Scheduler.jobs = new Array();
|
||||
Kernel.Scheduler.activ = 0;
|
||||
Kernel.Scheduler.working = false;
|
||||
}
|
||||
Kernel.Scheduler.tick = function() {
|
||||
if (Kernel.Scheduler.working) {
|
||||
Kernel.Scheduler.jobs[Kernel.Scheduler.activ].signalHandler(SIGXCPU);
|
||||
Kernel.Scheduler.activ %= Kernel.Scheduler.jobs.length;
|
||||
return;
|
||||
}
|
||||
Kernel.Scheduler.working = true;
|
||||
Kernel.Scheduler.activ++;
|
||||
Kernel.Scheduler.activ %= Kernel.Scheduler.jobs.length;
|
||||
Kernel.Scheduler.jobs[Kernel.Scheduler.activ].tick();
|
||||
Kernel.time++;
|
||||
Kernel.Scheduler.working = false;
|
||||
}
|
||||
Kernel.Scheduler.add = function(process) {
|
||||
if (!process.tick)
|
||||
return 2; // no tick method
|
||||
for (var i = 0; i < this.jobs.length; i++) {
|
||||
if (this.jobs[i].pid == process.pid)
|
||||
return 3; // no double processes
|
||||
}
|
||||
this.jobs.push(process);
|
||||
return 0;
|
||||
}
|
||||
Kernel.Scheduler.remove = function(process) {
|
||||
for (var i = 0; i < this.jobs.length; i++) {
|
||||
if (this.jobs[i].pid == process.pid) {
|
||||
if (this.activ == i)
|
||||
this.working = false;
|
||||
this.jobs.splice(i, i);
|
||||
return 0; // success
|
||||
}
|
||||
}
|
||||
return 1; // not in list
|
||||
}
|
||||
|
||||
Kernel.ProcessManager = function() {
|
||||
}
|
||||
Kernel.ProcessManager.nextPid;
|
||||
Kernel.ProcessManager.processList;
|
||||
Kernel.ProcessManager.loadedList;
|
||||
Kernel.ProcessManager.init = function() {
|
||||
Kernel.msgOut(" init process list", true);
|
||||
Kernel.ProcessManager.processList = new Array();
|
||||
Kernel.ProcessManager.loadedList = new Array();
|
||||
Kernel.ProcessManager.nextPid = 1;
|
||||
}
|
||||
Kernel.ProcessManager.add = function(process) {
|
||||
this.processList[process.pid] = process;
|
||||
if (process.pid != process.parentId)
|
||||
this.processList[process.parentId].signalHandler(SIGCHLD);
|
||||
}
|
||||
Kernel.ProcessManager.quit = function(process) {
|
||||
var parentId = process.parentId;
|
||||
var pid = process.pid;
|
||||
console.log("Kernel: quiting pid: " + pid);
|
||||
Kernel.Scheduler.remove(process);
|
||||
if (pid != parentId)
|
||||
this.processList[parentId].signalHandler(SIGCHLD);
|
||||
}
|
||||
Kernel.ProcessManager.remove = function(process) {
|
||||
this.processList.splice(process.pid, 1);
|
||||
var childs = this.getAllChilds(process.pid);
|
||||
for (var i = 0; i < childs.length; i++)
|
||||
childs[i].parentId = 1;
|
||||
if (childs.length > 0)
|
||||
this.processList[1].signalHandler(SIGCHLD);
|
||||
}
|
||||
Kernel.ProcessManager.load = function(path, loaded) {
|
||||
if (Kernel.ProcessManager.loadedList[path]) {
|
||||
loaded();
|
||||
return;
|
||||
}
|
||||
Kernel.ProcessManager.loadedList[path] = true;
|
||||
Emulator.Request.include(Kernel.Filesystem.getRealPath(path), loaded);
|
||||
}
|
||||
Kernel.ProcessManager.getAllChilds = function(pid) {
|
||||
var kids = new Array();
|
||||
for(var index in Kernel.ProcessManager.processList) {
|
||||
var proc = Kernel.ProcessManager.processList[index];
|
||||
if (proc.parentId == pid) {
|
||||
if (proc.exitCode === undefined)
|
||||
kids.push(proc);
|
||||
}
|
||||
}
|
||||
return kids;
|
||||
}
|
||||
Kernel.ProcessManager.getPid = function() {
|
||||
return Kernel.ProcessManager.nextPid++;
|
||||
}
|
||||
Kernel.ProcessManager.getClassNameFromFileName = function(name) {
|
||||
name = name.split("/");
|
||||
name = name[name.length - 1];
|
||||
name = name[0].toUpperCase() + name.substring(1);
|
||||
name = name.split(".")[0];
|
||||
name += "Class";
|
||||
return name;
|
||||
}
|
||||
|
||||
var Process = function(parentId) {
|
||||
}
|
||||
Process.prototype.pid;
|
||||
Process.prototype.userId;
|
||||
Process.prototype.parentId;
|
||||
Process.prototype.files;
|
||||
Process.prototype.exitCode;
|
||||
Process.prototype.init = function(parentId) {
|
||||
// DO NOT OVERWRITE
|
||||
this.pid = Kernel.ProcessManager.getPid();
|
||||
this.parentId = parentId;
|
||||
this.files = new Array();
|
||||
}
|
||||
Process.prototype.main = function(args) {
|
||||
|
||||
}
|
||||
Process.prototype.tick = function() {
|
||||
}
|
||||
Process.prototype.exit = function(code) {
|
||||
this.exitCode = code;
|
||||
Kernel.ProcessManager.quit(this);
|
||||
}
|
||||
Process.prototype.signalHandler = function(signal) {
|
||||
switch(signal) {
|
||||
case SIGCHLD:
|
||||
break;
|
||||
case SIGHUP:
|
||||
//break;
|
||||
case SIGALRM:
|
||||
//break;
|
||||
case SIGTERM:
|
||||
//break;
|
||||
case SIGXCPU:
|
||||
//break;
|
||||
case SIGUSR1:
|
||||
//break;
|
||||
case SIGUSR2:
|
||||
//break;
|
||||
default: //SIGKILL
|
||||
console.log("PID " + this.pid + " got Signal " + signal);
|
||||
this.exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var File = function(path) {
|
||||
this.path = path;
|
||||
}
|
||||
File.prototype.path;
|
||||
File.prototype.position = 0;
|
||||
File.prototype.writeMode = APPND;
|
||||
File.prototype.forceUpdate = function() {
|
||||
Kernel.Filesystem.update(this.path);
|
||||
}
|
||||
File.prototype.exists = function() {
|
||||
return Kernel.Filesystem.getFile(this.path).exists()
|
||||
}
|
||||
File.prototype.read = function(length) {
|
||||
var val = Kernel.Filesystem.getFile(this.path).read(this.position, length);
|
||||
if (length)
|
||||
this.position += length;
|
||||
return val;
|
||||
}
|
||||
File.prototype.write = function(string) {
|
||||
this.writeFIFO(string);
|
||||
}
|
||||
File.prototype.writeFIFO = function(string) {
|
||||
Kernel.Filesystem.getFile(this.path).writeFIFO(string, writeMode);
|
||||
}
|
||||
File.prototype.writeLIFO = function(string) {
|
||||
Kernel.Filesystem.getFile(this.path).writeLIFO(string, writeMode);
|
||||
}
|
||||
|
||||
var InnerFile = function(path) {
|
||||
this.path = path;
|
||||
}
|
||||
InnerFile.prototype = new File;
|
||||
InnerFile.prototype.content;
|
||||
InnerFile.prototype.exists = function() {
|
||||
return ((typeof this.content) != "number");
|
||||
}
|
||||
InnerFile.prototype.read = function(position, length) {
|
||||
if (!length)
|
||||
return this.content;
|
||||
return this.content.substring(position, position + length)
|
||||
}
|
||||
InnerFile.prototype.writeFIFO = function(string, mode) {
|
||||
if (mode == APPND)
|
||||
this.content += string;
|
||||
if (mode == OVWRT)
|
||||
this.content = string;
|
||||
}
|
||||
InnerFile.prototype.writeLIFO = function(string, mode) {
|
||||
if (mode == APPND)
|
||||
this.content = text + this.content;
|
||||
if (mode == OVWRT)
|
||||
this.content = string;
|
||||
}
|
||||
|
||||
Kernel.Filesystem = function() {
|
||||
}
|
||||
Kernel.Filesystem.devices;
|
||||
Kernel.Filesystem.root;
|
||||
Kernel.Filesystem.files;
|
||||
Kernel.Filesystem.init = function() {
|
||||
Kernel.msgOut(" geting device list", true);
|
||||
Kernel.Filesystem.devices = Emulator.Devices.getAll();
|
||||
var hdd = Kernel.Filesystem.devices.harddisks[OS.system.hdd];
|
||||
var partition = hdd.partitions[OS.system.partition];
|
||||
Kernel.msgOut(" generating root path", true);
|
||||
Kernel.Filesystem.root = hdd.name + "/" + partition.name;
|
||||
Kernel.Filesystem.files = new Array();
|
||||
|
||||
}
|
||||
Kernel.Filesystem.getFile = function(path) {
|
||||
if (Kernel.Filesystem.files[path])
|
||||
return Kernel.Filesystem.files[path];
|
||||
return Kernel.Filesystem.update(path);
|
||||
console.log("Kernel: get file " + path);
|
||||
}
|
||||
Kernel.Filesystem.update = function(path) {
|
||||
var file = new InnerFile(path);
|
||||
file.content = Emulator.Request.get(Kernel.Filesystem.getRealPath(path), "", false, ret);
|
||||
Kernel.Filesystem.files[path] = file;
|
||||
return file;
|
||||
}
|
||||
Kernel.Filesystem.getRealPath = function(name) {
|
||||
return Kernel.Filesystem.root + name;
|
||||
}
|
||||
Kernel.Filesystem.addTTY = function(path, output, input) {
|
||||
var out = new InnerFile(path + "/o");
|
||||
out.output = output;
|
||||
out.writeFIFO = function(string) {
|
||||
this.output(string);
|
||||
}
|
||||
out.writeLIFI = function(string) {
|
||||
this.output(string.reverse());
|
||||
}
|
||||
out.read = function() {
|
||||
return "";
|
||||
}
|
||||
var inp = new InnerFile(path + "/i");
|
||||
inp.input = input;
|
||||
inp.writeFIFO = function(string) {
|
||||
var input = this.input();
|
||||
input.reverse();
|
||||
for (var i = 0; i < string.length; i++)
|
||||
input.push(char);
|
||||
input.reverse();
|
||||
}
|
||||
inp.writeLIFI = function(string) {
|
||||
for(var i = 0; i < string.length; i++)
|
||||
this.input().push(string[i]);
|
||||
}
|
||||
inp.read = function() {
|
||||
return this.input().pop();
|
||||
}
|
||||
Kernel.Filesystem.files[path + "/o"] = out;
|
||||
Kernel.Filesystem.files[path + "/i"] = inp
|
||||
}
|
||||
|
||||
|
||||
Kernel.IO = function() {
|
||||
}
|
||||
Kernel.IO.inputBuffer;
|
||||
Kernel.IO.init = function() {
|
||||
Kernel.msgOut(" generating /dev/tty1", true);
|
||||
Kernel.Filesystem.addTTY("/dev/tty1", Kernel.IO.output, Kernel.IO.input);
|
||||
Kernel.IO.inputBuffer = new Array();
|
||||
}
|
||||
Kernel.IO.key = function(code) {
|
||||
Kernel.IO.inputBuffer.push(code);
|
||||
}
|
||||
Kernel.IO.powersw = function() {
|
||||
console.log("Kernel: power switch pressed, but no action defined");
|
||||
}
|
||||
Kernel.IO.input = function() {
|
||||
return Kernel.IO.inputBuffer;
|
||||
}
|
||||
Kernel.IO.output = function(string) {
|
||||
Emulator.output(string);
|
||||
}
|
116
wish-sys/sys-part/lib/sha256.js
Normal file
116
wish-sys/sys-part/lib/sha256.js
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* SHA-256 implementation in JavaScript | (c) Chris Veness 2002-2010 | www.movable-type.co.uk */
|
||||
/* - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html */
|
||||
/* http://csrc.nist.gov/groups/ST/toolkit/examples.html */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
var Sha256 = {}; // Sha256 namespace
|
||||
|
||||
/**
|
||||
* Generates SHA-256 hash of string
|
||||
*
|
||||
* @param {String} msg String to be hashed
|
||||
* @param {Boolean} [utf8encode=true] Encode msg as UTF-8 before generating hash
|
||||
* @returns {String} Hash of msg as hex character string
|
||||
*/
|
||||
Sha256.hash = function(msg, utf8encode) {
|
||||
utf8encode = (typeof utf8encode == 'undefined') ? true : utf8encode;
|
||||
|
||||
// convert string to UTF-8, as SHA only deals with byte-streams
|
||||
if (utf8encode) msg = Utf8.encode(msg);
|
||||
|
||||
// constants [§4.2.2]
|
||||
var K = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
|
||||
// initial hash value [§5.3.1]
|
||||
var H = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
|
||||
|
||||
// PREPROCESSING
|
||||
|
||||
msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1]
|
||||
|
||||
// convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1]
|
||||
var l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length
|
||||
var N = Math.ceil(l/16); // number of 16-integer-blocks required to hold 'l' ints
|
||||
var M = new Array(N);
|
||||
|
||||
for (var i=0; i<N; i++) {
|
||||
M[i] = new Array(16);
|
||||
for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding
|
||||
M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
|
||||
(msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
|
||||
} // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
|
||||
}
|
||||
// add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
|
||||
// note: most significant word would be (len-1)*8 >>> 32, but since JS converts
|
||||
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
|
||||
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
|
||||
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
|
||||
|
||||
|
||||
// HASH COMPUTATION [§6.1.2]
|
||||
|
||||
var W = new Array(64); var a, b, c, d, e, f, g, h;
|
||||
for (var i=0; i<N; i++) {
|
||||
|
||||
// 1 - prepare message schedule 'W'
|
||||
for (var t=0; t<16; t++) W[t] = M[i][t];
|
||||
for (var t=16; t<64; t++) W[t] = (Sha256.sigma1(W[t-2]) + W[t-7] + Sha256.sigma0(W[t-15]) + W[t-16]) & 0xffffffff;
|
||||
|
||||
// 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value
|
||||
a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7];
|
||||
|
||||
// 3 - main loop (note 'addition modulo 2^32')
|
||||
for (var t=0; t<64; t++) {
|
||||
var T1 = h + Sha256.Sigma1(e) + Sha256.Ch(e, f, g) + K[t] + W[t];
|
||||
var T2 = Sha256.Sigma0(a) + Sha256.Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + T1) & 0xffffffff;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (T1 + T2) & 0xffffffff;
|
||||
}
|
||||
// 4 - compute the new intermediate hash value (note 'addition modulo 2^32')
|
||||
H[0] = (H[0]+a) & 0xffffffff;
|
||||
H[1] = (H[1]+b) & 0xffffffff;
|
||||
H[2] = (H[2]+c) & 0xffffffff;
|
||||
H[3] = (H[3]+d) & 0xffffffff;
|
||||
H[4] = (H[4]+e) & 0xffffffff;
|
||||
H[5] = (H[5]+f) & 0xffffffff;
|
||||
H[6] = (H[6]+g) & 0xffffffff;
|
||||
H[7] = (H[7]+h) & 0xffffffff;
|
||||
}
|
||||
|
||||
return Sha256.toHexStr(H[0]) + Sha256.toHexStr(H[1]) + Sha256.toHexStr(H[2]) + Sha256.toHexStr(H[3]) +
|
||||
Sha256.toHexStr(H[4]) + Sha256.toHexStr(H[5]) + Sha256.toHexStr(H[6]) + Sha256.toHexStr(H[7]);
|
||||
}
|
||||
|
||||
Sha256.ROTR = function(n, x) { return (x >>> n) | (x << (32-n)); }
|
||||
Sha256.Sigma0 = function(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); }
|
||||
Sha256.Sigma1 = function(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); }
|
||||
Sha256.sigma0 = function(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x>>>3); }
|
||||
Sha256.sigma1 = function(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); }
|
||||
Sha256.Ch = function(x, y, z) { return (x & y) ^ (~x & z); }
|
||||
Sha256.Maj = function(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); }
|
||||
|
||||
//
|
||||
// hexadecimal representation of a number
|
||||
// (note toString(16) is implementation-dependant, and
|
||||
// in IE returns signed numbers when used on full words)
|
||||
//
|
||||
Sha256.toHexStr = function(n) {
|
||||
var s="", v;
|
||||
for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); }
|
||||
return s;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
63
wish-sys/sys-part/lib/utf8.js
Normal file
63
wish-sys/sys-part/lib/utf8.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */
|
||||
/* single-byte character encoding (c) Chris Veness 2002-2011 */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/* changelog
|
||||
* 2010-09-29: fixed decode order of operation to avoid falsely recognising decoded string as 3-byte
|
||||
* utf-8 charaacter
|
||||
*/
|
||||
|
||||
var Utf8 = {}; // Utf8 namespace
|
||||
|
||||
/**
|
||||
* Encode multi-byte Unicode string into utf-8 multiple single-byte characters
|
||||
* (BMP / basic multilingual plane only)
|
||||
*
|
||||
* Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
|
||||
*
|
||||
* @param {String} strUni Unicode string to be encoded as UTF-8
|
||||
* @returns {String} encoded string
|
||||
*/
|
||||
Utf8.encode = function(strUni) {
|
||||
// use regular expressions & String.replace callback function for better efficiency
|
||||
// than procedural approaches
|
||||
var strUtf = strUni.replace(
|
||||
/[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
|
||||
function(c) {
|
||||
var cc = c.charCodeAt(0);
|
||||
return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
|
||||
);
|
||||
strUtf = strUtf.replace(
|
||||
/[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
|
||||
function(c) {
|
||||
var cc = c.charCodeAt(0);
|
||||
return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
|
||||
);
|
||||
return strUtf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode utf-8 encoded string back into multi-byte Unicode characters
|
||||
*
|
||||
* @param {String} strUtf UTF-8 string to be decoded back to Unicode
|
||||
* @returns {String} decoded string
|
||||
*/
|
||||
Utf8.decode = function(strUtf) {
|
||||
// note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
|
||||
var strUni = strUtf.replace(
|
||||
/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars
|
||||
function(c) { // (note parentheses for precence)
|
||||
var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f);
|
||||
return String.fromCharCode(cc); }
|
||||
);
|
||||
strUni = strUni.replace(
|
||||
/[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars
|
||||
function(c) { // (note parentheses for precence)
|
||||
var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
|
||||
return String.fromCharCode(cc); }
|
||||
);
|
||||
return strUni;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
189
wish-sys/sys-part/sbin/init.js
Normal file
189
wish-sys/sys-part/sbin/init.js
Normal file
|
@ -0,0 +1,189 @@
|
|||
var InitClass = function() {
|
||||
}
|
||||
InitClass.prototype = new Process();
|
||||
InitClass.prototype.childList;
|
||||
InitClass.prototype.state = 0;
|
||||
InitClass.prototype.inittab;
|
||||
InitClass.prototype.destLevel;
|
||||
InitClass.prototype.Start = function() {
|
||||
}
|
||||
InitClass.prototype.Start.array;
|
||||
InitClass.prototype.Start.index;
|
||||
InitClass.prototype.modifyLevel = false;
|
||||
InitClass.prototype.main = function(args) {
|
||||
this.childList = new Array();
|
||||
var stdout = this.files['stdout'];
|
||||
if (this.pid == 1) {
|
||||
stdout.write("\ninit: we are pid 1");
|
||||
stdout.write("\n trying to daemonize");
|
||||
stdout.write("\n adding to scheduler job list");
|
||||
Kernel.Scheduler.add(this);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
InitClass.prototype.tick = function() {
|
||||
var stdout = this.files['stdout'];
|
||||
var stdin = this.files['stdin'];
|
||||
switch(this.state) {
|
||||
case 0:
|
||||
this.state++;
|
||||
stdout.write("\ninit: we are a daemon now ... yay ...");
|
||||
stdout.write("\nreseting system runlevel");
|
||||
OS.runlevel = 0;
|
||||
stdout.write("\nloading /etc/inittab.json ...");
|
||||
var file = Kernel.Filesystem.getFile("/etc/inittab.json");
|
||||
this.files[file.path] = file;
|
||||
this.inittab = JSON.parse(file.read());
|
||||
break;
|
||||
case 1:
|
||||
this.state++;
|
||||
if (this.destLevel = this.inittab.initdefault)
|
||||
break;
|
||||
this.state = 100;
|
||||
break;
|
||||
case 2:
|
||||
this.state++;
|
||||
stdout.write("\033[?25l\n");
|
||||
stdout.write("destination runlevel=" + this.destLevel);
|
||||
break;
|
||||
case 3:
|
||||
this.Start.array = this.inittab.sysinit;
|
||||
this.Start.index = 0;
|
||||
this.state++;
|
||||
break;
|
||||
case 4:
|
||||
if (this.Start.index >= this.Start.array.length) {
|
||||
this.state = 5;
|
||||
} else {
|
||||
this.execProgram();
|
||||
this.Start.index++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (OS.runlevel == this.destLevel) {
|
||||
this.state = 30;
|
||||
break;
|
||||
} else
|
||||
this.state = 6;
|
||||
OS.runlevel += Math.sign(this.destLevel - OS.runlevel);
|
||||
console.log("init: entering runlevel " + OS.runlevel);
|
||||
break;
|
||||
case 6:
|
||||
this.Start.array = this.getProgramsForRunlevel(OS.runlevel);
|
||||
this.Start.index = 0;
|
||||
this.state = 4;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
console.log("init: we are finished");
|
||||
this.state = 31;
|
||||
break;
|
||||
case 31:
|
||||
break;
|
||||
case 100: // input runlevel
|
||||
this.state++;
|
||||
stdout.write("\nno default runlevel defined");
|
||||
stdout.write("\ntype in destination level: \033[?25h");
|
||||
case 101:
|
||||
var keycode = stdin.read();
|
||||
var char = KeyCodes.normalKey(keycode);
|
||||
if (isNumber(char)) {
|
||||
this.destLevel = parseInt(char);
|
||||
this.state = 2;
|
||||
}
|
||||
break;
|
||||
case SYSHALT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
InitClass.prototype.changeRunlevel = function() {
|
||||
Kernel.Filesystem.update("/tmp/destLevel.1");
|
||||
var runlevel = Kernel.Filesystem.getFile("/tmp/destLevel.1").read();
|
||||
this.destLevel = parseInt(runlevel);
|
||||
this.state = 5;
|
||||
}
|
||||
InitClass.prototype.getProgramsForRunlevel = function(level) {
|
||||
var array = eval("this.inittab.l" + level);
|
||||
if (array)
|
||||
return array;
|
||||
return new Array();
|
||||
}
|
||||
InitClass.prototype.execProgram = function() {
|
||||
var command = this.Start.array[this.Start.index].command;
|
||||
var params = command.split(" ");
|
||||
var name = params[0];
|
||||
var files = this.Start.array[this.Start.index].files;
|
||||
var pathArray = new Array();
|
||||
if (files)
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
pathArray.push([files[i], this.files[files[i]].path]);
|
||||
}
|
||||
var s = "";
|
||||
s += "var func = function () { ";
|
||||
s += " try {";
|
||||
s += " var prog = new " + Kernel.ProcessManager.getClassNameFromFileName(name) + "();";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += " prog.init(1);";
|
||||
s += " var paths = JSON.parse('" + JSON.stringify(pathArray) + "');";
|
||||
s += " for(var i = 0; i < paths.length; i++) {";
|
||||
s += " prog.files[paths[i][0]] = Kernel.Filesystem.getFile(paths[i][1]);";
|
||||
s += " }";
|
||||
s += " Kernel.ProcessManager.add(prog);";
|
||||
s += " console.log(\"init: start command '" + command + "'...\");";
|
||||
s += " try {";
|
||||
s += " prog.main(JSON.parse('" + JSON.stringify(params) + "'));";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += "}";
|
||||
eval(s);
|
||||
Kernel.ProcessManager.load(name, func);
|
||||
}
|
||||
InitClass.prototype.signalHandler = function(signal) {
|
||||
switch(signal) {
|
||||
case SIGCHLD:
|
||||
var newChildList = Kernel.ProcessManager.getAllChilds(this.pid);
|
||||
var oldChilds = this.childList.diff(newChildList);
|
||||
var newChilds = newChildList.diff(this.childList);
|
||||
var logText = "init: We lost " + oldChilds.length + " kids and got " + newChilds.length + " new orphans (or selfmade kids)... : (";
|
||||
console.log(logText);
|
||||
for (var i = 0; i < oldChilds; i++)
|
||||
Kernel.ProcessManager.remove(oldChilds[i]);
|
||||
this.childList = newChildList;
|
||||
break;
|
||||
case SIGHUP:
|
||||
console.log("init: we lost File for stdout or stdin");
|
||||
break;
|
||||
case SIGALRM:
|
||||
console.log("init: we got alert signal, but we haven't set it")
|
||||
break;
|
||||
case SIGXCPU:
|
||||
console.log("init: we need too much time");
|
||||
break;
|
||||
case SIGUSR1:
|
||||
console.log("init: Got usr1 signal. Looking up new runlevel from env");
|
||||
this.changeRunlevel();
|
||||
break;
|
||||
case SIGUSR2:
|
||||
console.log("init: Got usr2 signal. why??");
|
||||
break;
|
||||
case SIGTERM:
|
||||
console.log("init: They want us to terminale! D:");
|
||||
console.log("init: Let's kill the kernel... Muahahahaha...");
|
||||
Kernel.shutdown();
|
||||
break;
|
||||
case SIGKILL:
|
||||
console.log("init: Got kill signal, shuting down.");
|
||||
Kernel.shutdown();
|
||||
break;
|
||||
default:
|
||||
console.log("PID " + this.pid + " got Signal " + signal);
|
||||
// Kernel.ProcessManager.remove(this);
|
||||
break;
|
||||
}
|
||||
}
|
213
wish-sys/sys-part/sbin/init.old
Normal file
213
wish-sys/sys-part/sbin/init.old
Normal file
|
@ -0,0 +1,213 @@
|
|||
var InitClass = function() {
|
||||
}
|
||||
InitClass.prototype = new Process();
|
||||
InitClass.prototype.childList;
|
||||
InitClass.prototype.state = 0;
|
||||
InitClass.prototype.inittab;
|
||||
InitClass.prototype.destLevel;
|
||||
InitClass.prototype.Wait = function() {
|
||||
}
|
||||
InitClass.prototype.Wait.state = -1;
|
||||
InitClass.prototype.Wait.array;
|
||||
|
||||
InitClass.prototype.main = function(args) {
|
||||
var stdout = this.files['stdout'];
|
||||
if (this.pid == 1) {
|
||||
stdout.write("\ninit: we are pid 1");
|
||||
stdout.write("\n setting runlvel 0 (we are not running yet)");
|
||||
OS.runlevel = 0;
|
||||
stdout.write("\n trying to daemonize");
|
||||
stdout.write("\n adding to scheduler job list");
|
||||
Kernel.Scheduler.add(this);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
InitClass.prototype.tick = function() {
|
||||
var stdout = this.files['stdout'];
|
||||
var stdin = this.files['stdin'];
|
||||
switch(this.state) {
|
||||
case 0:
|
||||
this.state++;
|
||||
stdout.write("\ninit: we are a daemon now ... yay ...");
|
||||
stdout.write("\nloading /etc/inittab.json ...");
|
||||
var file = Kernel.Filesystem.getFile("/etc/inittab.json");
|
||||
this.files[file.path] = file;
|
||||
this.inittab = JSON.parse(file.read());
|
||||
break;
|
||||
case 1:
|
||||
this.state++;
|
||||
for (var i = 0; i < this.inittab.length; i++) {
|
||||
if (this.inittab[i].action == "initdefault") {
|
||||
this.destLevel = this.inittab[i].runlevels;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.destLevel) {
|
||||
this.destLevel = parseInt(this.destLevel);
|
||||
stdout.write("\nfound initdefault");
|
||||
stdout.write("\ndestination runlevel: " + this.destLevel + "\n");
|
||||
} else {
|
||||
stdout.write("\nno initdefault");
|
||||
stdout.write("\nType in destination runlevel:\033[?25h ");
|
||||
this.state = 25;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
this.state++;
|
||||
var array = new Array();
|
||||
stdout.write("looking for sysinit entrys...\n");
|
||||
for (var i = 0; i < this.inittab.length; i++) {
|
||||
if (this.inittab[i].action == "sysinit") {
|
||||
array.push(this.inittab[i].process);
|
||||
}
|
||||
}
|
||||
if (array.length > 0)
|
||||
stdout.write(" found: \n");
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
stdout.write(" " + array[i] + "\n");
|
||||
}
|
||||
InitClass.execAll(array);
|
||||
break;
|
||||
case 3:
|
||||
this.state++;
|
||||
var array = new Array();
|
||||
stdout.write("looking for boot entrys...\n");
|
||||
for (var i = 0; i < this.inittab.length; i++) {
|
||||
if (this.inittab[i].action == "boot") {
|
||||
array.push(this.inittab[i].process);
|
||||
}
|
||||
}
|
||||
if (array.length > 0)
|
||||
stdout.write(" found: \n");
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
stdout.write(" " + array[i] + "\n");
|
||||
}
|
||||
InitClass.execAll(array);
|
||||
break;
|
||||
case 4:
|
||||
switch(this.Wait.state) {
|
||||
case -1:
|
||||
this.Wait.state = 0;
|
||||
this.Wait.array = new Array();
|
||||
stdout.write("looking for bootwait entrys...\n");
|
||||
for (var i = 0; i < this.inittab.length; i++) {
|
||||
if (this.inittab[i].action == "bootwait") {
|
||||
this.Wait.array.push(this.inittab[i].process);
|
||||
}
|
||||
}
|
||||
if (this.Wait.array.length > 0)
|
||||
stdout.write(" found: \n");
|
||||
for (var i = 0; i < this.Wait.array.length; i++) {
|
||||
stdout.write(" " + this.Wait.array[i] + "\n");
|
||||
}
|
||||
break;
|
||||
case -2:
|
||||
this.Wait.state = 0;
|
||||
this.state++;
|
||||
break;
|
||||
default:
|
||||
if (this.Wait.state >= this.Wait.array.length) {
|
||||
this.Wait.state = -2;
|
||||
break;
|
||||
}
|
||||
InitClass.execWait(this.Wait.array[this.Wait.state], this.Wait);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 25:
|
||||
var code = stdin.read();
|
||||
if (!code)
|
||||
break;
|
||||
var char = KeyCodes.normalKey(code);
|
||||
if (isNumber(char)) {
|
||||
this.destLevel = parseInt(char);
|
||||
this.state = 2;
|
||||
stdout.write("\n\033[?25ldestination runlevel: " + this.destLevel + "\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case SYSHALT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
InitClass.prototype.getStartScripts = function() {
|
||||
|
||||
}
|
||||
InitClass.prototype.getStopScripts = function() {
|
||||
|
||||
}
|
||||
InitClass.execAll = function(array) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var params = InitClass.splitParameter(array[i]);
|
||||
var path = params[0];
|
||||
params.splice(0, 1);
|
||||
var func;
|
||||
eval("func = function() {InitClass.okay('" + path + "', '" + JSON.stringify(params) + "');}")
|
||||
Kernel.ProcessManager.exec(path, func);
|
||||
}
|
||||
}
|
||||
InitClass.okay = function(path, params) {
|
||||
params = JSON.parse(params);
|
||||
var name = path.split("/");
|
||||
name = name[name.length - 1];
|
||||
name = name[0].toUpperCase() + name.substring(1);
|
||||
var prog = eval("new " + name + "Class(1)");
|
||||
Kernel.ProcessManager.add(prog);
|
||||
prog.main(params);
|
||||
}
|
||||
InitClass.wait;
|
||||
InitClass.execWait = function(line, wait) {
|
||||
InitClass.wait = wait;
|
||||
var params = InitClass.splitParameter(line);
|
||||
var path = params[0];
|
||||
params.splice(0, 1);
|
||||
var func;
|
||||
eval("func = function() {InitClass.okayWait('" + path + "', '" + JSON.stringify(params) + "');}");
|
||||
Kernel.ProcessManager.exec(path, func);
|
||||
}
|
||||
InitClass.okayWait = function(path, params) {
|
||||
InitClass.okay(path, params);
|
||||
InitClass.wait.state++;
|
||||
}
|
||||
InitClass.splitParameter = function(line) {
|
||||
var paramArray = line.split(" ");
|
||||
for (var i = 0; i < paramArray.length; i++) {
|
||||
if (paramArray[i] == "") {
|
||||
paramArray.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return paramArray;
|
||||
}
|
||||
InitClass.prototype.signalHandler = function(signal) {
|
||||
switch(signal) {
|
||||
case SIGCHLD:
|
||||
var newChildList = Kernel.ProcessManager.getAllChilds(this.pid);
|
||||
var oldChilds = this.childList.diff(newChildList);
|
||||
var newChilds = newChildList.diff(this.childList);
|
||||
var logText = "init: We lost " + oldChilds.length + " kids and got " + newChilds.length + " new orphans... : (";
|
||||
console.log(logText);
|
||||
this.childList = newChildList;
|
||||
break;
|
||||
case SIGHUP:
|
||||
//break;
|
||||
case SIGALRM:
|
||||
//break;
|
||||
case SIGTERM:
|
||||
//break;
|
||||
case SIGXCPU:
|
||||
//break;
|
||||
case SIGUSR1:
|
||||
//break;
|
||||
case SIGUSR2:
|
||||
//break;
|
||||
default: //SIGKILL
|
||||
console.log("PID " + this.pid + " got Signal " + signal);
|
||||
// Kernel.ProcessManager.remove(this);
|
||||
break;
|
||||
}
|
||||
}
|
176
wish-sys/sys-part/sbin/login.js
Normal file
176
wish-sys/sys-part/sbin/login.js
Normal file
|
@ -0,0 +1,176 @@
|
|||
var LoginClass = function() {
|
||||
}
|
||||
LoginClass.prototype = new Process();
|
||||
LoginClass.prototype.state = 0;
|
||||
LoginClass.prototype.childList = new Array();
|
||||
LoginClass.prototype.username;
|
||||
LoginClass.prototype.password;
|
||||
LoginClass.prototype.users;
|
||||
LoginClass.prototype.user;
|
||||
LoginClass.prototype.main = function(args) {
|
||||
console.log("login: loading /lib/sha256.js");
|
||||
Kernel.ProcessManager.load("/lib/sha256.js", nothing);
|
||||
console.log("login: loading /lib/utf8.js");
|
||||
Kernel.ProcessManager.load("/lib/utf8.js", nothing);
|
||||
console.log("login: adding to scheduler job list");
|
||||
Kernel.Scheduler.add(this);
|
||||
}
|
||||
LoginClass.prototype.tick = function() {
|
||||
var stdout = this.files['stdout'];
|
||||
var stdin = this.files['stdin'];
|
||||
switch(this.state) {
|
||||
case 0:
|
||||
stdout.write("\033[?25h\033[0:0H");
|
||||
if (OS.staticShift)
|
||||
stdout.write("\033[0:" + (OS.staticShift - 1) + "H");
|
||||
stdout.write("\033[0J");
|
||||
this.state++;
|
||||
break;
|
||||
case 1:
|
||||
this.username = new Array();
|
||||
this.password = new Array();
|
||||
stdout.write(OS.hostname + " login: ");
|
||||
this.state++;
|
||||
break;
|
||||
case 2:
|
||||
var code = stdin.read();
|
||||
if (!code)
|
||||
break;
|
||||
if (KeyCodes.isEnter(code)) {
|
||||
this.state++;
|
||||
stdout.write("\n");
|
||||
break;
|
||||
}
|
||||
if (KeyCodes.isBackspace(code)) {
|
||||
if (!this.username.length)
|
||||
break;
|
||||
this.username.pop();
|
||||
stdout.write("\033[1D \033[1D");
|
||||
break;
|
||||
}
|
||||
var char = KeyCodes.normalKey(code);
|
||||
this.username.push(char);
|
||||
stdout.write(char);
|
||||
break;
|
||||
case 3:
|
||||
stdout.write("password: ");
|
||||
this.state++;
|
||||
break;
|
||||
case 4:
|
||||
var code = stdin.read();
|
||||
if (!code)
|
||||
break;
|
||||
if (KeyCodes.isEnter(code)) {
|
||||
this.state++;
|
||||
stdout.write("\n");
|
||||
break;
|
||||
}
|
||||
if (KeyCodes.isBackspace(code)) {
|
||||
if (!this.password.length)
|
||||
break;
|
||||
this.password.pop();
|
||||
break;
|
||||
}
|
||||
var char = KeyCodes.normalKey(code);
|
||||
this.password.push(char);
|
||||
break;
|
||||
case 5:
|
||||
this.username = this.username.join("");
|
||||
this.password = Sha256.hash(this.password.join(""));
|
||||
this.files['passwd'] = Kernel.Filesystem.getFile("/etc/passwd.json");
|
||||
Kernel.Filesystem.update("/etc/passwd.json");
|
||||
this.users = JSON.parse(this.files['passwd'].read());
|
||||
this.state++;
|
||||
break;
|
||||
case 6:
|
||||
for (var i = 0; i < this.users.length; i++) {
|
||||
if (this.users[i].username == this.username) {
|
||||
if (this.users[i].password == this.password) {
|
||||
this.state = 7;
|
||||
this.user = this.users[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.state == 6) {
|
||||
this.state = 1;
|
||||
stdout.write("\n");
|
||||
stdout.write("Login incorrect\n");
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
stdout.write("\n");
|
||||
console.log("login: okay, user='" + this.user.username + "' shell='" + this.user.shell + "' dir='" + this.user.home + "'");
|
||||
this.execProgram(this.user);
|
||||
this.state++;
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
LoginClass.prototype.execProgram = function(user) {
|
||||
var name = user.shell;
|
||||
params = [name, user.username, user.home];
|
||||
var pathArray = new Array();
|
||||
pathArray[0] = ["stdout", this.files['stdout'].path];
|
||||
pathArray[1] = ["stdin", this.files['stdin'].path];
|
||||
var s = "";
|
||||
s += "var func = function () { ";
|
||||
s += " try {";
|
||||
s += " var prog = new " + Kernel.ProcessManager.getClassNameFromFileName(name) + "();";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += " prog.init(" + this.pid + ");";
|
||||
s += " var paths = JSON.parse('" + JSON.stringify(pathArray) + "');";
|
||||
s += " for(var i = 0; i < paths.length; i++) {";
|
||||
s += " prog.files[paths[i][0]] = Kernel.Filesystem.getFile(paths[i][1]);";
|
||||
s += " }";
|
||||
s += " Kernel.ProcessManager.add(prog);";
|
||||
s += " console.log(\"login: start shell '" + name + "'...\");";
|
||||
s += " try {";
|
||||
s += " prog.main(JSON.parse('" + JSON.stringify(params) + "'));";
|
||||
s += " } catch (exception) {";
|
||||
s += " console.dir(exception);";
|
||||
s += " }";
|
||||
s += "}";
|
||||
eval(s);
|
||||
Kernel.ProcessManager.load(name, func);
|
||||
}
|
||||
LoginClass.prototype.signalHandler = function(signal) {
|
||||
switch(signal) {
|
||||
case SIGCHLD:
|
||||
var newChildList = Kernel.ProcessManager.getAllChilds(this.pid);
|
||||
var oldChilds = this.childList.diff(newChildList);
|
||||
var newChilds = newChildList.diff(this.childList);
|
||||
if (newChilds.length)
|
||||
console.log("login: we got " + newChilds.length + " new kid(s)... : )")
|
||||
if (oldChilds.length) {
|
||||
console.log("login: we lost " + oldChilds.length + " kid(s) (should be client shell)");
|
||||
console.log("login: trying to restart");
|
||||
this.state = 0;
|
||||
}
|
||||
for (var i = 0; i < oldChilds; i++)
|
||||
Kernel.ProcessManager.remove(oldChilds[i]);
|
||||
this.childList = newChildList;
|
||||
break;
|
||||
case SIGHUP:
|
||||
//break;
|
||||
case SIGALRM:
|
||||
//break;
|
||||
case SIGTERM:
|
||||
//break;
|
||||
case SIGXCPU:
|
||||
//break;
|
||||
case SIGUSR1:
|
||||
//break;
|
||||
case SIGUSR2:
|
||||
//break;
|
||||
default: //SIGKILL
|
||||
console.log("PID " + this.pid + " got Signal " + signal);
|
||||
Kernel.ProcessManager.remove(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue