mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
remote debug console
This commit is contained in:
parent
0f0a82b8b1
commit
36c5a5c62b
9 changed files with 201 additions and 47 deletions
|
@ -182,6 +182,12 @@ bool Action::setBreakPoint(uint4 tp,const string &specify)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Action::clearBreakPoints(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
breakpoint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// If enabled, a warning will be printed whenever this action applies.
|
/// If enabled, a warning will be printed whenever this action applies.
|
||||||
/// The warning can be toggled for \b this Action or some sub-action by
|
/// The warning can be toggled for \b this Action or some sub-action by
|
||||||
/// specifying its name.
|
/// specifying its name.
|
||||||
|
@ -371,6 +377,15 @@ void ActionGroup::addAction(Action *ac)
|
||||||
list.push_back(ac);
|
list.push_back(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionGroup::clearBreakPoints(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<Action *>::const_iterator iter;
|
||||||
|
for(iter=list.begin();iter!= list.end();++iter)
|
||||||
|
(*iter)->clearBreakPoints();
|
||||||
|
Action::clearBreakPoints();
|
||||||
|
}
|
||||||
|
|
||||||
Action *ActionGroup::clone(const ActionGroupList &grouplist) const
|
Action *ActionGroup::clone(const ActionGroupList &grouplist) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -870,6 +885,15 @@ int4 ActionPool::apply(Funcdata &data)
|
||||||
return 0; // Indicate successful completion
|
return 0; // Indicate successful completion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionPool::clearBreakPoints(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<Rule *>::const_iterator iter;
|
||||||
|
for(iter=allrules.begin();iter!=allrules.end();++iter)
|
||||||
|
(*iter)->clearBreakPoints();
|
||||||
|
Action::clearBreakPoints();
|
||||||
|
}
|
||||||
|
|
||||||
Action *ActionPool::clone(const ActionGroupList &grouplist) const
|
Action *ActionPool::clone(const ActionGroupList &grouplist) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,7 @@ public:
|
||||||
virtual void printStatistics(ostream &s) const; ///< Dump statistics to stream
|
virtual void printStatistics(ostream &s) const; ///< Dump statistics to stream
|
||||||
int4 perform(Funcdata &data); ///< Perform this action (if necessary)
|
int4 perform(Funcdata &data); ///< Perform this action (if necessary)
|
||||||
bool setBreakPoint(uint4 tp,const string &specify); ///< Set a breakpoint on this action
|
bool setBreakPoint(uint4 tp,const string &specify); ///< Set a breakpoint on this action
|
||||||
|
virtual void clearBreakPoints(void); ///< Clear all breakpoints set on \b this Action
|
||||||
bool setWarning(bool val,const string &specify); ///< Set a warning on this action
|
bool setWarning(bool val,const string &specify); ///< Set a warning on this action
|
||||||
bool disableRule(const string &specify); ///< Disable a specific Rule within \b this
|
bool disableRule(const string &specify); ///< Disable a specific Rule within \b this
|
||||||
bool enableRule(const string &specify); ///< Enable a specific Rule within \b this
|
bool enableRule(const string &specify); ///< Enable a specific Rule within \b this
|
||||||
|
@ -147,6 +148,7 @@ public:
|
||||||
ActionGroup(uint4 f,const string &nm) : Action(f,nm,"") {} ///< Construct given properties and a name
|
ActionGroup(uint4 f,const string &nm) : Action(f,nm,"") {} ///< Construct given properties and a name
|
||||||
virtual ~ActionGroup(void); ///< Destructor
|
virtual ~ActionGroup(void); ///< Destructor
|
||||||
void addAction(Action *ac); ///< Add an Action to the group
|
void addAction(Action *ac); ///< Add an Action to the group
|
||||||
|
virtual void clearBreakPoints(void);
|
||||||
virtual Action *clone(const ActionGroupList &grouplist) const;
|
virtual Action *clone(const ActionGroupList &grouplist) const;
|
||||||
virtual void reset(Funcdata &data);
|
virtual void reset(Funcdata &data);
|
||||||
virtual void resetStats(void);
|
virtual void resetStats(void);
|
||||||
|
@ -216,6 +218,7 @@ public:
|
||||||
uint4 getNumApply(void) { return count_apply; } ///< Get number of successful applications
|
uint4 getNumApply(void) { return count_apply; } ///< Get number of successful applications
|
||||||
void setBreak(uint4 tp) { breakpoint |= tp; } ///< Set a breakpoint on \b this Rule
|
void setBreak(uint4 tp) { breakpoint |= tp; } ///< Set a breakpoint on \b this Rule
|
||||||
void clearBreak(uint4 tp) { breakpoint &= ~tp; } ///< Clear a breakpoint on \b this Rule
|
void clearBreak(uint4 tp) { breakpoint &= ~tp; } ///< Clear a breakpoint on \b this Rule
|
||||||
|
void clearBreakPoints(void) { breakpoint = 0; } ///< Clear all breakpoints on \b this Rule
|
||||||
void turnOnWarnings(void) { flags |= warnings_on; } ///< Enable warnings for \b this Rule
|
void turnOnWarnings(void) { flags |= warnings_on; } ///< Enable warnings for \b this Rule
|
||||||
void turnOffWarnings(void) { flags &= ~warnings_on; } ///< Disable warnings for \b this Rule
|
void turnOffWarnings(void) { flags &= ~warnings_on; } ///< Disable warnings for \b this Rule
|
||||||
bool isDisabled(void) const { return ((flags & type_disable)!=0); } ///< Return \b true if \b this Rule is disabled
|
bool isDisabled(void) const { return ((flags & type_disable)!=0); } ///< Return \b true if \b this Rule is disabled
|
||||||
|
@ -266,6 +269,7 @@ public:
|
||||||
ActionPool(uint4 f,const string &nm) : Action(f,nm,"") {} ///< Construct providing properties and name
|
ActionPool(uint4 f,const string &nm) : Action(f,nm,"") {} ///< Construct providing properties and name
|
||||||
virtual ~ActionPool(void); ///< Destructor
|
virtual ~ActionPool(void); ///< Destructor
|
||||||
void addRule(Rule *rl); ///< Add a Rule to the pool
|
void addRule(Rule *rl); ///< Add a Rule to the pool
|
||||||
|
virtual void clearBreakPoints(void);
|
||||||
virtual Action *clone(const ActionGroupList &grouplist) const;
|
virtual Action *clone(const ActionGroupList &grouplist) const;
|
||||||
virtual void reset(Funcdata &data);
|
virtual void reset(Funcdata &data);
|
||||||
virtual void resetStats(void);
|
virtual void resetStats(void);
|
||||||
|
|
|
@ -17,44 +17,46 @@
|
||||||
#include "flow.hh"
|
#include "flow.hh"
|
||||||
#include "blockaction.hh"
|
#include "blockaction.hh"
|
||||||
|
|
||||||
#ifdef OPACTION_DEBUG
|
#ifdef __REMOTE_SOCKET__
|
||||||
|
|
||||||
#include "ifacedecomp.hh"
|
#include "ifacedecomp.hh"
|
||||||
|
|
||||||
static IfaceStatus *ghidra_dcp = (IfaceStatus *)0;
|
static IfaceStatus *ghidra_dcp = (IfaceStatus *)0;
|
||||||
|
static RemoteSocket *remote = (RemoteSocket *)0;
|
||||||
|
|
||||||
void turn_on_debugging(Funcdata *fd)
|
/// \brief Establish a debug console for decompilation of the given function
|
||||||
|
///
|
||||||
|
/// Attempt to connect to a UNIX domain socket and direct the i/o streams to
|
||||||
|
/// the decompiler console interface. The socket must have been previously established
|
||||||
|
/// by another process.
|
||||||
|
/// From the command-line, `nc -l -U /tmp/ghidrasocket` for example.
|
||||||
|
void connect_to_console(Funcdata *fd)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (ghidra_dcp == (IfaceStatus *)0) {
|
if (remote == (RemoteSocket *)0) {
|
||||||
ghidra_dcp = new IfaceStatus("[ghidradbg]> ",cin,cout);
|
remote = new RemoteSocket();
|
||||||
ghidra_dcp->optr = (ostream *)0;
|
if (remote->open("/tmp/ghidrasocket")) {
|
||||||
ghidra_dcp->fileoptr = (ostream *)0;
|
ghidra_dcp = new IfaceStatus("[ghidradbg]> ",*remote->getInputStream(),*remote->getOutputStream());
|
||||||
IfaceCapability::registerAllCommands(ghidra_dcp);
|
IfaceCapability::registerAllCommands(ghidra_dcp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check if debug script exists
|
if (!remote->isSocketOpen())
|
||||||
ifstream is("ghidracom.txt");
|
return;
|
||||||
if (!is) return;
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
IfaceDecompData *decomp_data = (IfaceDecompData *)ghidra_dcp->getData("decompile");
|
IfaceDecompData *decomp_data = (IfaceDecompData *)ghidra_dcp->getData("decompile");
|
||||||
decomp_data->fd = fd;
|
decomp_data->fd = fd;
|
||||||
decomp_data->conf = fd->getArch();
|
decomp_data->conf = fd->getArch();
|
||||||
ghidra_dcp->pushScript("ghidracom.txt","ghidradbg> ");
|
ostream *oldPrintStream = decomp_data->conf->print->getOutputStream();
|
||||||
ghidra_dcp->optr = new ofstream("ghidrares.txt");
|
bool emitXml = decomp_data->conf->print->emitsXml();
|
||||||
ghidra_dcp->fileoptr = ghidra_dcp->optr;
|
decomp_data->conf->print->setOutputStream(remote->getOutputStream());
|
||||||
decomp_data->conf->setDebugStream(ghidra_dcp->optr);
|
decomp_data->conf->print->setXML(false);
|
||||||
|
ghidra_dcp->reset();
|
||||||
mainloop(ghidra_dcp);
|
mainloop(ghidra_dcp);
|
||||||
ghidra_dcp->popScript();
|
decomp_data->conf->clearAnalysis(fd);
|
||||||
}
|
decomp_data->conf->print->setOutputStream(oldPrintStream);
|
||||||
|
decomp_data->conf->print->setXML(emitXml);
|
||||||
void turn_off_debugging(Funcdata *fd)
|
fd->debugDisable();
|
||||||
|
decomp_data->conf->allacts.getCurrent()->clearBreakPoints();
|
||||||
{
|
|
||||||
if (ghidra_dcp->optr != (ostream *)0) {
|
|
||||||
delete ghidra_dcp->optr;
|
|
||||||
ghidra_dcp->optr = (ostream *)0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,9 +215,13 @@ void DeregisterProgram::loadParameters(void)
|
||||||
void DeregisterProgram::rawAction(void)
|
void DeregisterProgram::rawAction(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef OPACTION_DEBUG
|
#ifdef __REMOTE_SOCKET__
|
||||||
if (ghidra_dcp != (IfaceStatus *)0)
|
if (ghidra_dcp != (IfaceStatus *)0)
|
||||||
delete ghidra_dcp;
|
delete ghidra_dcp;
|
||||||
|
if (remote != (RemoteSocket *)0)
|
||||||
|
delete remote;
|
||||||
|
ghidra_dcp = (IfaceStatus *)0;
|
||||||
|
remote = (RemoteSocket *)0;
|
||||||
#endif
|
#endif
|
||||||
if (ghidra != (ArchitectureGhidra *)0) {
|
if (ghidra != (ArchitectureGhidra *)0) {
|
||||||
res = 1;
|
res = 1;
|
||||||
|
@ -284,14 +290,11 @@ void DecompileAt::rawAction(void)
|
||||||
throw LowlevelError(s.str());
|
throw LowlevelError(s.str());
|
||||||
}
|
}
|
||||||
if (!fd->isProcStarted()) {
|
if (!fd->isProcStarted()) {
|
||||||
#ifdef OPACTION_DEBUG
|
#ifdef __REMOTE_SOCKET__
|
||||||
turn_on_debugging(fd);
|
connect_to_console(fd);
|
||||||
#endif
|
#endif
|
||||||
ghidra->allacts.getCurrent()->reset( *fd );
|
ghidra->allacts.getCurrent()->reset( *fd );
|
||||||
ghidra->allacts.getCurrent()->perform( *fd );
|
ghidra->allacts.getCurrent()->perform( *fd );
|
||||||
#ifdef OPACTION_DEBUG
|
|
||||||
turn_off_debugging(fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sout.write("\000\000\001\016",4);
|
sout.write("\000\000\001\016",4);
|
||||||
|
|
|
@ -230,9 +230,8 @@ public:
|
||||||
virtual void rawAction(void);
|
virtual void rawAction(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef OPACTION_DEBUG
|
#ifdef __REMOTE_SOCKET__
|
||||||
extern void turn_on_debugging(Funcdata *fd);
|
extern void connect_to_console(Funcdata *fd);
|
||||||
extern void turn_off_debugging(Funcdata *fd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -225,6 +225,14 @@ IfaceDecompData::~IfaceDecompData(void)
|
||||||
// fd will get deleted with Database
|
// fd will get deleted with Database
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IfaceDecompData::allocateCallGraph(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (cgraph != (CallGraph *)0)
|
||||||
|
delete cgraph;
|
||||||
|
cgraph = new CallGraph(conf);
|
||||||
|
}
|
||||||
|
|
||||||
void IfaceDecompData::abortFunction(ostream &s)
|
void IfaceDecompData::abortFunction(ostream &s)
|
||||||
|
|
||||||
{ // Clear references to current function
|
{ // Clear references to current function
|
||||||
|
@ -2096,10 +2104,7 @@ void IfcDuplicateHash::iterationCallback(Funcdata *fd)
|
||||||
void IfcCallGraphBuild::execute(istream &s)
|
void IfcCallGraphBuild::execute(istream &s)
|
||||||
|
|
||||||
{ // Build call graph from existing function starts
|
{ // Build call graph from existing function starts
|
||||||
if (dcp->cgraph != (CallGraph *)0)
|
dcp->allocateCallGraph();
|
||||||
delete dcp->cgraph;
|
|
||||||
|
|
||||||
dcp->cgraph = new CallGraph(dcp->conf);
|
|
||||||
|
|
||||||
dcp->cgraph->buildAllNodes(); // Build a node in the graph for existing symbols
|
dcp->cgraph->buildAllNodes(); // Build a node in the graph for existing symbols
|
||||||
quick = false;
|
quick = false;
|
||||||
|
@ -2146,11 +2151,7 @@ void IfcCallGraphBuild::iterationCallback(Funcdata *fd)
|
||||||
void IfcCallGraphBuildQuick::execute(istream &s)
|
void IfcCallGraphBuildQuick::execute(istream &s)
|
||||||
|
|
||||||
{ // Build call graph from existing function starts, do only disassembly
|
{ // Build call graph from existing function starts, do only disassembly
|
||||||
if (dcp->cgraph != (CallGraph *)0)
|
dcp->allocateCallGraph();
|
||||||
delete dcp->cgraph;
|
|
||||||
|
|
||||||
dcp->cgraph = new CallGraph(dcp->conf);
|
|
||||||
|
|
||||||
dcp->cgraph->buildAllNodes(); // Build a node in the graph for existing symbols
|
dcp->cgraph->buildAllNodes(); // Build a node in the graph for existing symbols
|
||||||
quick = true;
|
quick = true;
|
||||||
iterateFunctionsAddrOrder();
|
iterateFunctionsAddrOrder();
|
||||||
|
@ -2199,7 +2200,7 @@ void IfcCallGraphLoad::execute(istream &s)
|
||||||
DocumentStorage store;
|
DocumentStorage store;
|
||||||
Document *doc = store.parseDocument(is);
|
Document *doc = store.parseDocument(is);
|
||||||
|
|
||||||
dcp->cgraph = new CallGraph(dcp->conf);
|
dcp->allocateCallGraph();
|
||||||
dcp->cgraph->restoreXml(doc->getRoot());
|
dcp->cgraph->restoreXml(doc->getRoot());
|
||||||
*status->optr << "Successfully read in callgraph" << endl;
|
*status->optr << "Successfully read in callgraph" << endl;
|
||||||
|
|
||||||
|
@ -2744,6 +2745,7 @@ void mainloop(IfaceStatus *status) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
while(!status->isStreamFinished()) {
|
while(!status->isStreamFinished()) {
|
||||||
status->writePrompt();
|
status->writePrompt();
|
||||||
|
status->optr->flush();
|
||||||
execute(status,dcp);
|
execute(status,dcp);
|
||||||
}
|
}
|
||||||
if (status->done) break;
|
if (status->done) break;
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
IfaceDecompData(void);
|
IfaceDecompData(void);
|
||||||
virtual ~IfaceDecompData(void);
|
virtual ~IfaceDecompData(void);
|
||||||
|
void allocateCallGraph(void);
|
||||||
void abortFunction(ostream &s);
|
void abortFunction(ostream &s);
|
||||||
void clearArchitecture(void);
|
void clearArchitecture(void);
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "interface.hh"
|
#include "interface.hh"
|
||||||
|
#ifdef __REMOTE_SOCKET__
|
||||||
|
#include "sys/socket.h"
|
||||||
|
#include "sys/un.h"
|
||||||
|
#include "unistd.h"
|
||||||
|
#include "ext/stdio_filebuf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
vector<IfaceCapability *> IfaceCapability::thelist;
|
vector<IfaceCapability *> IfaceCapability::thelist;
|
||||||
|
|
||||||
|
@ -30,6 +36,84 @@ void IfaceCapability::registerAllCommands(IfaceStatus *status)
|
||||||
thelist[i]->registerCommands(status);
|
thelist[i]->registerCommands(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __REMOTE_SOCKET__
|
||||||
|
|
||||||
|
RemoteSocket::RemoteSocket(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
fileDescriptor = 0;
|
||||||
|
inbuf = (basic_filebuf<char> *)0;
|
||||||
|
outbuf = (basic_filebuf<char> *)0;
|
||||||
|
inStream = (istream *)0;
|
||||||
|
outStream = (ostream *)0;
|
||||||
|
isOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteSocket::close(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (inStream != (istream *)0) {
|
||||||
|
delete inStream;
|
||||||
|
inStream = (istream *)0;
|
||||||
|
}
|
||||||
|
if (outStream != (ostream *)0) {
|
||||||
|
delete outStream;
|
||||||
|
outStream = (ostream *)0;
|
||||||
|
}
|
||||||
|
if (inbuf != (basic_filebuf<char> *)0) {
|
||||||
|
// Destroying the buffer should automatically close the socket
|
||||||
|
delete inbuf;
|
||||||
|
inbuf = (basic_filebuf<char> *)0;
|
||||||
|
}
|
||||||
|
if (outbuf != (basic_filebuf<char> *)0) {
|
||||||
|
delete outbuf;
|
||||||
|
outbuf = (basic_filebuf<char> *)0;
|
||||||
|
}
|
||||||
|
isOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemoteSocket::open(const string &filename)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (isOpen) return false;
|
||||||
|
if ((fileDescriptor = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||||
|
throw IfaceError("Could not create socket");
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
int4 len = filename.length();
|
||||||
|
if (len >= sizeof(addr.sun_path))
|
||||||
|
throw IfaceError("Socket name too long");
|
||||||
|
memcpy(addr.sun_path,filename.c_str(),len);
|
||||||
|
addr.sun_path[len] = '\0';
|
||||||
|
len += sizeof(addr.sun_family);
|
||||||
|
if (connect(fileDescriptor, (struct sockaddr *)&addr, len) < 0) {
|
||||||
|
::close(fileDescriptor);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdopen(fileDescriptor, "r");
|
||||||
|
inbuf = new __gnu_cxx::stdio_filebuf<char>(fileDescriptor,ios::in);
|
||||||
|
fdopen(fileDescriptor, "w");
|
||||||
|
outbuf = new __gnu_cxx::stdio_filebuf<char>(fileDescriptor,ios::out);
|
||||||
|
inStream = new istream(inbuf);
|
||||||
|
outStream = new ostream(outbuf);
|
||||||
|
isOpen = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemoteSocket::isSocketOpen(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!isOpen) return false;
|
||||||
|
if (inStream->eof()) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
IfaceStatus::IfaceStatus(const string &prmpt,istream &is,ostream &os,int4 mxhist)
|
IfaceStatus::IfaceStatus(const string &prmpt,istream &is,ostream &os,int4 mxhist)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -75,6 +159,15 @@ void IfaceStatus::popScript(void)
|
||||||
inerror = false;
|
inerror = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IfaceStatus::reset(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
while(!inputstack.empty())
|
||||||
|
popScript();
|
||||||
|
errorisdone = false;
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
|
||||||
void IfaceStatus::saveHistory(const string &line)
|
void IfaceStatus::saveHistory(const string &line)
|
||||||
|
|
||||||
{ // Save line in circular history buffer
|
{ // Save line in circular history buffer
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -44,6 +44,32 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#ifdef __REMOTE_SOCKET__
|
||||||
|
|
||||||
|
/// \brief A wrapper around a UNIX domain socket
|
||||||
|
///
|
||||||
|
/// The open() command attempts to connect to given socket name,
|
||||||
|
/// which must have been previously established by an external process.
|
||||||
|
/// The socket is bound to a C++ istream and ostream.
|
||||||
|
class RemoteSocket {
|
||||||
|
int fileDescriptor; ///< Descriptor for the socket
|
||||||
|
basic_filebuf<char> *inbuf; ///< Input buffer associated with the socket
|
||||||
|
basic_filebuf<char> *outbuf; ///< Output buffer for the socket
|
||||||
|
istream *inStream; ///< The C++ input stream
|
||||||
|
ostream *outStream; ///< The C++ output stream
|
||||||
|
bool isOpen; ///< Has the socket been opened
|
||||||
|
public:
|
||||||
|
RemoteSocket(void); ///< Constructor
|
||||||
|
~RemoteSocket(void) { close(); } ///< Destructor
|
||||||
|
bool open(const string &filename); ///< Connect to the given socket
|
||||||
|
bool isSocketOpen(void); ///< Return \b true if the socket is ready to transfer data
|
||||||
|
istream *getInputStream(void) { return inStream; } ///< Get the input stream
|
||||||
|
ostream *getOutputStream(void) { return outStream; } ///< Get the output stream
|
||||||
|
void close(void); ///< Close the streams and socket
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct IfaceError {
|
struct IfaceError {
|
||||||
string explain; // Explanatory string
|
string explain; // Explanatory string
|
||||||
IfaceError(const string &s) { explain = s; }
|
IfaceError(const string &s) { explain = s; }
|
||||||
|
@ -136,6 +162,7 @@ public:
|
||||||
void setErrorIsDone(bool val) { errorisdone = val; }
|
void setErrorIsDone(bool val) { errorisdone = val; }
|
||||||
void pushScript(const string &filename,const string &newprompt);
|
void pushScript(const string &filename,const string &newprompt);
|
||||||
void popScript(void);
|
void popScript(void);
|
||||||
|
void reset(void);
|
||||||
int4 getNumInputStreamSize(void) const { return inputstack.size(); }
|
int4 getNumInputStreamSize(void) const { return inputstack.size(); }
|
||||||
void writePrompt(void) { *optr << prompt; }
|
void writePrompt(void) { *optr << prompt; }
|
||||||
void registerCom(IfaceCommand *fptr, const char *nm1,
|
void registerCom(IfaceCommand *fptr, const char *nm1,
|
||||||
|
|
|
@ -239,6 +239,7 @@ CPUI_DEBUG -- This is the ONE debug switch that should be passed in
|
||||||
#ifdef CPUI_DEBUG
|
#ifdef CPUI_DEBUG
|
||||||
# define OPACTION_DEBUG
|
# define OPACTION_DEBUG
|
||||||
# define PRETTY_DEBUG
|
# define PRETTY_DEBUG
|
||||||
|
//# define __REMOTE_SOCKET__
|
||||||
//# define TYPEPROP_DEBUG
|
//# define TYPEPROP_DEBUG
|
||||||
//# define DFSVERIFY_DEBUG
|
//# define DFSVERIFY_DEBUG
|
||||||
//# define BLOCKCONSISTENT_DEBUG
|
//# define BLOCKCONSISTENT_DEBUG
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue