/* * Baltisot * Copyright (C) 1999-2007 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "LuaCommandLine.h" #include "Buffer.h" #include "CopyJob.h" #include "ReadJob.h" #include "LuaTask.h" class CommandLineSpawn; class LuaCommandLinePrinter : public LuaPrinter { public: LuaCommandLinePrinter(CommandLineSpawn * _cls) : cls(_cls) { } virtual void puts(const char * msg); private: CommandLineSpawn * cls; }; class CommandLineSpawn : public Task { public: CommandLineSpawn(Lua * _L, const Socket & _s) : L(_L), s(_s) { SetBurst(); p = new LuaCommandLinePrinter(this); b << "Lua Command Line - Ready to serve.\n"; nL = L->thread(1); L->pop(); nL->SetPrinter(p); } virtual ~CommandLineSpawn() { delete p; } void puts(const char * msg) { b << msg; } virtual String GetName() { return "Command Line Spawn"; } virtual int Do() throw (GeneralException) { switch (current) { case 0: delete c; c = 0; cmd = ""; if (!s.IsConnected()) return TASK_DONE; b << "> "; c = new CopyJob(&b, &s, b.GetSize()); WaitFor(c); current = 1; Suspend(TASK_ON_HOLD); case 1: delete c; c = 0; if (s.IsClosed()) return TASK_DONE; c = new ReadJob(&s, &b, any); WaitFor(c); current = 2; Suspend(TASK_ON_HOLD); case 2: delete c; c = 0; if (s.IsClosed()) return TASK_DONE; b >> t; if (t[t.strlen() - 1] != '\\') { cmd = cmd + t + "\n"; pbuff = 0; c = new LuaTask(nL, cmd); cmd = ""; WaitFor(c); current = 0; } else { String e = t.extract(0, t.strlen() - 2); cmd = cmd + e + "\n"; c = new ReadJob(&s, &b, any); WaitFor(c); } Suspend(TASK_ON_HOLD); } } private: Lua * L; Lua * nL; Socket s; Buffer b; Buffer * pbuff; Task * c; String t; String cmd; LuaPrinter * p; }; void LuaCommandLinePrinter::puts(const char * msg) { cls->puts(msg); } LuaCommandLine::LuaCommandLine(Lua * _L, int _port) : L(_L), port(_port) { bool r = true; r = Listener.SetLocal("", port); if (!r) { throw GeneralException("Initialisation of CommandLine failed: can't bind."); } r = Listener.Listen(); if (!r) { throw GeneralException("Initialisation of CommandLine failed: can't listen."); } Listener.SetNonBlock(); WaitFor(&Listener, W4_STICKY | W4_READING); } LuaCommandLine::~LuaCommandLine() { Listener.close(); } String LuaCommandLine::GetName() { return "Command Line"; } int LuaCommandLine::Do() throw (GeneralException) { try { Socket s = Listener.Accept(); s.SetNonBlock(); new CommandLineSpawn(L, s); } catch (GeneralException) { } return TASK_ON_HOLD; }