DRDE/APIG/client/commander.cpp

663 lines
18 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"
#include "eppxml.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() {
bool didSelect = false;
char legend1[80]="Elements: ",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);
while (!didSelect) {
say((char *)"Select element to edit");
prompt(true);
mvgetstr(row-1,2,selection);
thisArg = atoi(selection);
if (thisArg >= 1 and thisArg <= eppArgs[commandsNow[cmdNow]].n + 1)
didSelect = true;
else beep();
} -
thisArg--;
}
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, eppMainActive =false;
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) { beep();
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)) { beep();
say((char *)"Max length exceeded!");
continue;
}
if (next == '\012')
rawString[strlen(rawString)-1] = 0;
}
if (!strlen(rawString)) continue;
if (eppMainActive) {
int ion,nAll; char cmdChars[9] = {'c','i','p','t','C','R','U','D','T'};
eppMainActive = false;
switch(rawString[0]) {
case '?': help();
break;
case 'L':
for (nAll=0;nAll<6;nAll++)
if (loadSchema(nAll)) beep();
break;
case 'W':
for (nAll=0;nAll<9;nAll++)
writeCommand(cmdChars[nAll]);
break;
case 'V':
ion=atoi(&rawString[1]);
viSchema(ion);
break;
case 'l':
ion=atoi(&rawString[1]);
if (loadSchema(ion)) beep();
break;
case 'w':
writeCommand(rawString[1]);
break;
case 'v':
viBlankForm(rawString[1]);
break;
default: beep();
break;
}
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();
eppMainActive = true;
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 {beep(); 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"); beep();}
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,"tkvi")) { char *lastLog="./logs/lastLog";
sprintf(wwork,"vim %s",lastLog);
system(wwork);
clear();
continue;
}
if (!strcmp(rawString,"done")) {
goto done;
}
if (!strcmp(rawString,"quit")) { quit:
thisConfig->terminateRequest = true;
if (thisConfig->daemonProcess > 2) {
sprintf(work,"kill -9 %d",thisConfig->daemonProcess);
system(work); }
shm.remove("ausreg-cd-global");
sprintf(work,"rm /tmp/ausreg-cd.lock");
system(work);
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";
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,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 - cd UI log");
mvprintw(17,10," log - cd daemon log*");
mvprintw(18,10," mlog - master daemon log");
mvprintw(19,10," tkvi - xmledit ./logs/lastLog (last toolkit log)");
mvprintw(20,10," done - terminate commander but not process");
mvprintw(21,10," q/quit - end process tree, delete log files");
mvprintw(23,5,"<n> is an integer, above active everywhere outside data entry (>>)");
mvprintw(24,5,"no space before <n>, X0/W0 to delete/write all commands.");
mvprintw(25,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 (active this screen only)");
mvprintw(20,10," l<n> - load the schema");
mvprintw(21,10," L - load ./resources/*");
mvprintw(22,10," w<letter> - write blank XML form for 1 above ... ");
mvprintw(23,10," W - or all to ./xml.");
mvprintw(24,10," v<letter> - vi/xmledit a blank XML form");
mvprintw(25,10," V<n> - vi/xmledit a XSDs");
mvprintw(7,50, "Commands are defined by the XSDs");
mvprintw(8,50, "in ./resources. These are being migrated from");
mvprintw(9,50,"what was in in the 2007 toolkit to.");
mvprintw(10,50, "what's at the 'XML TO USE IN AC' link @");
mvprintw(11,50,"dnseppus.meansofproduction.biz/doc,.");
mvprintw(13,50,"If no XSD loaded you'll see");
mvprintw(14,50,"stubs in the internal editor.");
mvprintw(16,50," n = 1 : epp-1.0.xsd 2: domain-1-0.xsd 3: contact-1.0.xsd");
mvprintw(17,50," 4: registrant-1.0.xsd 5: host-1-0.xsd 6: kv-1.0.xsd");
say((char *)"Action sequence 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();
sprintf(sp,"Enter strings for '%s', enter to end",eppArgs[commandsNow[cmdNow]].names[thisArg]);
say(sp);
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();
};