interactive shell wip
This commit is contained in:
parent
59796d600b
commit
5b7014737a
13 changed files with 261 additions and 177 deletions
3
Makefile
3
Makefile
|
@ -15,8 +15,7 @@ $(BUILDDIR):
|
|||
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system
|
||||
#-lboost_program_options
|
||||
$(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -lreadline -lboost_program_options
|
||||
|
||||
$(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
|
|
@ -7,7 +7,14 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include<boost/program_options/parsers.hpp>
|
||||
#include<readline/readline.h>
|
||||
#include<readline/history.h>
|
||||
|
||||
#include "Program.h"
|
||||
#include "Interactive.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -21,12 +28,28 @@ Interactive::~Interactive() {
|
|||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
int Interactive::run() {
|
||||
int Interactive::loop() {
|
||||
string cmd;
|
||||
vector<string> v;
|
||||
//vector<char const*> vc;
|
||||
//const char** argv;
|
||||
//int argc;
|
||||
|
||||
Program p = Program();
|
||||
p.init();
|
||||
|
||||
while (cmd.compare("quit")) {
|
||||
cout<< "smrtlink>" << flush;
|
||||
cin >> cmd;
|
||||
cout << cmd <<endl;;
|
||||
cmd = readline("smrtlink> ");
|
||||
add_history(cmd.c_str());
|
||||
v = boost::program_options::split_unix(cmd);
|
||||
|
||||
//vc = vector<char const*>(v.size());
|
||||
//std::transform(begin(v), end(v), begin(vc), [](std::string const &s) { return s.c_str(); });
|
||||
//argv = &vc[0];
|
||||
//argc = v.size();
|
||||
|
||||
p.run(v);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class Interactive {
|
|||
public:
|
||||
Interactive();
|
||||
virtual ~Interactive();
|
||||
int run();
|
||||
int loop();
|
||||
};
|
||||
|
||||
#endif /* INTERACTIVE_H_ */
|
||||
|
|
|
@ -158,8 +158,8 @@ std::string Packet::opCodeToString() {
|
|||
return "SET";
|
||||
case CONFIRM:
|
||||
return "CONFIRM";
|
||||
case RETURN:
|
||||
return "RETURN";
|
||||
case REPLY:
|
||||
return "REPLY";
|
||||
default:
|
||||
return "NONE";
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ static short sequenceId=0;
|
|||
class Packet
|
||||
{
|
||||
public:
|
||||
enum OpCode {DISCOVERY, GET, RETURN, SET, CONFIRM, NONE};
|
||||
enum OpCode {DISCOVERY, GET, REPLY, SET, CONFIRM, NONE};
|
||||
Packet(OpCode);
|
||||
static void encode(bytes&);
|
||||
bytes getBytes();
|
||||
|
|
112
src/Program.cpp
112
src/Program.cpp
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "Constant.h"
|
||||
#include "Program.h"
|
||||
|
@ -14,11 +17,117 @@
|
|||
#include "Socket.h"
|
||||
#include "Switch.h"
|
||||
#include "Packet.h"
|
||||
#include "Types.h"
|
||||
#include "lookup.h"
|
||||
#include "table.h"
|
||||
|
||||
using namespace smrtlink;
|
||||
using namespace std;
|
||||
|
||||
int Program::run(vector<string> arg) {
|
||||
int optind = 0;
|
||||
std::vector<std::string> vect;
|
||||
std::map<std::string, std::string> ll;
|
||||
std::cmatch sm;
|
||||
std::string cmd = arg[optind++];
|
||||
switch (caseArg(cmd.c_str())) {
|
||||
case caseArg("reboot"):
|
||||
if (!reboot())
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("reset"):
|
||||
if (!reset())
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("save"):
|
||||
if (!save())
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("restore"):
|
||||
if (!restore())
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("flash"):
|
||||
if (!flash())
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case caseArg("list"):
|
||||
if (!list())
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case caseArg("sniff"):
|
||||
if (!sniff())
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case caseArg("encode"):
|
||||
if (optind < arg.size()) {
|
||||
std::string s(arg[optind]);
|
||||
optind++;
|
||||
if (encode(s))
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "Argument expected after encode\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case caseArg("set"):
|
||||
while (optind < arg.size()) {
|
||||
if (regex_match(arg[optind].c_str(), sm,
|
||||
std::regex("^([a-z]+)=(.*)$"))) {
|
||||
if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
ll.insert(std::pair<std::string, std::string>(sm[1], sm[2]));
|
||||
} else {
|
||||
cerr << "Invalid Syntax " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!setProperty(ll))
|
||||
return 0;
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("get"):
|
||||
while (optind < arg.size()) {
|
||||
if (regex_match(arg[optind].c_str(), sm,
|
||||
std::regex("^([a-z]+)$"))) {
|
||||
if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
vect.push_back(sm[1]);
|
||||
} else {
|
||||
cerr << "Invalid argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!getProperty(vect))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %s\n", cmd.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int printHeader(Packet p) {
|
||||
if (options.flags.HEADER) {
|
||||
if (options.flags.HEX) {
|
||||
|
@ -240,7 +349,8 @@ int Program::flash() {
|
|||
|
||||
int Program::reboot() {
|
||||
try {
|
||||
discover([this](Packet a) {
|
||||
discover(
|
||||
[this](Packet a) {
|
||||
datasets d =a.getPayload();
|
||||
Switch sw = Switch();
|
||||
sw.parse(d);
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
sock = std::make_shared<Socket>(*io_service);
|
||||
}
|
||||
void init();
|
||||
int run(std::vector<std::string>);
|
||||
|
||||
int list();
|
||||
int sniff();
|
||||
int encode(std::string);
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
#include "Host.h"
|
||||
#include "Types.h"
|
||||
|
||||
#define SEND_F 1
|
||||
#define RECEIVE_F 2
|
||||
|
||||
Socket::Socket(boost::asio::io_service& io_service) :
|
||||
send_socket_(io_service), receive_socket_(io_service), timer(io_service) {
|
||||
}
|
||||
//, resolver( io_service)
|
||||
void Socket::init(short dst_port, short src_port) {
|
||||
if (initialized)
|
||||
if (initialized == 3)
|
||||
return;
|
||||
|
||||
if (options.flags.REVERSE) {
|
||||
|
@ -38,29 +41,7 @@ void Socket::init(short dst_port, short src_port) {
|
|||
boost::asio::ip::address_v4::from_string("255.255.255.255"),
|
||||
dst_port);
|
||||
|
||||
send_socket_.open(boost::asio::ip::udp::v4());
|
||||
send_socket_.set_option(boost::asio::socket_base::broadcast(true));
|
||||
send_socket_.set_option(boost::asio::socket_base::reuse_address(true));
|
||||
send_socket_.bind(local_endpoint_);
|
||||
|
||||
receive_socket_.open(boost::asio::ip::udp::v4());
|
||||
receive_socket_.set_option(boost::asio::socket_base::broadcast(true));
|
||||
receive_socket_.set_option(boost::asio::socket_base::reuse_address(true));
|
||||
receive_socket_.bind(wildcard_endpoint_);
|
||||
|
||||
if (options.timeout != 0) {
|
||||
timer.expires_from_now(
|
||||
boost::posix_time::milliseconds(options.timeout));
|
||||
timer.async_wait([this](const boost::system::error_code& error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
receive_socket_.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
initialized = 3;
|
||||
}
|
||||
|
||||
void Socket::setHostIp(ipAddr ip) {
|
||||
|
@ -68,6 +49,12 @@ void Socket::setHostIp(ipAddr ip) {
|
|||
}
|
||||
|
||||
void Socket::send(Packet p) {
|
||||
if (!send_socket_.is_open() || !(initialized&SEND_F)) {
|
||||
send_socket_.open(boost::asio::ip::udp::v4());
|
||||
send_socket_.set_option(boost::asio::socket_base::broadcast(true));
|
||||
send_socket_.set_option(boost::asio::socket_base::reuse_address(true));
|
||||
send_socket_.bind(local_endpoint_);
|
||||
}
|
||||
bytes data = p.getBytes();
|
||||
p.encode(data);
|
||||
unsigned char * a = &data[0];
|
||||
|
@ -80,6 +67,25 @@ void Socket::send(Packet p) {
|
|||
}
|
||||
|
||||
void Socket::listen() {
|
||||
if (!receive_socket_.is_open() || !(initialized & RECEIVE_F)) {
|
||||
receive_socket_.open(boost::asio::ip::udp::v4());
|
||||
receive_socket_.set_option(boost::asio::socket_base::broadcast(true));
|
||||
receive_socket_.set_option(
|
||||
boost::asio::socket_base::reuse_address(true));
|
||||
receive_socket_.bind(wildcard_endpoint_);
|
||||
}
|
||||
if (options.timeout != 0) {
|
||||
timer.expires_from_now(
|
||||
boost::posix_time::milliseconds(options.timeout));
|
||||
timer.async_wait([this](const boost::system::error_code& error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
receive_socket_.close();
|
||||
initialized&=~RECEIVE_F;
|
||||
}
|
||||
});
|
||||
}
|
||||
data.resize(MAX_LENGTH);
|
||||
receive_socket_.async_receive_from(boost::asio::buffer(data, MAX_LENGTH),
|
||||
remote_endpoint_,
|
||||
|
|
31
src/Switch-Cmd.cpp
Normal file
31
src/Switch-Cmd.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Switch.cpp
|
||||
*
|
||||
* Created on: 29.09.2015
|
||||
* Author: jdi
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "Types.h"
|
||||
#include "Switch.h"
|
||||
#include "Constant.h"
|
||||
#include "table.h"
|
||||
|
||||
using namespace smrtlink;
|
||||
using namespace std;
|
||||
|
||||
int Switch::set(pair<string, string> str) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string Switch::get(std::string str) {
|
||||
std::string ret;
|
||||
switch (caseArg(str.c_str())) {
|
||||
case caseArg("ip"):
|
||||
ret = "0.0.0.0";
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -65,9 +65,13 @@ public:
|
|||
int parse(datasets);
|
||||
int parse(dataset);
|
||||
int parse(std::string);
|
||||
int print();
|
||||
int set(std::pair<std::string,std::string>);
|
||||
|
||||
std::string get(std::string);
|
||||
std::string toString();
|
||||
|
||||
int print();
|
||||
|
||||
struct {
|
||||
std::string type;
|
||||
std::string hardware_version;
|
||||
|
|
11
src/Types.h
11
src/Types.h
|
@ -95,6 +95,14 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
namespace smrtlink {
|
||||
|
||||
constexpr unsigned int caseArg(const char* str, int h = 0) {
|
||||
return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> operator+(const std::vector<T> &A, const std::vector<T> &B) {
|
||||
std::vector<T> AB;
|
||||
|
@ -117,6 +125,7 @@ struct Options {
|
|||
bool JSON;
|
||||
bool PLAIN;
|
||||
bool REVERSE;
|
||||
|
||||
bool HEADER;
|
||||
bool PERMANENT;
|
||||
bool WAIT;
|
||||
|
@ -128,7 +137,7 @@ struct Options {
|
|||
std::string file;
|
||||
int debug_level = 0;
|
||||
int verbosity = 0;
|
||||
long timeout = 180U;
|
||||
long timeout = 250U;
|
||||
};
|
||||
|
||||
#endif /* TYPES_H_ */
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
LOOKUP_SET(TYPE,type, 1, STRING) //+string
|
||||
LOOKUP_SET(type, TYPE, STRING) //+string
|
||||
LOOKUP_SET(mac, MAC, HEX) //+byte[6]
|
||||
LOOKUP_SET(firmware,FIRMWARE_VERSION, STRING)
|
||||
LOOKUP_SET(hardware,HARDWARE_VERSION, STRING)
|
||||
|
||||
|
||||
LOOKUP_SET(HOSTNAME,host, 2, STRING) //+string
|
||||
LOOKUP_SET(MAC,MAC, 3, HEX) //+byte[6]
|
||||
LOOKUP_SET(IP_ADDR,ip, 4, DEC) //+byte[4]
|
||||
LOOKUP_SET(IP_MASK,mask, 5, DEC) //+byte[4]
|
||||
LOOKUP_SET(GATEWAY,gateway, 6, DEC) //+byte[4]
|
||||
LOOKUP_SET(FIRMWARE_VERSION,FIRMWARE_VERSION, 7, STRING)
|
||||
LOOKUP_SET(HARDWARE_VERSION,HARDWARE_VERSION, 8, STRING)
|
||||
LOOKUP_SET(DHCP_ENABLED,dhcp, 9, BOOL) //+bool byte
|
||||
|
||||
LOOKUP_SET(PORT_VLAN_FOOOOO, 2101,2101, HEX)
|
||||
|
|
118
src/smrtlink.cpp
118
src/smrtlink.cpp
|
@ -1,14 +1,13 @@
|
|||
//============================================================================
|
||||
// Name : smrtlink.cpp
|
||||
// Author : jdi
|
||||
// Version :
|
||||
// Version : 1.2
|
||||
// Copyright : GPL v2
|
||||
// Description : SmrtLink in C++, Ansi-style
|
||||
//============================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
@ -21,6 +20,7 @@
|
|||
#include "Interactive.h"
|
||||
#include "Host.h"
|
||||
#include "Program.h"
|
||||
#include "Types.h"
|
||||
#include "Switch.h"
|
||||
#include "lookup.h"
|
||||
|
||||
|
@ -32,10 +32,6 @@ using namespace std;
|
|||
|
||||
Options options;
|
||||
|
||||
constexpr unsigned int caseArg(const char* str, int h = 0) {
|
||||
return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h];
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int index, opt;
|
||||
|
||||
|
@ -54,8 +50,6 @@ int main(int argc, char *argv[]) {
|
|||
0, 't' }, { "wait", required_argument, 0, 'w' }, { 0, 0, 0,
|
||||
0 }, };
|
||||
|
||||
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "bhrvVXIswxP:U:i:f:t:d::", longopts,
|
||||
&index)) != -1) {
|
||||
switch (opt) {
|
||||
|
@ -154,113 +148,17 @@ int main(int argc, char *argv[]) {
|
|||
cerr << "Command is ignored in interactive mode\n";
|
||||
}
|
||||
Interactive p = Interactive();
|
||||
if (!p.run())
|
||||
if (!p.loop())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (optind < argc) {
|
||||
} else if (optind < argc) {
|
||||
Program p = Program();
|
||||
p.init();
|
||||
std::vector<std::string> vect;
|
||||
std::map<std::string, std::string> list;
|
||||
std::cmatch sm;
|
||||
std::string cmd = std::string(argv[optind++]);
|
||||
switch (caseArg(cmd.c_str())) {
|
||||
case caseArg("reboot"):
|
||||
if (!p.reboot())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("reset"):
|
||||
if (!p.reset())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("save"):
|
||||
if (!p.save())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("restore"):
|
||||
if (!p.restore())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("flash"):
|
||||
if (!p.flash())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
|
||||
case caseArg("list"):
|
||||
if (!p.list())
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case caseArg("sniff"):
|
||||
if (!p.sniff())
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case caseArg("encode"):
|
||||
if (optind < argc) {
|
||||
std::string s(argv[optind]);
|
||||
optind++;
|
||||
if (p.encode(s))
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
fprintf(stderr, "Argument expected after encode\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case caseArg("set"):
|
||||
while (optind < argc) {
|
||||
if (regex_match(argv[optind], sm,
|
||||
std::regex("^([a-z]+)=(.*)$"))) {
|
||||
if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
list.insert(
|
||||
std::pair<std::string, std::string>(sm[1], sm[2]));
|
||||
} else {
|
||||
cerr << "Invalid Syntax " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!p.setProperty(list))
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("get"):
|
||||
while (optind < argc) {
|
||||
if (regex_match(argv[optind], sm, std::regex("^([a-z]+)$"))) {
|
||||
if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
vect.push_back(sm[1]);
|
||||
} else {
|
||||
cerr << "Invalid argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!p.getProperty(vect))
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %s\n", cmd.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
vector<string> v;
|
||||
while (optind < argc)
|
||||
v.push_back(argv[optind++]);
|
||||
p.run(v);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue