/* This file is part of Bolixo. Bolixo 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 3 of the License, or (at your option) any later version. Bolixo 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 Bolixo. If not, see . */ /* Command line tool to control documentd */ #include #include #include #include #include #include #include #include "bolixo.m" using namespace std; #include "bolixo.h" #include "proto/bod_client.protodef" #include "proto/documentd_control.protoch" #define bod_control_status_NOTNEED #define bod_control_quit_NOTNEED #define bod_control_debug_NOTNEED #define bod_control_debugfile_NOTNEED #define bod_control_helptest_NOTNEED #define bod_control_publishemail_NOTNEED #define bod_control_help_connect_NOTNEED #define bod_control_nodelogin_NOTNEED #define bod_control_nodelogout_NOTNEED #define bod_control_instrument_NOTNEED #define bod_control_keepmsgs_NOTNEED #define bod_control_erase_session_NOTNEED #define bod_control_set_admin_session_NOTNEED #define bod_control_slowplaystep_NOTNEED #include "proto/bod_control.protoch" int main (int argc, char *argv[]) { glocal int ret = -1; glocal const char *control = "/var/lib/lxc/documentd/rootfs/var/run/blackhole/documentd.sock"; glocal const char *bod_control = "/var/lib/lxc/bod/rootfs/var/run/blackhole/bod-2.sock"; glocal unsigned idle_time = 60*60; // One hour glocal bool force = false; glocal.ret = (argc,argv,"bolixo"); setproginfo ("documentd-control",VERSION ,MSG_U(I_DOCUMENTD_CONTROL ,"Command line tool to control documentd\n" "\n" "\tchessmaxskill 1-5\n" "\tdebug 0/1\n" "\tdebugfile filename\n" "\tdeleteoldgames\n" "\tendgame gameid revision\n" "\tendgames\n" "\tinstrument 0|1\n" "\tlistgames\n" "\tplaystep gameid command=value ...\n" "\tprotocolstats 0|1\n" "\tquit\n" "\tresetgame gameid\n" "\tsetflag flag value\n" "\tstatus\n" "\tstartgame gameid\n" )); setarg ('p',"control","Unix socket to reach documentd",glocal.control,false); setarg (' ',"bod-control","Unix socket to reach bod",glocal.bod_control,false); setarg (' ',"idle-time","Idle time for a game (deleted after that)",glocal.idle_time,false); setarg (' ',"force","Force endgame (for endgame and deleteoldgames)",glocal.force,false); glocal int ret = -1; glocal CONNECT_INFO con; glocal CONNECT_INFO con_bod; glocal.con.port = glocal.control; glocal.con_bod.port = glocal.bod_control; if (strcmp(argv[0],"status")==0 && argc==1){ (glocal.con); if (!internal_error) glocal.ret = 0; for (auto x:lines) printf ("%s\n",x); }else if (strcmp(argv[0],"listgames")==0 && argc==1){ (glocal.con); if (!internal_error) glocal.ret = 0; for (auto x:stats){ printf ("gameid=%s modified=%u modified_by=%s last_activity=%u revision=%u\n" ,x.gameid,x.modified,x.modified_by,x.last_activity,x.revision); } }else if (strcmp(argv[0],"deleteoldgames")==0 && argc==1){ for (unsigned i=0; i<2; i++){ (glocal.con); if (!internal_error) glocal.ret = 0; time_t old_now = time(nullptr) - glocal.idle_time; for (auto x:stats){ glocal bool delete_ok = true; glocal const char *gameid = x.gameid; if (x.modified != 0 && x.modified < old_now){ // It was modified some time ago, must be saved using bod (glocal.con_bod,x.gameid); if (!success){ tlmp_error (MSG_U(E_FAILSAVEGAME,"Can't save document/game %s: %s\n") ,glocal.gameid,msg); glocal.delete_ok = false; } } if (glocal.force || (glocal.delete_ok && x.last_activity < old_now)){ // This game/document has not been accessed for some time // We delete the game. The revision obtained by listgame // must match when the deletion is executed in documentd. // If it does not match, it means the game was modified // while we were saving. So endgame fails. // But failure is not a problem. The game continue to // exist in documentd. glocal const char *gameid = x.gameid; (glocal.con,x.gameid,x.revision,glocal.force); if (!success) tlmp_error ("deleteoldgames: can't delete %s: %s\n",glocal.gameid,msg); } } } }else if (strcmp(argv[0],"quit")==0 && argc==1){ (glocal.con); if (!internal_error) glocal.ret = 0; }else if (strcmp(argv[0],"debug")==0 && argc==2){ (glocal.con,atoi(argv[1])); }else if (strcmp(argv[0],"debugfile")==0 && argc==2){ (glocal.con,argv[1]); }else if (strcmp(argv[0],"load")==0 && argc == 2){ (glocal.con,argv[1]); printf ("success=%d msg=%s\n",success,msg); }else if (strcmp(argv[0],"save")==0 && argc == 2){ (glocal.con,argv[1]); printf ("success=%d msg=%s\n",success,msg); }else if (strcmp(argv[0],"startgame")==0 && argc == 3){ (glocal.con,argv[1],argv[2]); printf ("success=%d msg=%s\n",success,msg); }else if (strcmp(argv[0],"endgame")==0 && argc == 3){ (glocal.con,argv[1],atoi(argv[2]),glocal.force); printf ("success=%d msg=%s\n",success,msg); }else if (strcmp(argv[0],"endgames")==0 && argc == 1){ (glocal.con); }else if (strcmp(argv[0],"resetgame")==0 && argc == 2){ (glocal.con,argv[1]); printf ("success=%d msg=%s\n",success,msg); }else if (strcmp(argv[0],"playstep")==0 && argc > 2){ vector args; for (int i=2; i(glocal.con,argv[1],args); if (!success){ printf ("success=%d unknown=%d msg=%s\n",success,unknown,msg); }else{ for (auto &r:res){ if (strcmp(r.var,"content")==0){ printf ("Content:\n%s\n",r.val); }else{ printf ("var=%s val=%s\n",r.var,r.val); } } } }else if (strcmp(argv[0],"instrument")==0 && argc==2){ (glocal.con,atoi(argv[1])); }else if (strcmp(argv[0],"protocolstats")==0 && argc==2){ (glocal.con,atoi(argv[1])); }else if (strcmp(argv[0],"chessmaxskill")==0 && argc==2){ (glocal.con,atoi(argv[1])); }else if (strcmp(argv[0],"setflag")==0 && argc==3){ (glocal.con,argv[1],argv[2]); }else{ tlmp_error ("Invalid command: %s\n",argv[0]); usage(); } return glocal.ret; return glocal.ret; }