/* Talk to the horizon program using the unix socket */ #include #include #include #include #include #include #include "fdpass.h" #include #include using namespace std; static int horizon_bind (const char *addr, const char *port) { int ret = -1; if (strcmp(addr,"unix")==0){ if (port[0] != '/'){ tlmp_error ("Unix socket must use absolute path\n"); }else{ ret = tcpserver_openunix(port); if (ret == -1) tlmp_error ("Can't setup UNIX socket on %s (%s)\n",port,strerror(errno)); } }else{ ret = tcpserver_opentcp(addr,port,true); if (ret == -1) tlmp_error ("Can't setup TCP socket on %s,%s (%s)\n",addr,port,strerror(errno)); } return ret; } int main (int argc, char *argv[]) { glocal const char *bind = NULL; glocal const char *port = "/var/run/blackhole/horizon.sock"; glocal bool silent = false; glocal int ret = -1; glocal.ret = (argc,argv); setproginfo ("horizon-control",VERSION ,"Send control command to the horizon server\n" "\n" "Commands are:\n" "\tallow ip\n" "\tconnections\n" "\tnameip ip name\n" "\tvserver name ip\n" "\tvserverdir name rootdirectory|-\n" "\n" "\tn_clear\n" "\tn_commit\n" "\tn_vserver name ip\n" "\tn_vserverdir name rootdirectory\n" "\n" "\tdebug 0|1\n" "\tdebugfile filename\n" "\tkill handle\n" "\tquit\n" "\treadsecrets\n" "\treseterror\n" "\tresetmaxconnect\n" "\tstatus\n" "\tunbindfd addr port name\n" "\n" "\tfindproc on|off\n" "\tfindprocport unixpath\n" ); setarg ('p',"port","Unix domain control port",glocal.port,false); setarg (' ',"bind","Bind a TCP socket and send it to the horizon server",glocal.bind,false); setarg ('s',"silent","Silent mode (mostly for --bind option)",glocal.silent,false); int ret = -1; if (glocal.bind != NULL){ // It is either: ip-addr,port,ipname or unix,[/logical-path:]/socket-path,vserver-name glocal string addr,tcpport,name; if (fdpass_splitbind (glocal.bind,glocal.addr,glocal.tcpport,glocal.name)!=-1){ // First we check if the horizon is already listening on this IP,port combination glocal string realport = glocal.tcpport; glocal string vaddr = glocal.addr; if (glocal.addr=="unix"){ glocal.vaddr = string_f ("unix/%s",glocal.name.c_str()); // We support a little trick to virtualise the unix socket // (actually hide the path of the vserver holding it) // If the port has a : inside, the first part is the logical // path and the second part is the real path vector tb; int n = str_splitline (glocal.tcpport.c_str(),':',tb); if (n == 2){ glocal.tcpport = tb[0]; glocal.realport = tb[1]; } } glocal string foundaddr; ret = ("unix:",glocal.port,5); send ("status\n"); if (strncmp(line,"listen ",7)==0){ vector tb; int n = str_splitline (line,' ',tb); if (n >= 4){ if ((glocal.vaddr == tb[2] || tb[2] == "0.0.0.0") && glocal.tcpport == tb[3]){ glocal.foundaddr = tb[2]; } } }else if (strcmp(line,"Ok")==0){ end = true; } if (glocal.foundaddr.size()>0){ if (!glocal.silent) printf ("Horizon is already listening on address %s port %s\n",glocal.foundaddr.c_str(),glocal.tcpport.c_str()); }else{ glocal int fd = horizon_bind (glocal.addr.c_str(),glocal.realport.c_str()); if (glocal.fd != -1){ ret = ("unix:",glocal.port,5); sendf ("bindfd %s %s %s\n",glocal.addr.c_str(),glocal.tcpport.c_str(),glocal.name.c_str()); if (strcmp(line,"waiting")==0){ if (fdpass_sendfd (info.handle,glocal.fd)==-1){ tlmp_error ("Can't send listening socket to the horizon server\n"); }else{ if (!glocal.silent) printf ("horizon now listening on address %s port %s\n",glocal.addr.c_str(),glocal.tcpport.c_str()); } end = true; }else if (strcmp(line,"Ok")==0){ end = true; }else{ printf ("%s\n",line); } } } } }else{ usage(); } return ret; glocal SSTRING cmd; for (int i=0; i0) glocal.cmd.append (' '); glocal.cmd.append (argv[i]); } int ret = -1; ret = ("unix:",glocal.port,5); sendf ("%s\n",glocal.cmd.c_str()); if (strcmp(line,"Ok")==0){ end = true; }else{ printf ("%s\n",line); } return ret; return glocal.ret; }