608 lines
16 KiB
C++
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(10,50,"a what's at 'XML TO USE IN AC' @");
|
|
mvprintw(11,50,"dnseppus.meansofproduction.biz/doc, currently");
|
|
mvprintw(12,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();
|
|
};
|
|
|