diff --git a/tui/main.cpp b/tui/main.cpp index 37a45fc..ccc8708 100644 --- a/tui/main.cpp +++ b/tui/main.cpp @@ -2,386 +2,8 @@ #include #include #include -#include -#include -#include -#include -#include - -#define COLOR_DARK_GRAY 9 - -void red(WINDOW *window) { - wattron(window, COLOR_PAIR(1)); -} - -void cyan(WINDOW *window) { - wattron(window, COLOR_PAIR(5)); -} - -void green(WINDOW *window) { - wattron(window, COLOR_PAIR(2)); -} - -void magenta(WINDOW *window) { - wattron(window, COLOR_PAIR(6)); -} - -void quit(WINDOW *window) { - delwin(window); - - endwin(); -} - -void msgbox(const char *text) { - //WINDOW *msgbox = newwin(LINES / 2, COLS / 2, LINES / 4, COLS / 4); - WINDOW *msgbox = newwin(8, COLS / 2, LINES / 4, COLS / 4); - wbkgd(msgbox, COLOR_PAIR(8)); - box(msgbox, 0, 0); - mvwaddstr(msgbox, 1, 2, text); - move(3, 5); - wrefresh(msgbox); - - WINDOW *ok = derwin(msgbox, 3, 6, msgbox->_maxy / 2 + 1, msgbox->_maxx / 2); - box(ok, 0, 0); - wattron(ok, COLOR_PAIR(5)); - mvwaddstr(ok, 1, 2, "OK"); - touchwin(msgbox); - wrefresh(ok); - -check_return: - char c = getch(); - - if(c != '\r') { - goto check_return; - } - - delwin(ok); - delwin(msgbox); -} - -void arpMenu(WINDOW *window); -void interfaceMenu(WINDOW *window); -void interfaceSelect(WINDOW *window, QString interface); - -void mainmenu(WINDOW *window) { - wclear(window); - - cyan(window); - box(window, 0, 0); - - red(window); - mvwaddstr(window, 1, 2, "System Configuration:"); - - green(window); - mvwaddstr(window, 3, 2, "1. Interfaces"); - mvwaddstr(window, 4, 2, "2. ARP"); - mvwaddstr(window, 5, 2, "3. Wireless"); - - cyan(window); - mvwaddstr(window, 7, 2, "q. Quit"); - - magenta(window); - mvwaddstr(window, 9, 2, "Enter selection: "); - - wrefresh(window); - - char c = getch(); - - if(c < '0' || c > '3') { - if(c != 27 && c != 'q') { // allow escape in addition to 0 for quit - mainmenu(window); - } - }else{ - if(c == '1') { - interfaceMenu(window); - }else if(c == '2') { - arpMenu(window); - } - } -} - -void arpMenu(WINDOW *window) { - wclear(window); - - cyan(window); - box(window, 0, 0); - - red(window); - mvwaddstr(window, 1, 2, "ARP Table:"); - - green(window); - - QHash arpList = Neighbor::list(QString()); - - int y = 3; - int width = 0; - int widthMAC = 0; - int widthIP = 0; - QString format = "%-"; - - foreach(QString arp, arpList.keys()) { - QString mac = arpList.value(arp); - widthMAC = qMax(widthMAC, mac.length()); - widthIP = qMax(widthIP, arp.length()); - } - - width = widthMAC + widthIP; - format += QString::number(widthIP) + "s at %" + QString::number(widthMAC) + "s"; - - QByteArray formatArr = format.toLatin1(); - const char *formatStr = formatArr.constData(); - char *str = (char*)malloc(width + 5); - - foreach(QString arp, arpList.keys()) { - //arp = QString::number(count) + ". " + arp; - memset(str, 0, width + 5); - QByteArray arpArray = arp.toLatin1(); - QString arpMac = arpList.value(arp); - QByteArray arpMacArray = arpMac.toLatin1(); - const char *arpStr = arpArray.constData(); - const char *arpMacStr = arpMacArray.constData(); - - snprintf(str, width + 5, formatStr, arpStr, arpMacStr); - /*memcpy(str, arpStr, strlen(arpStr)); - memcpy(str + strlen(arpStr), " at ", 4); - memcpy(str + strlen(arpStr) + 4, arpMacStr, strlen(arpMacStr));*/ - - mvwaddstr(window, y, 2, str); - - ++y; - } - - free(str); - cyan(window); - mvwaddstr(window, y + 1, 2, "0. Back to main menu"); - wrefresh(window); - -arpChar: - char c = getch(); - - if(c != '0' && c != 27 && c != 'q') { - goto arpChar; - }else{ - if(c != 'q') { - mainmenu(window); - } - } -} - -void interfaceMenu(WINDOW *window) { - wclear(window); - - cyan(window); - box(window, 0, 0); - - red(window); - mvwaddstr(window, 1, 2, "Interfaces:"); - - green(window); - - QStringList interfaceList = Interface::list(); - - int count = 1; - int y = 3; - int lastInterface = 0; - QHash interfaceHash; - - foreach(QString interface, interfaceList) { - QString orig = interface; - interface = QString::number(count) + ". " + interface; - QByteArray interfaceArray = interface.toLatin1(); - const char *interfaceStr = interfaceArray.constData(); - - mvwaddstr(window, y, 2, interfaceStr); - - lastInterface = count + '0'; - - interfaceHash.insert(lastInterface, orig); - - ++y; - ++count; - } - - cyan(window); - mvwaddstr(window, y + 1, 2, "0. Back to main menu"); - - magenta(window); - mvwaddstr(window, y + 3, 2, "q. Quit"); - mvwaddstr(window, y + 5, 2, "Enter selection: "); - wrefresh(window); - - char c = getch(); - - if(c < '0' || c > lastInterface) { - if(c != 'q') { - if(c == 27) { - mainmenu(window); - }else{ - interfaceMenu(window); - } - } - }else{ - if(c == '0') { - mainmenu(window); - }else{ - if(c > '0' && c <= lastInterface) { - interfaceSelect(window, interfaceHash.value(c)); - } - } - } -} - -void interfaceSelect(WINDOW *window, QString interface) { - wclear(window); - - cyan(window); - box(window, 0, 0); - - red(window); - QString title = QString("IP Addresses on: ") + interface; - QByteArray array = title.toLatin1(); - const char *data = array.constData(); - - mvwaddstr(window, 1, 2, data); - - green(window); - - Interface obj(interface); - QStringList ipList = obj.addresses(); - - int count = 1; - int y = 3; - - foreach(QString ip, ipList) { - ip = QString::number(count) + ". " + ip; - QByteArray ipArray = ip.toLatin1(); - const char *ipStr = ipArray.constData(); - - mvwaddstr(window, y, 2, ipStr); - - ++y; - ++count; - } - - if(count == 1) { - mvwaddstr(window, y, 2, "No IP addresses found."); - ++y; - } - - cyan(window); - mvwaddstr(window, y + 1, 2, "0. Back to interfaces"); - - magenta(window); - mvwaddstr(window, y + 3, 2, "a. Add IP address"); - mvwaddstr(window, y + 4, 2, "d. Delete IP address"); - mvwaddstr(window, y + 5, 2, "q. Quit"); - - mvwaddstr(window, y + 7, 2, "Enter selection: "); - wrefresh(window); - - char c = getch(); - - if(c < '0' || c > (count + '0' - 1)) { - if(c == 27) { - interfaceMenu(window); - }else if(c == 'q') { - // no-op, just quit - }else if(c == 'a') { - wdeleteln(window); - mvwaddstr(window, y + 7, 2, "Enter IP address to add: "); - wrefresh(window); - - char ipToAdd[19] = {0}; - - echo(); - wgetnstr(window, ipToAdd, sizeof(ipToAdd) / sizeof(char) - 1); - noecho(); - - QString ip = ipToAdd; - - if(!ip.contains(QRegularExpression("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([5-9]|[1-2][0-9]|3[0-2])$"))) { - msgbox("Invalid IP address. Please try again."); - interfaceSelect(window, interface); - return; - } - - wdeleteln(window); - QString confirm = "Are you sure you want to add "; - - confirm += ip; - confirm += " [y/n]? "; - - QByteArray arr = confirm.toLatin1(); - const char *confirmStr = arr.constData(); - - mvwaddstr(window, y + 7, 2, confirmStr); - wrefresh(window); - - c = getch(); - - if(c == 'y') { - if(obj.addAddress(ip)) { - msgbox("Could not add IP address. Not enough permissions?"); - }else{ - msgbox("IP address added successfully."); - } - - interfaceSelect(window, interface); - }else{ - interfaceSelect(window, interface); - } - }else if(c == 'd') { - wdeleteln(window); - mvwaddstr(window, y + 7, 2, "Enter number of IP address to delete: "); - wrefresh(window); - char ipToDelete = getch(); - - if(ipToDelete < '1' || ipToDelete > '9') { - interfaceSelect(window, interface); - return; - } - - if(!(ipList.count() >= ipToDelete - '0')) { - interfaceSelect(window, interface); - return; - } - - wdeleteln(window); - QString confirm = "Are you sure you want to delete "; - - confirm += ipList[ipToDelete - '0' - 1]; - confirm += " [y/n]? "; - - QByteArray arr = confirm.toLatin1(); - const char *confirmStr = arr.constData(); - - mvwaddstr(window, y + 7, 2, confirmStr); - wrefresh(window); - - c = getch(); - - if(c == 'y') { - if(obj.deleteAddress(ipList[ipToDelete - '0' - 1])) { - msgbox("Could not delete IP address. Not enough permissions?"); - }else{ - msgbox("IP address deleted successfully."); - } - - interfaceSelect(window, interface); - }else{ - interfaceSelect(window, interface); - } - }else{ - interfaceSelect(window, interface); - } - }else{ - if(c == '0') { - interfaceMenu(window); - }else{ - interfaceSelect(window, interface); - } - } -} +#include +#include "menu.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); @@ -423,11 +45,21 @@ int main(int argc, char *argv[]) { //printf("\e[1;1H\e[2J"); - mainmenu(window); + QThread *thread = new QThread; + Menu *menu = new Menu(window); + + menu->moveToThread(thread); + + QObject::connect(thread, SIGNAL(started()), menu, SLOT(start())); + QObject::connect(menu, SIGNAL(finished()), thread, SLOT(quit())); + QObject::connect(menu, SIGNAL(finished()), menu, SLOT(deleteLater())); + QObject::connect(menu, SIGNAL(finished()), thread, SLOT(deleteLater())); + + thread->start(); + + int ret = app.exec(); - quit(window); - /*int ret = app.exec(); + return ret; - return ret;*/ return 0; } diff --git a/tui/menu.cpp b/tui/menu.cpp new file mode 100644 index 0000000..fe8717f --- /dev/null +++ b/tui/menu.cpp @@ -0,0 +1,390 @@ +#include +#include "menu.h" + +Menu::Menu(WINDOW *window, QObject *parent) : + QObject(parent), + m_window(window) +{ + +} + +Menu::~Menu() { + emit finished(); +} + +void Menu::start() { + mainmenu(m_window); +} + +void Menu::red(WINDOW *window) { + wattron(window, COLOR_PAIR(1)); +} + +void Menu::cyan(WINDOW *window) { + wattron(window, COLOR_PAIR(5)); +} + +void Menu::green(WINDOW *window) { + wattron(window, COLOR_PAIR(2)); +} + +void Menu::magenta(WINDOW *window) { + wattron(window, COLOR_PAIR(6)); +} + +void Menu::quit(WINDOW *window) { + delwin(window); + + endwin(); + + qApp->quit(); +} + +void Menu::msgbox(const char *text) { + //WINDOW *msgbox = newwin(LINES / 2, COLS / 2, LINES / 4, COLS / 4); + WINDOW *msgbox = newwin(8, COLS / 2, LINES / 4, COLS / 4); + wbkgd(msgbox, COLOR_PAIR(8)); + box(msgbox, 0, 0); + mvwaddstr(msgbox, 1, 2, text); + move(3, 5); + wrefresh(msgbox); + + WINDOW *ok = derwin(msgbox, 3, 6, msgbox->_maxy / 2 + 1, msgbox->_maxx / 2); + box(ok, 0, 0); + wattron(ok, COLOR_PAIR(5)); + mvwaddstr(ok, 1, 2, "OK"); + touchwin(msgbox); + wrefresh(ok); + +check_return: + char c = getch(); + + if(c != '\r') { + goto check_return; + } + + delwin(ok); + delwin(msgbox); +} + +void Menu::mainmenu(WINDOW *window) { + wclear(window); + + cyan(window); + box(window, 0, 0); + + red(window); + mvwaddstr(window, 1, 2, "System Configuration:"); + + green(window); + mvwaddstr(window, 3, 2, "1. Interfaces"); + mvwaddstr(window, 4, 2, "2. ARP"); + mvwaddstr(window, 5, 2, "3. Wireless"); + + cyan(window); + mvwaddstr(window, 7, 2, "q. Quit"); + + magenta(window); + mvwaddstr(window, 9, 2, "Enter selection: "); + + wrefresh(window); + + char c = getch(); + + if(c < '0' || c > '3') { + if(c != 27 && c != 'q') { // allow escape in addition to 0 for quit + mainmenu(window); + } + }else{ + if(c == '1') { + interfaceMenu(window); + }else if(c == '2') { + arpMenu(window); + } + } + + quit(window); +} + +void Menu::arpMenu(WINDOW *window) { + wclear(window); + + cyan(window); + box(window, 0, 0); + + red(window); + mvwaddstr(window, 1, 2, "ARP Table:"); + + green(window); + + QHash arpList = Neighbor::list(QString()); + + int y = 3; + int width = 0; + int widthMAC = 0; + int widthIP = 0; + QString format = "%-"; + + foreach(QString arp, arpList.keys()) { + QString mac = arpList.value(arp); + widthMAC = qMax(widthMAC, mac.length()); + widthIP = qMax(widthIP, arp.length()); + } + + width = widthMAC + widthIP; + format += QString::number(widthIP) + "s at %" + QString::number(widthMAC) + "s"; + + QByteArray formatArr = format.toLatin1(); + const char *formatStr = formatArr.constData(); + char *str = (char*)malloc(width + 5); + + foreach(QString arp, arpList.keys()) { + //arp = QString::number(count) + ". " + arp; + memset(str, 0, width + 5); + QByteArray arpArray = arp.toLatin1(); + QString arpMac = arpList.value(arp); + QByteArray arpMacArray = arpMac.toLatin1(); + const char *arpStr = arpArray.constData(); + const char *arpMacStr = arpMacArray.constData(); + + snprintf(str, width + 5, formatStr, arpStr, arpMacStr); + /*memcpy(str, arpStr, strlen(arpStr)); + memcpy(str + strlen(arpStr), " at ", 4); + memcpy(str + strlen(arpStr) + 4, arpMacStr, strlen(arpMacStr));*/ + + mvwaddstr(window, y, 2, str); + + ++y; + } + + free(str); + cyan(window); + mvwaddstr(window, y + 1, 2, "0. Back to main menu"); + wrefresh(window); + +arpChar: + char c = getch(); + + if(c != '0' && c != 27 && c != 'q') { + goto arpChar; + }else{ + if(c != 'q') { + mainmenu(window); + } + } +} + +void Menu::interfaceMenu(WINDOW *window) { + wclear(window); + + cyan(window); + box(window, 0, 0); + + red(window); + mvwaddstr(window, 1, 2, "Interfaces:"); + + green(window); + + QStringList interfaceList = Interface::list(); + + int count = 1; + int y = 3; + int lastInterface = 0; + QHash interfaceHash; + + foreach(QString interface, interfaceList) { + QString orig = interface; + interface = QString::number(count) + ". " + interface; + QByteArray interfaceArray = interface.toLatin1(); + const char *interfaceStr = interfaceArray.constData(); + + mvwaddstr(window, y, 2, interfaceStr); + + lastInterface = count + '0'; + + interfaceHash.insert(lastInterface, orig); + + ++y; + ++count; + } + + cyan(window); + mvwaddstr(window, y + 1, 2, "0. Back to main menu"); + + magenta(window); + mvwaddstr(window, y + 3, 2, "q. Quit"); + mvwaddstr(window, y + 5, 2, "Enter selection: "); + wrefresh(window); + + char c = getch(); + + if(c < '0' || c > lastInterface) { + if(c != 'q') { + if(c == 27) { + mainmenu(window); + }else{ + interfaceMenu(window); + } + } + }else{ + if(c == '0') { + mainmenu(window); + }else{ + if(c > '0' && c <= lastInterface) { + interfaceSelect(window, interfaceHash.value(c)); + } + } + } +} + +void Menu::interfaceSelect(WINDOW *window, QString interface) { + wclear(window); + + cyan(window); + box(window, 0, 0); + + red(window); + QString title = QString("IP Addresses on: ") + interface; + QByteArray array = title.toLatin1(); + const char *data = array.constData(); + + mvwaddstr(window, 1, 2, data); + + green(window); + + Interface obj(interface); + QStringList ipList = obj.addresses(); + + int count = 1; + int y = 3; + + foreach(QString ip, ipList) { + ip = QString::number(count) + ". " + ip; + QByteArray ipArray = ip.toLatin1(); + const char *ipStr = ipArray.constData(); + + mvwaddstr(window, y, 2, ipStr); + + ++y; + ++count; + } + + if(count == 1) { + mvwaddstr(window, y, 2, "No IP addresses found."); + ++y; + } + + cyan(window); + mvwaddstr(window, y + 1, 2, "0. Back to interfaces"); + + magenta(window); + mvwaddstr(window, y + 3, 2, "a. Add IP address"); + mvwaddstr(window, y + 4, 2, "d. Delete IP address"); + mvwaddstr(window, y + 5, 2, "q. Quit"); + + mvwaddstr(window, y + 7, 2, "Enter selection: "); + wrefresh(window); + + char c = getch(); + + if(c < '0' || c > (count + '0' - 1)) { + if(c == 27) { + interfaceMenu(window); + }else if(c == 'q') { + // no-op, just quit + }else if(c == 'a') { + wdeleteln(window); + mvwaddstr(window, y + 7, 2, "Enter IP address to add: "); + wrefresh(window); + + char ipToAdd[19] = {0}; + + echo(); + wgetnstr(window, ipToAdd, sizeof(ipToAdd) / sizeof(char) - 1); + noecho(); + + QString ip = ipToAdd; + + if(!ip.contains(QRegularExpression("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([5-9]|[1-2][0-9]|3[0-2])$"))) { + msgbox("Invalid IP address. Please try again."); + interfaceSelect(window, interface); + return; + } + + wdeleteln(window); + QString confirm = "Are you sure you want to add "; + + confirm += ip; + confirm += " [y/n]? "; + + QByteArray arr = confirm.toLatin1(); + const char *confirmStr = arr.constData(); + + mvwaddstr(window, y + 7, 2, confirmStr); + wrefresh(window); + + c = getch(); + + if(c == 'y') { + if(obj.addAddress(ip)) { + msgbox("Could not add IP address. Not enough permissions?"); + }else{ + msgbox("IP address added successfully."); + } + + interfaceSelect(window, interface); + }else{ + interfaceSelect(window, interface); + } + }else if(c == 'd') { + wdeleteln(window); + mvwaddstr(window, y + 7, 2, "Enter number of IP address to delete: "); + wrefresh(window); + char ipToDelete = getch(); + + if(ipToDelete < '1' || ipToDelete > '9') { + interfaceSelect(window, interface); + return; + } + + if(!(ipList.count() >= ipToDelete - '0')) { + interfaceSelect(window, interface); + return; + } + + wdeleteln(window); + QString confirm = "Are you sure you want to delete "; + + confirm += ipList[ipToDelete - '0' - 1]; + confirm += " [y/n]? "; + + QByteArray arr = confirm.toLatin1(); + const char *confirmStr = arr.constData(); + + mvwaddstr(window, y + 7, 2, confirmStr); + wrefresh(window); + + c = getch(); + + if(c == 'y') { + if(obj.deleteAddress(ipList[ipToDelete - '0' - 1])) { + msgbox("Could not delete IP address. Not enough permissions?"); + }else{ + msgbox("IP address deleted successfully."); + } + + interfaceSelect(window, interface); + }else{ + interfaceSelect(window, interface); + } + }else{ + interfaceSelect(window, interface); + } + }else{ + if(c == '0') { + interfaceMenu(window); + }else{ + interfaceSelect(window, interface); + } + } +} diff --git a/tui/menu.h b/tui/menu.h new file mode 100644 index 0000000..9867ecf --- /dev/null +++ b/tui/menu.h @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define COLOR_DARK_GRAY 9 + +class Menu : public QObject { + Q_OBJECT + +public: + Menu(WINDOW *window, QObject *parent = 0); + ~Menu(); + +signals: + void finished(); + +public slots: + void start(); + +private: + WINDOW *m_window; + + void red(WINDOW *window); + void cyan(WINDOW *window); + void green(WINDOW *window); + void magenta(WINDOW *window); + void quit(WINDOW *window); + void msgbox(const char *text); + void arpMenu(WINDOW *window); + void interfaceMenu(WINDOW *window); + void interfaceSelect(WINDOW *window, QString interface); + void mainmenu(WINDOW *window); +}; diff --git a/tui/tui.pro b/tui/tui.pro index 2c113f0..9bd1cc6 100644 --- a/tui/tui.pro +++ b/tui/tui.pro @@ -6,7 +6,10 @@ TEMPLATE = app TARGET = tui QT += core -SOURCES += main.cpp +SOURCES += main.cpp \ + menu.cpp + +HEADERS += menu.h LIBS += -lncurses