/* * 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 */ /* $Id: LuaTask.cc,v 1.11 2007-05-30 19:03:22 pixel Exp $ */ #include #include #include #ifndef LUATASK_OMIT_HTTPCLIENT #include #endif #ifndef LUATASK_OMIT_COMMAND #include #endif htab * LuaTask::h = hcreate(1); LuaTask::LuaTask(Lua * _L, const String & _cmd) : L(_L), cmd(_cmd), nargs(0), c(0), b(0) { LuaTask * top = gettop(); if (top) { WaitFor(top); } else { SetBurst(); } settop(this); stacktop = L->gettop() + 1; } LuaTask::LuaTask(Lua * _L, int _nargs) throw (GeneralException) : L(_L), cmd(""), nargs(_nargs), c(0), b(0) { if (gettop()) throw GeneralException("Can't run a stack-based LuaTask when there are other tasks waiting."); SetBurst(); settop(this); stacktop = L->gettop() - nargs; } LuaTask::~LuaTask() { if (gettop() == this) { settop(0); } } LuaTask * LuaTask::gettop() { if (!hfind(h, (Uint8 *) L, sizeof(L))) { hadd(h, (Uint8 *) L, sizeof(L), 0); } return (LuaTask *) hstuff(h); } void LuaTask::settop(LuaTask * v) { if (!hfind(h, (Uint8 *) L, sizeof(L))) return; if (v) { hstuff(h) = v; } else { hdel(h); } } String LuaTask::GetName() { return "LuaTask(" + cmd + ")"; } int LuaTask::Do() throw (GeneralException) { switch (current) { case 0: current = 1; if (cmd != "") { L->resume(cmd); } else { L->resume(nargs); } case 2: nargs = 0; #ifndef LUATASK_OMIT_HTTPCLIENT if (task == "HttpClient") { LuaBuffer o(b); o.pushdestruct(L); nargs = 1; } #endif #ifndef LUATASK_OMIT_COMMAND if (task == "Command") { delete p; LuaBuffer o(b); o.pushdestruct(L); L->push((lua_Number) TaskMan::Estatus()); nargs = 2; } #endif if (!c) delete c; c = 0; if (current != 1) L->resume(nargs); case 1: current = 2; if (L->gettop() >= 1) { task = L->tostring(1); if (task == "") { L->error("Must precise a task-type to execute."); return TASK_DONE; #ifndef LUATASK_OMIT_HTTPCLIENT } else if (task == "HttpClient") { String url = L->tostring(2); t_headers headers; b = new Buffer(true); headers.push_back("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0"); c = new HttpClient(url, b, "", headers); WaitFor(c); Suspend(TASK_ON_HOLD); #endif #ifndef LUATASK_OMIT_COMMAND } else if (task == "Command") { pid_t pid; int i; char * cmd; char ** args, ** ptr; cmd = L->tostring(2).strdup(); args = (char **) malloc(sizeof(char *) * (L->gettop() - 1)); args[0] = cmd; for (i = 3; i <= L->gettop(); i++) { args[i - 2] = L->tostring(i).strdup(); } args[L->gettop() - 1] = 0; b = new Buffer(true); p = new InPipe(); if (!(pid = fork())) { p->Hook(); execvp(cmd, args); } c = new CopyJob(p, b); for (i = 3; i <= L->gettop(); i++) { free(args[i - 2]); } free(cmd); current = 3; WaitFor(pid); Suspend(TASK_ON_HOLD); #endif } else { L->error("Unknow requested task: " + task); return TASK_DONE; } } else { return TASK_DONE; } break; #ifndef LUATASK_OMIT_COMMAND case 3: current = 2; WaitFor(c); p->HalfClose(); return TASK_ON_HOLD; #endif } return TASK_ON_HOLD; }