interactive shell wip

This commit is contained in:
j3d1 2016-02-06 02:32:17 +01:00
parent 59796d600b
commit 5b7014737a
13 changed files with 261 additions and 177 deletions

View file

@ -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 $@

View file

@ -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;
while(cmd.compare("quit")){
cout<< "smrtlink>" << flush;
cin >> cmd;
cout << cmd <<endl;;
vector<string> v;
//vector<char const*> vc;
//const char** argv;
//int argc;
Program p = Program();
p.init();
while (cmd.compare("quit")) {
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;
}

View file

@ -12,7 +12,7 @@ class Interactive {
public:
Interactive();
virtual ~Interactive();
int run();
int loop();
};
#endif /* INTERACTIVE_H_ */

View file

@ -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";
}

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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) {
@ -27,7 +30,7 @@ void Socket::init(short dst_port, short src_port) {
src_port = p;
}
if (options.debug_level>=1)
if (options.debug_level >= 1)
std::cout << "Local IP:\t" << local_ip << "\n";
wildcard_endpoint_ = boost::asio::ip::udp::endpoint(
@ -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
View 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;
}

View file

@ -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;

View file

@ -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_ */

View file

@ -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)

View file

@ -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,12 +32,8 @@ 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;
int index, opt;
options.user = DEFAULT_USER;
options.password = DEFAULT_PASS;
@ -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);
}