DRDE/APIG/client/commander.cpp

608 lines
16 KiB
C++

#include <ncurses.h>
#include "ausreg-cd.h"
#define ASSERT(expr) \
if (!(expr)) { \
std::cerr << __FILE__ << ":" << __LINE__ << ":" << #expr << std::endl;}
const char *banner = CD_NAME " " CD_VERSION " compiled on " __DATE__ " @ " __TIME__ " (%d/%d)";
char theBanner[256];
int targetHost = 0;
const char *xsdPath = "./resources";
const char *xmlPath = "./acInputQueue";
const char *xmlWork = "./xml";
mdDG mdg;
using namespace boost::interprocess;
extern shared_memory_object shm;
#include "eppargs.h"
int is_numeric(const char *p) { int i = strlen(p),j=0;
if (*p) {
char c;
while ((c=*p++)) { j++;
if (!isdigit(c)) {
if (j == i) return 2;
else return 0;
}
}
return 1;
}
return 0;
}
void mdCommander::doHeader() {
int displayCmd = cmdsNow ? cmdNow + 1 : 0;
clear();
mvprintw(0,(col-strlen(banner))/2,"%s",theBanner);
sprintf(wwork,"Target AC host: %d this one: %d commmands: %d current: %d",
targetHost,mdStdDevIdx,activeCommands,displayCmd);
mvprintw(1,(col-strlen(wwork))/2,"%s",wwork);
}
int mdCommander::selectArg() {
char legend1[80]="Arg types: ",selection[10];
int i, wrow=5;
for (i=0;i < eppArgs[commandsNow[cmdNow]].n;i++) {
sprintf(wwork," %d %s ",i+1,eppArgs[commandsNow[cmdNow]].names[i]);
strcat(legend1,wwork);
}
mvprintw(wrow,2,(char *)legend1);
say((char *)"Select arg string type");
prompt(true);
mvgetstr(row-1,2,selection);
thisArg = atoi(selection);
}
void mdCommander::getArgStringsByType() {
eppArgDef *sp1;
char buffer[256],*sp;
int i, nLines=0, wrow=7;
nocbreak();
for (;argsNow[cmdNow] < MAX_CMD_ARGS;)
{memset(buffer,0,sizeof(buffer));
mvgetstr(wrow++,2,buffer);
if (strlen(buffer)) {
sp1 = (eppArgDef *)malloc(sizeof(eppArgDef));
sp = (char *) malloc(strlen(buffer)+1);
sp1->name = commandsNow[cmdNow];
sp1->s = sp;
commandArgs[cmdNow][argsNow[cmdNow]++] = sp1;
strcpy(sp,buffer);
}
else break;
}
cbreak();
prompt(false);
}
void mdCommander::prompt(bool forStrings) {
if (forStrings)
mvprintw(row-1,1,">>");
else
mvprintw(row-1,1,">");
}
void mdCommander::driver() {
bool rc, x;
char next,rawString[128],work[128];
const char *mdErrCode = "";
int i,commandLength;
activeCommands = 0;
cmdNow = 0;
cmdsNow = 0;
initEPPArgs();
memset(commandsNow,0,sizeof(commandsNow));
memset(argsNow,0,sizeof(argsNow));
initscr();
cbreak();
getmaxyx(stdscr,row,col);
if (row < 30 || col < 80) {
std::cerr << "Terminal too small for AC commander.";
}
greet();
while(acceptingInput) {
refresh();
mvprintw(row-1,1,"> ");
next=0;
i=0;
memset(rawString,0,sizeof(rawString));
while(next != '\012') {
next = mvgetch(row-1,2+i);
rawString[i++] = next;
if (i > (sizeof(rawString) - 1)) {
say((char *)"Max length exceeded!");
continue;
}
if (next == '\012')
rawString[strlen(rawString)-1] = 0;
}
if (!strlen(rawString)) continue;
if (strlen(rawString) == 1) {
switch(rawString[0]) {
case '1': ; case '2': ; case '3': ; case '4': ; case '5': ;
case '6': ; case '7': ; case '8': ; case '9':
goto retarget ;
case 'q': goto quit;
case '!': runCommand(false);
break;
case '?': help();
break;
case 'e': eppMainMenu();
break;
case 'a': acMainMenu();
break;
case 'c': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
check(false);
break;
case 'p': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
poll(false);
break;
case 'i': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
info(false);
break;
case 't': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
queryTransfer(false);
break;
case 'C': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
create(false);
break;
case 'R': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
renew(false);
break;
case 'U': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
update(false);
break;
case 'D': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
trash(false);
break;
case 'T': commandsNow[(cmdNow=cmdsNow++)]; activeCommands++;
transfer(false);
break;
}
continue;
}
if (strlen(rawString) == 2) {
if (!strcmp(rawString,"??")) {
showCommand(true);
continue;
}
if (!strcmp(rawString,"!!")) {
runCommand(true);
continue;
}
}
if (is_numeric(rawString) >= 1) {
retarget:
targetHost = atoi(rawString);
doHeader();
continue;
}
if (is_numeric(rawString+1) >= 1) {
int targetCmd = atoi(rawString+1);
switch(rawString[0]) {
case 'C':
if (isValidCmd(targetCmd,false)) {
cmdNow = --targetCmd;
doHeader();}
else say((char *)"Invalid Command Index");
break;
case 'E':
if (isValidCmd(targetCmd,false)) {
cmdNow = --targetCmd;
editingCommand(false);
doHeader();}
help();
break;
case 'S':
if (isValidCmd(targetCmd,false)) {
cmdNow = --targetCmd;
sendCommand(cmdNow);
doHeader();
}
else say((char *)"Invalid Command Index");
break;
case 'X':
if (!targetCmd) {targetCmd = 0; x = true;}
else {targetCmd--; x = false;}
if (isValidCmd(targetCmd,true)) {
flushCommand(targetCmd,x);
doHeader();
}
else say((char *)"Invalid Command Index");
break;
}
continue;
}
if (strlen(rawString) >= 3 && strlen(rawString) <= 5 )
{if (!strcmp(rawString,"loG")) {
sprintf(wwork,"cut -b 1-%d /tmp/ausreg-cd.log | less",col);
system(wwork);
clear();
continue;
}
if (!strcmp(rawString,"log")) {
sprintf(wwork,"cut -b 1-%d /tmp/ausreg-cd-ui.log | less",col);
system(wwork);
clear();
continue;
}
if (!strcmp(rawString,"mlog")) {
sprintf(wwork,"cut -b 1-%d /tmp/drde-cliever.log | less",col);
system(wwork);
clear();
continue;
}
if (!strcmp(rawString,"done")) {
goto done;
}
if (!strcmp(rawString,"quit")) { quit:
thisConfig->terminateRequest = true;
sprintf(work,"kill -9 %d",thisConfig->daemonProcess);
system(work);
shm.remove("ausreg-cd-global");
sprintf(work,"rm /tmp/ausreg-cd.lock");
shm.remove("ausreg-cd-global");
sprintf(work,"rm /tmp/ausreg-cd-ui.log");
system(work);
sprintf(work,"rm /tmp/ausreg-cd.log");
system(work);
goto done;
}
continue;
}
}
done:
nocbreak();
endwin();
}
void mdCommander::say(char *what)
{ memset(wwork,' ',sizeof(wwork));
mvprintw(row-2,1,wwork);
mvprintw(row-2,1,what);
}
void mdCommander::greet() {
const char *title="AusReg Cliever Commander",
*warn="NB: this program is meant to be powerful and fast, not safe or user friendly",
*prompt="Enter ? or command",
*advise="Please rm /tmp/ausreg-cd.lock-when done so others can use on this host";
sprintf(theBanner,banner,thisConfig->shellProcess,thisConfig->daemonProcess);
mvprintw(0,(col-strlen(banner))/2,"%s",theBanner);
mvprintw(row/2,(col-strlen(title))/2,"%s",title);
mvprintw((row/2)+2,(col-strlen(warn))/2,"%s",warn);
mvprintw((row/2)+6,(col-strlen(advise))/2,"%s",advise);
mvprintw(row-2,1,"%s",prompt);
refresh();
acceptingInput = true;
}
void mdCommander::help() {
const char *prompt="Enter command";
doHeader();
mvprintw(5,10," a - AC system");
mvprintw(6,10," e - EPP ");
mvprintw(7,10," ? - this screen");
mvprintw(8,10," ?? - display commands");
mvprintw(9,10," ! - run ");
mvprintw(10,10," !! - run all active");
mvprintw(11,10," C<n> - make <n> the current command");
mvprintw(12,10," E<n> - display/edit <n> ");
mvprintw(13,10," W<n> - write <n> to ./acInputQueue*");
mvprintw(14,10," X<n> - discard ");
mvprintw(15,10," <n> - make <n> the target device");
mvprintw(16,10," loG - display this cd UI log");
mvprintw(17,10," log - display this cd daemon log*");
mvprintw(18,10," mlog - display the master daemon log");
mvprintw(19,10," done - terminate commander but not process");
mvprintw(20,10," q/quit - end process tree, delete log files");
mvprintw(22,5,"<n> is an integer, above active everywhere outside data entry (>>)");
mvprintw(23,5,"no space before <n>, X0/W0 to delete/write all commands.");
mvprintw(24,5,"*will be inaccessible if another user running cd on this computer.");
mvprintw(row-2,1,"%s",prompt);
refresh();
}
void mdCommander::eppMainMenu() {
doHeader();
mvprintw(5,10," Create a new EPP command");
mvprintw(7,10,"Queries");
mvprintw(8,10," c - check");
mvprintw(9,10," i - info");
mvprintw(10,10," p - poll");
mvprintw(11,10," t - transfer query");
mvprintw(12,10,"Transactions");
mvprintw(13,10," C - create");
mvprintw(14,10," R - renew");
mvprintw(15,10," U - update");
mvprintw(16,10," D - delete");
mvprintw(17,10," T - transfer");
mvprintw(19,10,"IO");
mvprintw(22,10," v<letter> - vi/xmledit the schema ");
mvprintw(23,10," w<letter> - write blank XML form for 1 above");
mvprintw(24,10," W - write blank forms for all");
mvprintw(8,50, "Commands are defined by the XSDs");
mvprintw(9,50, "in ./resources. These are migrating to");
mvprintw(11,50,"a what's at 'XML TO USE IN AC' @");
mvprintw(12,50,"dnseppus.meansofproduction.biz/doc, currently");
mvprintw(13,50,"a mix of that and those in the 2007 toolkit.");
mvprintw(15,50,"If no XSD loaded you'll see");
mvprintw(16,50,"stubs in the internal editor.");
say((char *)"Action letter or ? to exit");
}
void mdCommander::acMainMenu() {
char selection[10];
doHeader();
mvprintw(5,(col-strlen("AC System Directives"))/2,"AC System Directives");
mvprintw(15,10," (H)ALT - Flush queues, stop, ignore incoming requests");
mvprintw(16,10," (L)OAD - Resume execution, accept work");
mvprintw(17,10," (B)ANG - Force reload the entire AC system");
mvprintw(20,10,"Only active on this screen, there's no confirmation.");
say((char *)"Select Action letter or anything else to exit");
prompt(false);
mvgetstr(row-1,2,selection);
switch(selection[0]) {
case 'H':
break;
case 'L':
break;
case 'B':
break;
}
help();
}
bool sendEPPCommand() {
mdg.dg.hdr.sourceHandle = thisCliever->myHandle;
mdg.dg.hdr.payloadSize = 0;
mdg.dg.hdr.msgType = MDDG_CDRESET;
return thisCliever->fg->send(mdg.dg);
}
bool mdCommander::runCommand(bool allOfEm) {
bool value=false;
if (!activeCommands) {say((char *)"There is no active command."); goto done;}
say((char *)"Command execution temporarily disabled.");
done: return value;
}
//--------------------------------
void mdCommander::flushCommand(int which,bool allOfEm){
int i,j;
if (!allOfEm) {
if (argsNow[which]) {
for (i=0;i<argsNow[which];i++) {
free(commandArgs[which][i]->s);
free(commandArgs[which][i]);
}
}
argsNow[which] = 0;
deleted[which] = true;
activeCommands--;
} else for (i=0;i<cmdsNow;i++) {
if (!deleted[i]) {
if (argsNow[i]) {
for (j=0;j<argsNow[i];j++) {
free(commandArgs[i][j]->s);
free(commandArgs[i][j]);
}
}
else deleted[i] = false; // back to start state.
}
cmdNow = 0;
cmdsNow = 0;
activeCommands = 0;
memset(commandArgs,0,sizeof(commandArgs));
memset(argsNow,0,sizeof(argsNow));
}
};
void mdCommander::sendCommand(int which){
say((char *)"Command processing disabled here during OTE Basic Testing");
};
void mdCommander::showCommand(bool allOfEm){
int activethCommand=0,i,nthItem;
const char *befehlJetzt = cmdNames[commandsNow[cmdNow]];
doHeader();
if (!activeCommands) {say((char *)"There is no active command."); goto done;}
if (!allOfEm) {
sprintf(wwork,"EPP directive: %s",befehlJetzt);
mvprintw(5,2,wwork);
for (nthItem=0;nthItem < argsNow[cmdNow];nthItem++) {
ASSERT(commandArgs[cmdNow][nthItem]->s);
sprintf(wwork,"%d %s %s",nthItem+1,
eppArgs[commandsNow[cmdNow]].names[commandArgs[cmdNow][nthItem]->name],
(commandArgs[cmdNow][nthItem]->s));
mvprintw(7+nthItem,2,wwork);
}
} else {
mvprintw(5,2,"These commands are pending/active: ");
for ( i=0, nthItem=0; nthItem < cmdsNow;nthItem++ ) {
if (!deleted[nthItem]) {
sprintf(wwork,"%d %s %s",nthItem+1,cmdNames[commandsNow[nthItem]],commandArgs[nthItem][0]->s);
mvprintw(7+(i++),2,wwork);
}
}
}
done: return;
};
//--------------------------------
// EPP Queries and Commands
//-------------------------------
bool mdCommander::editingCommand(bool run){
const char *befehlJetzt = cmdNames[commandsNow[cmdNow]];
char sp[256],*spp;
eppArgDef *arg;
int editLine,length;
doHeader();
mvprintw(3,(col-strlen(befehlJetzt))/2,befehlJetzt);
if (!run) {
if (!argsNow[cmdNow]) {
selectArg();
say((char *)"Enter arg string(s), just enter to end");
getArgStringsByType();
} else {
nocbreak();
while(true) {
showCommand(false);
say((char *)"line no. to replace, A to add, enter to return");
prompt(false);
mvgetstr(row-1,2,sp);
if (!strlen(sp)) goto done;
if (*sp == 'A' || *sp == 'a') {
selectArg();
prompt(true);
mvgetstr(row-1,2,sp);
if (length=strlen(sp)) {
arg = (eppArgDef *)malloc(sizeof(eppArgDef));
commandArgs[cmdNow][argsNow[cmdNow]++] = arg;
spp = commandArgs[cmdNow][argsNow[cmdNow]++]->s = (char *) malloc(length+1);
strcpy(spp,sp);
}
}
if (is_numeric(sp) >= 1) {
editLine = atoi(sp);
if (editLine > 1 && editLine < argsNow[cmdNow]) {
prompt(true);
mvgetstr(row-1,2,sp);
if (length=strlen(sp)) {
free (commandArgs[cmdNow][editLine-1]->s);
spp = commandArgs[cmdNow][editLine-1]->s = (char *) malloc(strlen(sp)+1);
strcpy(spp,sp);
}
}
}
} // editing loop
done: cbreak();
} // editing block
} // run / execute
else {
say((char *)"Press 'Y' to confirm");
prompt(false);
mvgetstr(row-1,2,sp);
if (sp[0] == 'Y') return false;
}
return true;
};
//
// Wrappers for specific EPP commands.
//
void mdCommander::check(bool run) {
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 0;
if (!editingCommand(run)) {
} else help();
}
void mdCommander::create(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 4;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::info(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 1;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::renew(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 5;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::queryTransfer(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 3;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::trash(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 7;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::transfer(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 8;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::poll(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 2;
if (!editingCommand(run)) {
} else help();
};
void mdCommander::update(bool run){
if (!commandsNow[cmdNow]) commandsNow[cmdNow] = 6;
if (!editingCommand(run)) {
} else help();
};