/************************************************************************* * * HTCd - Copyright (C) 1998-2006 Henrik Rydberg * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include static fp_stream merr(stderr); static IPnode NODE; static int PORT; static mstring URL,PATH,SERVER,URL1,URL2; static int volatile RUNNING; const mstring REDIRECT="/tmp/redirect."; const int BACKLOG=4; const int SNDBUFSIZE=16384; const int RCVBUFSIZE=16384; const int MAXHEAD=16384; const int SAFEZONE=4096; static void BreakURL() { static const mstring pre="//"; int p=URL.find(pre); if(p>=0) { p+=pre.size(); int q=p+URL.right(p).find('/'); if(q>=p) { URL1=URL.left(q); URL2=URL.right(q); } else { URL1=URL; URL2.clear(); } } else throw(0); } static mstring Combine(const sref& uri) { const int ncvt=3; static const mstring cvt[ncvt]={"/BODY","/en","/sv"}; mstring d=uri; mstring s=URL1; for(int i=0;i=0) { d.erase(p,cvt[i].size()); s+=cvt[i]; } } s+=URL2; s+=d; return s; } static int Handle(isocket& sock) { mstring buffer(MAXHEAD+SAFEZONE); int nhead=sock.gethead(buffer.data(),MAXHEAD); if(nhead<=0) return 0; httpReq req(sref(buffer.data(),nhead)); httpResp resp; resp.status=HTTP_301; //resp.location=URL+req.uri; resp.location=Combine(req.uri); if(req.arg.nempty()) { resp.location.append(1,'?'); resp.location+=req.arg; } resp.putHead(sock); putend(sock); sock.close(); return 1; } /////////////////////////////////////////////////////////////// extern "C" { static void onTERM(int sig) { RUNNING=0; } typedef void (*disp_t)(int); } static void MainProc(isocket& sock) { RUNNING=1; while(RUNNING) { int test=sock.test(); if(test>0) { try { isocket* s=sock.accept(); if(s) Handle(*s); } catch(const merror_t& e) { merr<<"SOCKET: "< "< [-1|0|1]\n"; return -1; } sref s(argv[1]); mstring host=s.left_last(':'); mstring sport=s.past_last(':'); if(sport.empty()) { sport=host; host.clear(); } PORT=atoi(sport); URL=argv[2]; if(URL.back()=='/') URL=URL.popb(); BreakURL(); if(host.empty()) { struct utsname u; uname(&u); host=u.nodename; } Lookup(NODE,host); SERVER=NODE.name; SERVER.append(1,'-'); SERVER+=itoa(PORT); PATH=REDIRECT; PATH+=SERVER; int cmd=argc>3?atoi(argv[3]):0; if(cmd) ProcTerminate(PATH); if(cmd>=0) { if(fork()==0) Daemon(); } return 0; } catch(const merror_t& e) { merr<<"ERROR: ["<