diff options
-rw-r--r-- | include/Action.h | 3 | ||||
-rw-r--r-- | include/Buffer.h | 2 | ||||
-rw-r--r-- | include/Confirm.h | 2 | ||||
-rw-r--r-- | include/CopyJob.h | 4 | ||||
-rw-r--r-- | include/Form.h | 2 | ||||
-rw-r--r-- | include/HttpServ.h | 4 | ||||
-rw-r--r-- | include/Menu.h | 2 | ||||
-rw-r--r-- | include/Message.h | 2 | ||||
-rw-r--r-- | include/Socket.h | 2 | ||||
-rw-r--r-- | include/Table.h | 2 | ||||
-rw-r--r-- | include/Task.h | 10 | ||||
-rw-r--r-- | lib/Buffer.cc | 8 | ||||
-rw-r--r-- | lib/Confirm.cc | 23 | ||||
-rw-r--r-- | lib/CopyJob.cc | 56 | ||||
-rw-r--r-- | lib/Form.cc | 31 | ||||
-rw-r--r-- | lib/Handle.cc | 9 | ||||
-rw-r--r-- | lib/HttpServ.cc | 221 | ||||
-rw-r--r-- | lib/IRC.cc | 4 | ||||
-rw-r--r-- | lib/Menu.cc | 19 | ||||
-rw-r--r-- | lib/Message.cc | 21 | ||||
-rw-r--r-- | lib/ReadJob.cc | 55 | ||||
-rw-r--r-- | lib/Socket.cc | 22 | ||||
-rw-r--r-- | lib/Table.cc | 33 | ||||
-rw-r--r-- | lib/Task.cc | 26 | ||||
-rw-r--r-- | lib/TaskMan.cc | 2 | ||||
-rw-r--r-- | src/Main.cc | 11 |
26 files changed, 338 insertions, 238 deletions
diff --git a/include/Action.h b/include/Action.h index 185cd1a..bf3dc1a 100644 --- a/include/Action.h +++ b/include/Action.h @@ -2,6 +2,7 @@ #define __ACTION_H__ #ifdef __cplusplus +#include <Task.h> #include <Handle.h> #include <Variables.h> #include <Exceptions.h> @@ -35,7 +36,7 @@ class Action : public Base { Action(const String & = ""); virtual ~Action(); Action * Look4URL(const String &); - virtual void Do(Variables *, Handle *) = 0; + virtual Task * Do(Variables *, Handle *) = 0; virtual void SendHead(Handle *); virtual void SendFoot(Handle *); virtual void ShowButton(Handle *, const String & = " Ok ", const String & = "start"); diff --git a/include/Buffer.h b/include/Buffer.h index cf57cb6..8b1c131 100644 --- a/include/Buffer.h +++ b/include/Buffer.h @@ -14,7 +14,7 @@ class Buffer : public Handle { Buffer(); ~Buffer(); virtual ssize_t write(const void *buf, size_t count); - virtual ssize_t read(void *buf, size_t count); + virtual ssize_t read(void *buf, size_t count) throw (GeneralException); virtual bool CanRead(); virtual bool CanWrite(); virtual String GetName(); diff --git a/include/Confirm.h b/include/Confirm.h index efd0606..d327f23 100644 --- a/include/Confirm.h +++ b/include/Confirm.h @@ -21,7 +21,7 @@ class Confirm : public Action { Confirm(const String & titre, const String & msg, const String & url, Action * yes, Action * no = 0); virtual ~Confirm() { } virtual String GetTitle(); - virtual void Do(Variables *, Handle *); + virtual Task * Do(Variables *, Handle *); private: String tit, msg; Action * NYes, * NNo; diff --git a/include/CopyJob.h b/include/CopyJob.h index 67cbf36..c4cda81 100644 --- a/include/CopyJob.h +++ b/include/CopyJob.h @@ -9,14 +9,16 @@ class CopyJob : public Task { public: - CopyJob(Handle *, Handle *, ssize_t = -1); + CopyJob(Handle *, Handle *, ssize_t = -1, bool = false); virtual ~CopyJob(); virtual int Do() throw (GeneralException); virtual String GetName(); private: Handle * s, * d; + bool ds; ssize_t siz, cursiz; char buffer[COPY_BUFSIZ]; + int r; }; #else diff --git a/include/Form.h b/include/Form.h index 50b7e3c..1b22742 100644 --- a/include/Form.h +++ b/include/Form.h @@ -29,7 +29,7 @@ class Form : public Action { int nb, Action * ok = 0); virtual ~Form() { } virtual String GetTitle(); - virtual void Do(Variables *, Handle *); + virtual Task * Do(Variables *, Handle *); private: String tit, iv, * nms, * ivs, * defs, ** lsts, ** dscs; int n; diff --git a/include/HttpServ.h b/include/HttpServ.h index 18295bc..51511b2 100644 --- a/include/HttpServ.h +++ b/include/HttpServ.h @@ -19,7 +19,7 @@ class HttpServ : public Task { public: - HttpServ(int = 1500, const String & = String("GruiK Server v0.1")) throw (GeneralException); + HttpServ(Action *, int = 1500, const String & = String("GruiK Server v0.1")) throw (GeneralException); ~HttpServ() {} void SetMenu(Action *); virtual String GetName(); @@ -27,6 +27,8 @@ class HttpServ : public Task { virtual int Do(); private: Socket Listener; + Action * p; + String name; int localport; }; diff --git a/include/Menu.h b/include/Menu.h index 4167656..e656657 100644 --- a/include/Menu.h +++ b/include/Menu.h @@ -21,7 +21,7 @@ class Menu : public Action { Menu(const String & titre, const String & url, String * labels, Action ** listac, int nb); virtual ~Menu() {} virtual String GetTitle(); - virtual void Do(Variables *, Handle *); + virtual Task * Do(Variables *, Handle *); private: String tit; String * lt; diff --git a/include/Message.h b/include/Message.h index 96b9aa4..77bd62c 100644 --- a/include/Message.h +++ b/include/Message.h @@ -20,7 +20,7 @@ class Message : public Action { Message(const String & titre, const String & msg, const String & url, Action * ok = 0); virtual ~Message() { } virtual String GetTitle(); - virtual void Do(Variables *, Handle *); + virtual Task * Do(Variables *, Handle *); private: String tit, msg; Action * Next; diff --git a/include/Socket.h b/include/Socket.h index 6bd612c..514db43 100644 --- a/include/Socket.h +++ b/include/Socket.h @@ -39,8 +39,6 @@ class Socket : public Handle { Socket Accept() throw (GeneralException); bool IsConnected(); bool IsListening(); - size_t WriteFile(Output &); - size_t ReadFile(Input &); virtual bool CanRead(); virtual bool CanWrite(); virtual String GetName(); diff --git a/include/Table.h b/include/Table.h index 64cf249..f1ec6c6 100644 --- a/include/Table.h +++ b/include/Table.h @@ -23,7 +23,7 @@ class Table : public Action { Table(const String & titre, const String & url, String * heads, String * cells, int nbcol, int nblgn, Action * ok = 0); virtual ~Table() { } virtual String GetTitle(); - virtual void Do(Variables *, Handle *); + virtual Task * Do(Variables *, Handle *); private: String tit, * hds, * cls; int nc, nl; diff --git a/include/Task.h b/include/Task.h index 1842314..503e0df 100644 --- a/include/Task.h +++ b/include/Task.h @@ -10,6 +10,7 @@ #define TASK_ON_HOLD 0 #define TASK_DONE 1 +#define TASK_BURST 2 class Task : public Base { public: @@ -23,13 +24,20 @@ class Task : public Base { void WaitFor(Task *); void WaitFor(pid_t); void WaitFor(struct timeval); + void SetBurst(); + void SetCleanUp(); + bool HasToClean(); + void Stop(); + void Restart(); + bool IsStopped(); protected: virtual int Do() throw (GeneralException); - int current; private: int state; + bool stopped; + bool cleanup; bool suspended; vector<Handle *> w4ha; vector<Task *> w4ta; diff --git a/lib/Buffer.cc b/lib/Buffer.cc index 6d0317e..123cc65 100644 --- a/lib/Buffer.cc +++ b/lib/Buffer.cc @@ -3,7 +3,7 @@ #include "General.h" #include "config.h" -Buffer::Buffer() : Handle(-1), buffer(NULL), realsiz(0), bufsiz(0), ptr(0) { } +Buffer::Buffer() : Handle(-1), buffer(0), realsiz(0), bufsiz(0), ptr(0) { } Buffer::~Buffer() { free(buffer); @@ -21,13 +21,13 @@ ssize_t Buffer::write(const void *buf, size_t count) { return count; } -ssize_t Buffer::read(void *buf, size_t count) { +ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) { count = MIN(count, realsiz - ptr); - + if (!count) { return 0; } - + memcpy(buf, buffer + ptr, count); ptr += count; diff --git a/lib/Confirm.cc b/lib/Confirm.cc index 0fbb902..7d72ee0 100644 --- a/lib/Confirm.cc +++ b/lib/Confirm.cc @@ -1,26 +1,31 @@ #include "HttpServ.h" #include "Confirm.h" +#include "Buffer.h" +#include "CopyJob.h" #include "config.h" Confirm::Confirm(const String & t, const String & m, const String & U, Action * y, Action * n) : Action(U), tit(t), msg(m), NYes(y), NNo(n) { } -void Confirm::Do(Variables * v, Handle * h) { - SendHead(h); - (*h) << msg << "<CENTER><TABLE BORDER=0><tr><td>" << endnl << +Task * Confirm::Do(Variables * v, Handle * h) { + Handle * b = new Buffer; + Task * t = new CopyJob(b, h, -1, true); + SendHead(b); + (*b) << msg << "<CENTER><TABLE BORDER=0><tr><td>" << endnl << "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NYes ? NYes->GetURL() : "start") << "\">" << endnl << "<INPUT TYPE=\"HIDDEN\" VALUE=\"yes\" NAME=\"confirm\">" << endnl << "<INPUT TYPE=\"SUBMIT\" VALUE=\" Oui \">" << endnl; - v->Dump(h); - (*h) << "</FORM></td><td>" << endnl << + v->Dump(b); + (*b) << "</FORM></td><td>" << endnl << "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NNo ? NNo->GetURL() : "start") << "\">" << endnl << "<INPUT TYPE=\"HIDDEN\" VALUE=\"no\" NAME=\"confirm\">" << endnl << "<INPUT TYPE=\"SUBMIT\" VALUE=\" Non \">" << endnl; - v->Dump(h); - (*h) << "</FORM></td></tr></TABLE></CENTER>" << endnl; - SendFoot(h); - + v->Dump(b); + (*b) << "</FORM></td></tr></TABLE></CENTER>" << endnl; + SendFoot(b); Accessed(); + + return t; } String Confirm::GetTitle(void) { diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc index fb8c6e2..9dc9978 100644 --- a/lib/CopyJob.cc +++ b/lib/CopyJob.cc @@ -1,34 +1,46 @@ #include "CopyJob.h" #include "General.h" -CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz) : s(as), d(ad), siz(asiz), cursiz(0) { } +CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz, bool ads) : s(as), d(ad), siz(asiz), ds(ads), cursiz(0), r(0) { + WaitFor(s); + WaitFor(d); +} CopyJob::~CopyJob() { } int CopyJob::Do() throw (GeneralException) { - int r, tr; + int tr; - while (!s->IsClosed() || (siz != cursiz)) { - switch (current) { - case 0: - tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ; - try { - r = s->read(buffer, MIN(COPY_BUFSIZ, tr)); - } - catch (IOAgain e) { - throw TaskSwitch(); - } - case 1: - try { - d->write(buffer, r); - } - catch (IOAgain e) { - current = 1; - throw TaskSwitch(); - } - current = 0; + switch (current) { + case 0: + tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ; + try { + r = s->read(buffer, MIN(COPY_BUFSIZ, tr)); + } + catch (IOAgain e) { + Suspend(); + } + case 1: + if (!r) { + return TASK_DONE; + } + try { + d->write(buffer, r); + } + catch (IOAgain e) { + current = 1; + Suspend(); } - cursiz += r; + current = 0; + } + cursiz += r; + + if (!s->IsClosed() || (siz != cursiz)) { + throw TaskSwitch(); + } + + if (ds) { + delete s; } return TASK_DONE; diff --git a/lib/Form.cc b/lib/Form.cc index 5fb885a..e26cf72 100644 --- a/lib/Form.cc +++ b/lib/Form.cc @@ -1,5 +1,8 @@ #include "Form.h" #include "HttpServ.h" +#include "Buffer.h" +#include "CopyJob.h" +#include "config.h" Form::Form(const String & titre, const String & url, const String & inv, String * names, String * invs, String * defaults, String ** lists, String ** descs, int nb, Action * na) : @@ -9,16 +12,18 @@ String Form::GetTitle(void) { return tit; } -void Form::Do(Variables * v, Handle * h) { - SendHead(h); +Task * Form::Do(Variables * v, Handle * h) { + Handle * b = new Buffer(); + Task * t = new CopyJob(b, h, -1, true); + SendHead(b); - (*h) << + (*b) << "<center>" << endnl << "<form ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\" METHOD=POST>" << endnl; - v->Dump(h); + v->Dump(b); - (*h) << + (*b) << "<table BORDER=0 CELLSPACING=0 BGCOLOR=\"#000000\"><tr><td>" << endnl << "<table BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=\"300\" BGCOLOR=\"#FFFFCC\">" << endnl << "<tr><td ALIGN=CENTER WIDTH=\"100%\" BGCOLOR=\"#000000\"><b><font FACE=\"arial,helvetica\" COLOR=\"#FFFFFF\">" << endnl << @@ -26,31 +31,33 @@ iv << endnl << "</font></b></td></tr>" << endnl; for (int i = 0; i < n; i++) { - (*h) << + (*b) << "<tr><td>" << ivs[i] << "</td></tr>" << endnl; if (lsts[i]) { String * s, * t; - (*h) << + (*b) << "<tr><td><select NAME=\"" << nms[i] << "\">" << endnl; for (s = lsts[i], t = dscs[i]; s->strlen(); s++, t++) { - (*h) << + (*b) << "<option VALUE=\"" << *s << "\">" << *t << "</option>" << endnl; } - (*h) << + (*b) << "</select></td></tr>" << endnl; } else { - (*h) << + (*b) << "<tr><td><input TYPE=\"text\" NAME=\"" << nms[i] << "\" VALUE=\"" << defs[i] << "\" size=40></tr></td>" << endnl; } } - (*h) << + (*b) << "<tr><td ALIGN=\"center\"><input TYPE=\"submit\" VALUE=\" Ok \"></td></tr>" << endnl << "</table></td></tr></table></form></center>" << endnl; - SendFoot(h); + SendFoot(b); Accessed(); + + return t; } diff --git a/lib/Handle.cc b/lib/Handle.cc index dd22b5c..6f7c6e5 100644 --- a/lib/Handle.cc +++ b/lib/Handle.cc @@ -9,9 +9,7 @@ Handle::Handle(const Handle & nh) : h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(false), nonblock(false) { } Handle::~Handle() { - if (h >= 0) { - ::close(h); - } + close(); } Handle::Handle(int nh) : h(nh), closed(false) { } @@ -60,7 +58,7 @@ ssize_t Handle::write(const void *buf, size_t count) throw (GeneralException) { ssize_t Handle::read(void *buf, size_t count) throw (GeneralException) { ssize_t r; - + errno = 0; if ((r = ::read(h, buf, count)) < 0) { if ((!errno) || (errno = EAGAIN)) { @@ -73,8 +71,7 @@ ssize_t Handle::read(void *buf, size_t count) throw (GeneralException) { } if (!r) { - ::close(h); - closed = true; + close(); } return r; diff --git a/lib/HttpServ.cc b/lib/HttpServ.cc index 7464e5b..fe48f54 100644 --- a/lib/HttpServ.cc +++ b/lib/HttpServ.cc @@ -3,6 +3,7 @@ #include "HttpServ.h" #include "Buffer.h" #include "ReadJob.h" +#include "CopyJob.h" #include "Task.h" #include "config.h" @@ -10,7 +11,7 @@ String endhl = "\r\n", endnl = "\n"; class ProcessRequest : public Task { public: - ProcessRequest(Action *, const Socket &); + ProcessRequest(Action *, const Socket &, const String &, int); virtual ~ProcessRequest() {} virtual String GetName(); protected: @@ -25,121 +26,152 @@ class ProcessRequest : public Task { String file, domain, t; Buffer b; - Task * c; + Task * c, * a; Action * f; - int len; + int len, localport; Action * p; Socket s; String name; Variables * Vars; - bool bad; - + bool bad, hasvars, post; }; -ProcessRequest::ProcessRequest(Action * ap, const Socket & as) : p(ap), s(as) { } +ProcessRequest::ProcessRequest(Action * ap, const Socket & as, const String & aname, int aport) : localport(aport), p(ap), s(as), name(aname) { } String ProcessRequest::GetName() { return "Processing HTTP request"; } int ProcessRequest::Do() { - c = new ReadJob(&s, &b); - -} + switch (current) { + case 0: + c = new ReadJob(&s, &b); + WaitFor(c); + current = 1; + Suspend(); -void ProcessRequest::ProcessRequest(Action * p, Socket s) { - c = new ReadJob(&s, &b); + case 1: + delete c; - s.SetNonBlock(); + bad = false; - c->Run(); - delete c; - - bad = false; + if (!s.IsConnected()) return TASK_DONE; - if (!s.IsConnected()) return; + cerr << "Got a request\n----\n"; - cerr << "Got a request\n----\n"; - - bool post = ParseUri(file, domain, &b); - - len = -1; - do { - b >> t; - cerr << t << endl; - if ((t.strstr("Content-Length: ") == 0) || (t.strstr("Content-length: ") == 0)) { - cerr << "Saw 'Content-Lenght:', reading length from '" << t.extract(16) << "'\n"; - len = t.extract(16).to_int(); - } - } while (t.strlen()); - - if (post) { - // On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST. - // Cela est une erreur. - if (len == -1) { - bad = true; - Vars = new Variables(0); + post = ParseUri(file, domain, &b); + + len = -1; + do { + b >> t; + cerr << t << endl; + if ((t.strstr("Content-Length: ") == 0) || (t.strstr("Content-length: ") == 0)) { + cerr << "Saw 'Content-Lenght:', reading length from '" << t.extract(16) << "'\n"; + len = t.extract(16).to_int(); + } + } while (t.strlen()); + + hasvars = false; + + if (post) { + // On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST. + // Cela est une erreur. + if (len == -1) { + bad = true; + Vars = new Variables(); + } else { + cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n"; + // Les variables seront initialisées ici. + hasvars = true; + } } else { - cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n"; - // Les variables seront initialisées ici. - ParseVars(&s, len); + Vars = new Variables(); } - } else { - Vars = new Variables(0); - } + + c = new CopyJob(&s, &b, len); + WaitFor(c); + current = 2; + Suspend(); + + case 2: + delete c; + ParseVars(&s, len); - cerr << " Domain = '" << domain << "' - File = '" << file << "'\n"; + cerr << " Domain = '" << domain << "' - File = '" << file << "'\n"; - if (!bad) { - // Nous vérifions le domaine. - if (domain != "") { - bad = true; - // Les domaines valides sont '/', '/bin' et '/image'. - if (domain == "/image") bad = false; - if (domain == "/bin") bad = false; - if (domain == "/") bad = false; - } else { - // L'url sans domaine ni fichier est valide. (cela arrive sur certains navigateurs...) - bad = (file != ""); - } - } - - if (bad) { - ShowError(&s); - } else { - if (((domain == "") || (domain == "/")) && (file == "")) { - // Si le navigateur a demandé l'URL '/', alors on renvoie une notification - // de redirection. - SendRedirect(&s); - } else if (domain == "/bin") { - // Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer. - if ((f = p->Look4URL(file))) { - SendHeads(&s, "text/html"); - f->Do(Vars, &s); + if (!bad) { + // Nous vérifions le domaine. + if (domain != "") { + bad = true; + // Les domaines valides sont '/', '/bin' et '/image'. + if (domain == "/image") bad = false; + if (domain == "/bin") bad = false; + if (domain == "/") bad = false; } else { - ShowError(&s); + // L'url sans domaine ni fichier est valide. (cela arrive sur certains navigateurs...) + bad = (file != ""); } + } + + a = 0; + + if (bad) { + ShowError(&b); } else { - // Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas. - // On utilise try au cas où le fichier n'existe pas et donc que le constructeur - // d'input renvoie une erreur. - try { - Input i(String("datas/") + file); - SendHeads(&s, GetMime(file)); - s.ReadFile(i); - cerr << "File found, dumped.\n"; - } - catch (IOGeneral e) { - ShowError(&s); - cerr << "File not found, error showed.\n"; + if (((domain == "") || (domain == "/")) && (file == "")) { + // Si le navigateur a demandé l'URL '/', alors on renvoie une notification + // de redirection. + SendRedirect(&b); + } else if (domain == "/bin") { + // Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer. + if ((f = p->Look4URL(file))) { + SendHeads(&s, "text/html"); + a = f->Do(Vars, &s); + } else { + ShowError(&b); + } + } else { + // Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas. + // On utilise try au cas où le fichier n'existe pas et donc que le constructeur + // d'input renvoie une erreur. + try { + Handle * i = new Input(String("datas/") + file); + SendHeads(&b, GetMime(file)); + a = new CopyJob(i, &s, -1, true); + cerr << "File found, dumping.\n"; + } + catch (IOGeneral e) { + ShowError(&b); + cerr << "File not found, error showed.\n"; + } } } - } - delete Vars; + if (a) a->Stop(); + + delete Vars; + c = new CopyJob(&b, &s); + WaitFor(c); + current = 3; + Suspend(); + + case 3: + delete c; + + if (a) { + a->Restart(); + WaitFor(a); + current = 4; + Suspend(); + } + + case 4: + if (a) delete a; - cerr << "----\n"; + cerr << "----\n"; + } + return TASK_DONE; } void ProcessRequest::ParseVars(Handle * s, int len) { @@ -205,7 +237,7 @@ void ProcessRequest::ParseVars(Handle * s, int len) { bool ProcessRequest::ParseUri(String & file, String & domain, Handle * s) { String t, Uri; bool post = false; - const char * p = NULL; + const char * p = 0; ssize_t sppos; *s >> t; @@ -326,7 +358,7 @@ String ProcessRequest::GetMime(const String & f) { return "text/plain"; } -HttpServ::HttpServ(int port, const String & nname) throw (GeneralException) : name(nname), localport(port) { +HttpServ::HttpServ(Action * ap, int port, const String & nname) throw (GeneralException) : p(ap), name(nname), localport(port) { bool r = true; r = Listener.SetLocal("", port); @@ -338,18 +370,23 @@ HttpServ::HttpServ(int port, const String & nname) throw (GeneralException) : na throw GeneralException("Initialisation of the Mini HTTP-Server failed."); } - r.SetNonBlock(); + Listener.SetNonBlock(); + WaitFor(&Listener); cerr << "Mini HTTP-Server '" << name << "' ready and listening for port " << port << endl; } -int HttpServ::Do(Action * p) { +int HttpServ::Do() { try { Socket s = Listener.Accept(); - new ProcessRequest(p, Listener.Accept()); + s.SetNonBlock(); + new ProcessRequest(p, s, name, localport); } catch (GeneralException) { - return TASK_ON_HOLD; } + return TASK_ON_HOLD; } +String HttpServ::GetName() { + return String("Mini HTTP-Server '") + name + "'"; +} @@ -158,9 +158,9 @@ ircmsg_t ircmsgs[MSG_COUNT] = { "ERR_USERSDONTMATCH", ERR_USERSDONTMATCH }, }; -Channel * Channel::start = NULL; +Channel * Channel::start = 0; -Channel::Channel(const String & Name, const String & Key) : next(NULL), prev(NULL) { +Channel::Channel(const String & Name, const String & Key) : next(0), prev(0) { next = start->next; prev = start; start = this; diff --git a/lib/Menu.cc b/lib/Menu.cc index 7488d1d..f804cef 100644 --- a/lib/Menu.cc +++ b/lib/Menu.cc @@ -1,24 +1,31 @@ #include "Menu.h" #include "HttpServ.h" +#include "CopyJob.h" +#include "Buffer.h" +#include "config.h" Menu::Menu(const String & t, const String & U, String * ts, Action ** as, int nb) : Action(U), tit(t), lt(ts), la(as), nba(nb) { } -void Menu::Do(Variables * v, Handle * h) { +Task * Menu::Do(Variables * v, Handle * h) { int i, f = 0; + Handle * b = new Buffer(); + Task * t = new CopyJob(b, h, -1, true); - SendHead(h); - (*h) << "<center><TABLE BORDER=0>" << endnl; + SendHead(b); + (*b) << "<center><TABLE BORDER=0>" << endnl; for (i = 0; i < nba; i++) { - (*h) << "<TR BGCOLOR=\"#" << (f ? "dddddd" : "cccccc") << "\"><TD ALIGN=\"center\">" << (i + 1) << "</TD><TD>" + (*b) << "<TR BGCOLOR=\"#" << (f ? "dddddd" : "cccccc") << "\"><TD ALIGN=\"center\">" << (i + 1) << "</TD><TD>" "<A HREF=\"/bin/" << (la[i] ? la[i]->GetURL() : "start") << "\">" << lt[i] << "</A></TD></TR>" << endnl; f = f ? 0 : 1; } - (*h) << "</TABLE></center>" << endnl; - SendFoot(h); + (*b) << "</TABLE></center>" << endnl; + SendFoot(b); Accessed(); + + return t; } String Menu::GetTitle(void) { diff --git a/lib/Message.cc b/lib/Message.cc index 1ede8fb..acd7933 100644 --- a/lib/Message.cc +++ b/lib/Message.cc @@ -1,19 +1,26 @@ #include "HttpServ.h" #include "Message.h" +#include "Buffer.h" +#include "CopyJob.h" #include "config.h" Message::Message(const String & t, const String & m, const String & U, Action * n) : Action(U), tit(t), msg(m), Next(n) { } -void Message::Do(Variables * v, Handle * h) { - SendHead(h); - (*h) << msg << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl << +Task * Message::Do(Variables * v, Handle * h) { + Handle * b = new Buffer(); + Task * t = new CopyJob(b, h, -1, true); + + SendHead(b); + (*b) << msg << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl << "<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl; - v->Dump(h); - (*h) << "</FORM></CENTER>" << endnl; - SendFoot(h); - + v->Dump(b); + (*b) << "</FORM></CENTER>" << endnl; + SendFoot(b); + Accessed(); + + return t; } String Message::GetTitle(void) { diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc index 6640d82..9f037d9 100644 --- a/lib/ReadJob.cc +++ b/lib/ReadJob.cc @@ -1,7 +1,10 @@ #include "ReadJob.h" #include "HttpServ.h" -ReadJob::ReadJob(Handle * as, Handle * ad) : s(as), d(ad) { } +ReadJob::ReadJob(Handle * as, Handle * ad) : s(as), d(ad) { + WaitFor(s); + WaitFor(d); +} ReadJob::~ReadJob() { } @@ -10,31 +13,33 @@ int ReadJob::Do() throw (GeneralException) { cerr << "ReadJob running...\n"; - while (!s->IsClosed()) { - switch (current) { - case 0: - try { - cerr << "Trying to read...\n"; - *s >> buff; - } - catch (IOAgain e) { - cerr << "Suspending ReadJob to wait for reading...\n"; - throw TaskSwitch(); - } - cerr << "Read some bytes...\n"; - case 1: - try { - *d << buff << endnl; - } - catch (IOAgain e) { - cerr << "Suspending ReadJob to wait for writing...\n"; - current = 1; - throw TaskSwitch(); - } - current = 0; - cerr << "Wrote some bytes...\n"; - if (buff == "") return TASK_DONE; + switch (current) { + case 0: + try { + cerr << "Trying to read...\n"; + *s >> buff; + } + catch (IOAgain e) { + cerr << "Suspending ReadJob to wait for reading...\n"; + throw TaskSwitch(); + } + cerr << "Read some bytes...\n"; + case 1: + try { + *d << buff << endnl; } + catch (IOAgain e) { + cerr << "Suspending ReadJob to wait for writing...\n"; + current = 1; + throw TaskSwitch(); + } + current = 0; + cerr << "Wrote some bytes...\n"; + if (buff == "") return TASK_DONE; + } + + if (!s->IsClosed()) { + throw TaskSwitch(); } return TASK_DONE; diff --git a/lib/Socket.cc b/lib/Socket.cc index f3f4c0f..5d80783 100644 --- a/lib/Socket.cc +++ b/lib/Socket.cc @@ -41,28 +41,6 @@ bool Socket::CanWrite(void) { return connected; } -size_t Socket::WriteFile(Output & o) { - char c; - size_t s = 0; - - while (!IsClosed()) { - s += read(&c, 1); - o.write(&c, 1); - } - return s; -} - -size_t Socket::ReadFile(Input & i) { - char c; - size_t s = 0; - - while (!i.IsClosed()) { - s += i.read(&c, 1); - write(&c, 1); - } - return s; -} - /***********************************************\ * Toute la suite n'est pas à décrire. Consulter * diff --git a/lib/Table.cc b/lib/Table.cc index 776caae..30f3127 100644 --- a/lib/Table.cc +++ b/lib/Table.cc @@ -1,5 +1,8 @@ #include "Table.h" #include "HttpServ.h" +#include "CopyJob.h" +#include "Buffer.h" +#include "config.h" Table::Table(const String & titre, const String & url, String * heads, String * cells, int nbc, int nbl, Action * na) : Action(url), tit(titre), hds(heads), cls(cells), nc(nbc), nl(nbl), Next(na) { } @@ -8,34 +11,38 @@ String Table::GetTitle(void) { return tit; } -void Table::Do(Variables * v, Handle * h) { - SendHead(h); +Task * Table::Do(Variables * v, Handle * h) { + Handle * b = new Buffer(); + Task * t = new CopyJob(b, h, -1, true); + + SendHead(b); - (*h) << "<center><TABLE BORDER=0>" << endnl; + (*b) << "<center><TABLE BORDER=0>" << endnl; if (hds) { - (*h) << "<TR>" << endnl; + (*b) << "<TR>" << endnl; for (int i = 0; i < nc; i++) { - (*h) << "<TH BGCOLOR=\"#bbbbbb\">" << hds[i] << "</TH>" << endnl; + (*b) << "<TH BGCOLOR=\"#bbbbbb\">" << hds[i] << "</TH>" << endnl; } - (*h) << "</TR>" << endnl; + (*b) << "</TR>" << endnl; } for (int l = 0; l < nl; l++) { - (*h) << "<TR>" << endnl; + (*b) << "<TR>" << endnl; for (int c = 0; c < nc; c++) { - (*h) << "<TD BGCOLOR=\"#" << (l % 2 ? "cccccc" : "dddddd") << "\">" << cls[l * nc + c] << "</TD>" << endnl; + (*b) << "<TD BGCOLOR=\"#" << (l % 2 ? "cccccc" : "dddddd") << "\">" << cls[l * nc + c] << "</TD>" << endnl; } - (*h) << "</TR>" << endnl; + (*b) << "</TR>" << endnl; } - (*h) << "</TABLE>" + (*b) << "</TABLE>" "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl << "<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl; -(*h) << "</FORM></CENTER>" << endnl; +(*b) << "</FORM></CENTER>" << endnl; - - SendFoot(h); + SendFoot(b); Accessed(); + + return t; } diff --git a/lib/Task.cc b/lib/Task.cc index 063a983..4978bde 100644 --- a/lib/Task.cc +++ b/lib/Task.cc @@ -4,7 +4,7 @@ #include "Task.h" #include "String.h" -Task::Task() : state(TASK_ON_HOLD), suspended(false), current(0) { +Task::Task() : state(TASK_ON_HOLD), suspended(false), cleanup(false), current(0) { TaskMan::AddTask(this); } Task::~Task() { @@ -64,3 +64,27 @@ void Task::WaitFor(pid_t p) { void Task::WaitFor(timeval t) { w4to.push_back(t); } + +void Task::SetBurst() { + state = TASK_BURST; +} + +void Task::SetCleanUp() { + cleanup = true; +} + +bool Task::HasToClean() { + return cleanup; +} + +void Task::Stop() { + stopped = true; +} + +void Task::Restart() { + stopped = false; +} + +bool Task::IsStopped() { + return stopped; +} diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc index 479e25e..ded359a 100644 --- a/lib/TaskMan.cc +++ b/lib/TaskMan.cc @@ -13,7 +13,7 @@ static int nbprocess = 0; void taskman_sigchild(int sig) { got_sigchild = 1; - process.push_back(wait(NULL)); + process.push_back(wait(0)); signal(SIGCHLD, taskman_sigchild); nbprocess++; } diff --git a/src/Main.cc b/src/Main.cc index e712a95..9075f5d 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -3,6 +3,8 @@ #include <sys/types.h> #include <sys/wait.h> #include "Handle.h" +#include "Task.h" +#include "TaskMan.h" #include "HttpServ.h" #include "Socket.h" #include "config.h" @@ -30,7 +32,7 @@ class ad_t : public Action { ad_t() : Action("menu6") { } virtual ~ad_t() { } virtual String GetTitle() { return "Action dynamique"; } - virtual void Do(Variables * v, Handle * h) { + virtual Task * Do(Variables * v, Handle * h) { String ut, un; if (!fork()) { @@ -49,9 +51,10 @@ class ad_t : public Action { String("Vous avez choisi l'action dynamique. L'uptime de la machine est '") + ut + "' et sa définition complète est '" + un + "'", ""); - m->Do(v, h); + Task * t = m->Do(v, h); delete m; + return t; } }; Action * ad = new ad_t(); @@ -117,8 +120,8 @@ int main(int argc, char ** argv) { } try { - HttpServ h(port.to_int()); - h.MainLoop(buildmenu()); + HttpServ h(buildmenu(), port.to_int()); + TaskMan::MainLoop(); } catch (GeneralException e) { cerr << e.GetMsg() << endl; |