#include #include #include #include #include #include #include #include "trlitool.h" #include using namespace std; enum CONNECT_TYPE { TYPE_NONE, TYPE_CONTROL, TYPE_CLIENT }; struct HANDLE_INFO: public ARRAY_OBJ{ CONNECT_TYPE type; bool ok_sent; REQUEST_INFO req; string host; HANDLE_INFO(){ ok_sent = false; type = TYPE_NONE; } }; #include "proto/trli_stop_control.protoh" /* Count the number of web request who have received the OK from this server (So is currently processing) */ static unsigned count_nbalive (_F_TCPSERVER_V1 *c, unsigned &nbcon) { unsigned nbalive = 0; nbcon = 0; void *data; int fd = c->iter_init (data); while (fd != -1){ HANDLE_INFO *n = (HANDLE_INFO*)data; if (n->type == TYPE_CLIENT){ nbcon++; if (n->ok_sent){ nbalive++; } } fd = c->iter_next(data); } return nbalive; } static unsigned count_nbalive (_F_TCPSERVER_V1 *c) { unsigned nbcon; return count_nbalive (c,nbcon); } int main (int argc, char *argv[]) { glocal int ret = -1; glocal bool daemon = false; glocal const char *control = "/var/run/trli-stop.sock"; glocal const char *pidfile = "/var/run/trli-stop.pid"; glocal const char *user = "trli"; glocal.ret = (argc,argv); setproginfo ("trli-stop",VERSION,"Control web traffic"); setarg ('d',"daemon","Run in backgroup",glocal.daemon,false); setarg ('u',"user","Run as this user",glocal.user,false); setarg ('p',"control","Unix socket for control",glocal.control,false); setarg (' ',"pidfile","PID file",glocal.pidfile,false); if (glocal.daemon){ syslog (LOG_ERR,"%s",msg); }else{ fprintf (stderr,"%s",msg); } if (glocal.daemon){ syslog (LOG_WARNING,"%s",msg); }else{ fprintf (stderr,"%s",msg); } int ret = -1; glocal bool run = true; glocal unsigned nbrequest = 0; const char *unixsock = "/tmp/stop.sock"; (string_f("unix:%s",unixsock),5); HANDLE_INFO *n = new HANDLE_INFO; info.data = n; if (strncmp(info.port,"unix:",5)==0 && strcmp(info.port+5,glocal.control)==0){ n->type = TYPE_CONTROL; }else{ glocal.nbrequest++; n->type = TYPE_CLIENT; settcpnodelay(true); if (glocal.run){ n->ok_sent = true; sendf ("ok\n"); } } HANDLE_INFO *c = (HANDLE_INFO*)info.data; debug_printf ("linelen=%d type=%d\n",info.linelen,c->type); if (c->type == TYPE_CONTROL){ (this,c->req,line,info.linelen, endserver, endclient, no,c,c->host.c_str()); vector tb; tb.push_back(string_f("Version %s",VERSION)); tb.push_back(string_f("nbrequest %u",glocal.nbrequest)); unsigned nbcon; unsigned alive = count_nbalive(&glocal.TCPSERVER,nbcon); tb.push_back(string_f("nbcon=%u",nbcon)); tb.push_back(string_f("nbalive=%u",alive)); tb.push_back(string_f("run=%d",glocal.run)); rep_status(tb); endserver = true; if (on){ debug_seton(); }else{ debug_setoff(); } debug_setfdebug (filename); glocal.run = false; rep_stop (count_nbalive(&glocal.TCPSERVER)); glocal.run = false; rep_nbalive (count_nbalive(&glocal.TCPSERVER)); glocal.run = true; // We must unlock the processes waiting void *data; int fd = glocal.TCPSERVER.iter_init (data); while (fd != -1){ HANDLE_INFO *n = (HANDLE_INFO*)data; if (n->type == TYPE_CLIENT && !n->ok_sent){ glocal.TCPSERVER.sendto (fd,"Ok\n"); n->ok_sent = true; } fd = glocal.TCPSERVER.iter_next(data); } tlmp_error ("Invalid command\n"); endclient = true; }else{ tlmp_error ("Can't receive stuff from client\n"); endclient = true; } if (o.is_ok()){ if (fdpass_setcontrol(o,glocal.control,glocal.user)!=-1){ chmod (glocal.control,0666); chmod (unixsock,0666); if (glocal.daemon){ daemon_init(glocal.pidfile,glocal.user); } o.setrawmode(true); o.loop(); ret = 0; } } return ret; return glocal.ret; }