From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/net/htcd.cc | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/net/htcd.cc (limited to 'src/net/htcd.cc') diff --git a/src/net/htcd.cc b/src/net/htcd.cc new file mode 100644 index 0000000..89729e6 --- /dev/null +++ b/src/net/htcd.cc @@ -0,0 +1,153 @@ +/************************************************************************* + * + * 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 + +static fp_stream merr(stderr); + +static mstring PATH; +static htcServ* SERV; + +const mstring PIDURI="/sys/htcd"; + +const int BACKLOG=4; +const int SERVERS=9; +const int LOWER=3; +const int UPPER=6; +const int KEEPALIVE=300; +const int SNDBUFSIZE=16384; +const int RCVBUFSIZE=16384; + +/////////////////////////////////////////////////////////// + +static thrServ* server[SERVERS]; +static thrCron* crontab; + +extern "C" { + static void* thr_handler(void* p) { ((thrServ*)p)->enter(); return 0; } + static void* thr_cron(void* p) { ((thrCron*)p)->enter(); return 0; } + static void onTERM(int sig) { SERV->htcd.running=0; } + static void onHUP(int sig) { if(crontab) crontab->running=0; } + typedef void (*disp_t)(int); +} + +static void MainProc(isocket& sock) +{ + int keep=1; + while(SERV->htcd.running) { + int nvacant=0; for(int i=0;ivacant()) nvacant++; + if(nvacant>UPPER) keep=1; else if(nvacant<=LOWER) keep=0; + if(!keep) for(int i=0;ishutdown(); + time_t timeout=time(0)-KEEPALIVE; + for(int i=0;iserver[i]->last) server[i]->disconnect(); + int test=sock.test(); + if(test>0) { + thrServ* p=0; + for(int i=0;ivacant()) { p=server[i]; break; } + if(!p) for(int i=0;ifirstfirst) p=server[i]; + if(p->shutdown()) { + try { + isocket* s=sock.accept(); + if(s) p->reset(s,keep); + } + catch(const merror_t& e) { + merr<<"SOCKET: "<htcd.running=0; + } + for(int i=0;iterm(); + pthread_join(server[i]->ptid,0); + } + pthread_kill(crontab->tid,SIGHUP); + pthread_join(crontab->ptid,0); +} + +/////////////////////////////////////////////////////////////// + +static void httpServer(int overport) +{ + isocket sock(SERV->htcd.node.addr,overport,BACKLOG); + sock.keepalive(1); + sock.sendbufsize(SNDBUFSIZE); + sock.recvbufsize(RCVBUFSIZE); + + sigignore(SIGPIPE); + disp_t onterm=signal(SIGTERM,onTERM); + disp_t onint=signal(SIGINT,onTERM); + disp_t onhup=signal(SIGHUP,onHUP); + MainProc(sock); + signal(SIGHUP,onhup); + signal(SIGINT,onint); + signal(SIGTERM,onterm); +} + +static void Daemon(int overport) try +{ + PROCLOCK(PATH+PIDURI); + SERV=new htcServ(PATH); + crontab=new thrCron(*SERV); + pthread_create(&crontab->ptid,0,thr_cron,crontab); + for(int i=0;iptid,0,thr_handler,server[i]); + } + merr<<"htcd: "<htcd.port:overport); + merr<<"htcd: "<htcd.errlog<<"["<htcd.errlog<<"["< [-1|0|1]\n"; + return -1; + } + PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb(); + setenv("DOCROOT",PATH.c_str(),1); + int overport=atoi(argv[2]); + int cmd=argc>3?atoi(argv[3]):0; + if(cmd) ProcTerminate(PATH+PIDURI); + if(cmd>=0) { if(fork()==0) Daemon(overport); } + delete SERV; + return 0; +} +catch(const merror_t& e) { + merr<<"ERROR: ["<