working on sftp
This commit is contained in:
parent
d804da8881
commit
9f6dc1f3c2
|
@ -24,7 +24,7 @@ include_directories(
|
||||||
includes
|
includes
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(FooTerm src/main.cpp src/term_windows.cpp src/vte.cpp src/ssh.cpp src/eventloop.cpp)
|
add_executable(FooTerm src/main.cpp src/term_windows.cpp src/vte.cpp src/ssh.cpp src/eventloop.cpp src/panel.cpp includes/panel.hpp)
|
||||||
|
|
||||||
target_link_libraries(FooTerm
|
target_link_libraries(FooTerm
|
||||||
${GTKMM_LIBRARIES})
|
${GTKMM_LIBRARIES})
|
||||||
|
@ -32,8 +32,7 @@ target_link_libraries(FooTerm
|
||||||
target_link_libraries(FooTerm ${VTE_LIBRARIES})
|
target_link_libraries(FooTerm ${VTE_LIBRARIES})
|
||||||
add_definitions(${VTE_CFLAGS} ${VTE_CFLAGS_OTHER})
|
add_definitions(${VTE_CFLAGS} ${VTE_CFLAGS_OTHER})
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(third-party)
|
add_subdirectory(third-party)
|
||||||
find_package(fmt)
|
find_package(fmt)
|
||||||
|
|
||||||
target_link_libraries(FooTerm fmt::fmt ssh2)
|
target_link_libraries(FooTerm fmt::fmt ssh2 pthread util)
|
|
@ -9,7 +9,9 @@
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
class FooTermWindow;
|
||||||
|
|
||||||
struct EventLoopEntry {
|
struct EventLoopEntry {
|
||||||
enum {
|
enum {
|
||||||
|
@ -17,8 +19,14 @@ struct EventLoopEntry {
|
||||||
CHANNEL
|
CHANNEL
|
||||||
} entryType;
|
} entryType;
|
||||||
|
|
||||||
|
union {
|
||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
int out;
|
LIBSSH2_SFTP *sftp;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
int fdout;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventLoop {
|
class EventLoop {
|
||||||
|
@ -26,12 +34,14 @@ private:
|
||||||
std::vector<pollfd> pfds;
|
std::vector<pollfd> pfds;
|
||||||
std::vector<EventLoopEntry> outs;
|
std::vector<EventLoopEntry> outs;
|
||||||
bool isClosed{};
|
bool isClosed{};
|
||||||
|
FooTermWindow* window;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventLoop();
|
explicit EventLoop(FooTermWindow* window);
|
||||||
|
|
||||||
void registerFd(int fdin, EventLoopEntry entry);
|
void registerFd(int fdin, EventLoopEntry entry);
|
||||||
|
|
||||||
void run();
|
[[noreturn]] void run();
|
||||||
|
|
||||||
static void start(EventLoop *self) {
|
static void start(EventLoop *self) {
|
||||||
self->run();
|
self->run();
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
//
|
||||||
|
// Created by oupson on 01/03/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FOOTERM_PANEL_HPP
|
||||||
|
#define FOOTERM_PANEL_HPP
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <gtkmm/widget.h>
|
||||||
|
#include <gtkmm/paned.h>
|
||||||
|
#include <gtkmm/treemodel.h>
|
||||||
|
#include <gtkmm/treeview.h>
|
||||||
|
#include <gtkmm/liststore.h>
|
||||||
|
#include <gtkmm/scrolledwindow.h>
|
||||||
|
#include <gtkmm/listboxrow.h>
|
||||||
|
|
||||||
|
#include "vte.hpp"
|
||||||
|
|
||||||
|
class FileModel : public Gtk::TreeModel::ColumnRecord {
|
||||||
|
public:
|
||||||
|
FileModel() {
|
||||||
|
add(colName);
|
||||||
|
add(colSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk::TreeModelColumn<Glib::ustring> colName;
|
||||||
|
Gtk::TreeModelColumn<unsigned long> colSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Panel {
|
||||||
|
private:
|
||||||
|
Gtk::Paned paned;
|
||||||
|
Vte vte;
|
||||||
|
Session session;
|
||||||
|
|
||||||
|
FileModel fileModel;
|
||||||
|
std::filesystem::path path;
|
||||||
|
|
||||||
|
Gtk::ScrolledWindow mScrolledWindow;
|
||||||
|
Gtk::TreeView mTreeView;
|
||||||
|
Glib::RefPtr<Gtk::ListStore> mRefTreeModel;
|
||||||
|
|
||||||
|
void onCellDoubleClicked(const Gtk::TreePath &treePath, [[maybe_unused]] Gtk::TreeViewColumn *column);
|
||||||
|
|
||||||
|
void openSession(const char *host, int port, const char *username, const char *password);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Panel(EventLoop &eventLoop, const char *host, int port, const char *username, const char *password);
|
||||||
|
|
||||||
|
void listFiles();
|
||||||
|
|
||||||
|
Gtk::Paned &getPaned() {
|
||||||
|
return this->paned;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vte &getVte() {
|
||||||
|
return this->vte;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session &getSession() {
|
||||||
|
return this->session;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //FOOTERM_PANEL_HPP
|
|
@ -6,6 +6,7 @@
|
||||||
#define FOOTERM_SSH_HPP
|
#define FOOTERM_SSH_HPP
|
||||||
|
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -15,6 +16,7 @@ private:
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
int sock;
|
int sock;
|
||||||
|
LIBSSH2_SFTP* sftpSession;
|
||||||
|
|
||||||
static int openSocket(const char *addr, int port);
|
static int openSocket(const char *addr, int port);
|
||||||
|
|
||||||
|
@ -33,13 +35,21 @@ public:
|
||||||
|
|
||||||
bool isConnected();
|
bool isConnected();
|
||||||
|
|
||||||
int getSock() {
|
[[nodiscard]] int getSock() const {
|
||||||
return this->sock;
|
return this->sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LIBSSH2_SESSION *getSession() {
|
||||||
|
return this->session;
|
||||||
|
}
|
||||||
|
|
||||||
LIBSSH2_CHANNEL *getChannel() {
|
LIBSSH2_CHANNEL *getChannel() {
|
||||||
return this->channel;
|
return this->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBSSH2_SFTP* getSftp() {
|
||||||
|
return this->sftpSession;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SessionConnectException : public std::exception {
|
class SessionConnectException : public std::exception {
|
||||||
|
|
|
@ -5,22 +5,28 @@
|
||||||
#ifndef FOOTERM_TERM_WINDOWS_HPP
|
#ifndef FOOTERM_TERM_WINDOWS_HPP
|
||||||
#define FOOTERM_TERM_WINDOWS_HPP
|
#define FOOTERM_TERM_WINDOWS_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <gtkmm/window.h>
|
#include <gtkmm/window.h>
|
||||||
#include <gtkmm/notebook.h>
|
#include <gtkmm/notebook.h>
|
||||||
#include <vte/vte.h>
|
#include <vte/vte.h>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
|
||||||
|
#include "panel.hpp"
|
||||||
#include "eventloop.hpp"
|
#include "eventloop.hpp"
|
||||||
|
|
||||||
class FooTermWindow : public Gtk::Window {
|
class FooTermWindow : public Gtk::Window {
|
||||||
private:
|
private:
|
||||||
Gtk::Notebook notebook;
|
Gtk::Notebook notebook;
|
||||||
|
std::vector<Panel> panels;
|
||||||
EventLoop eventLoop;
|
EventLoop eventLoop;
|
||||||
|
|
||||||
void on_button_click();
|
void on_button_click();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FooTermWindow();
|
FooTermWindow();
|
||||||
|
|
||||||
|
std::vector<Panel> &getPanels() {
|
||||||
|
return panels;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FOOTERM_TERM_WINDOWS_HPP
|
#endif //FOOTERM_TERM_WINDOWS_HPP
|
||||||
|
|
|
@ -9,17 +9,18 @@
|
||||||
#include <gtkmm/widget.h>
|
#include <gtkmm/widget.h>
|
||||||
|
|
||||||
#include "eventloop.hpp"
|
#include "eventloop.hpp"
|
||||||
|
#include "ssh.hpp"
|
||||||
|
|
||||||
class Vte {
|
class Vte {
|
||||||
|
private:
|
||||||
|
GtkWidget *terminal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vte();
|
Vte();
|
||||||
|
|
||||||
void spawnShell(EventLoop &eventLoop, const char *host, int port, const char *username, const char *password);
|
void spawnShell(EventLoop &eventLoop, Session& session);
|
||||||
|
|
||||||
Gtk::Widget *asGtkWidget();
|
Gtk::Widget *asGtkWidget();
|
||||||
|
|
||||||
private:
|
|
||||||
GtkWidget *terminal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FOOTERM_VTE_HPP
|
#endif //FOOTERM_VTE_HPP
|
||||||
|
|
|
@ -2,11 +2,15 @@
|
||||||
// Created by oupson on 01/03/2022.
|
// Created by oupson on 01/03/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "eventloop.hpp"
|
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
EventLoop::EventLoop() = default;
|
#include "eventloop.hpp"
|
||||||
|
#include "term_windows.hpp"
|
||||||
|
|
||||||
|
EventLoop::EventLoop(FooTermWindow *window) {
|
||||||
|
this->window = window;
|
||||||
|
}
|
||||||
|
|
||||||
void EventLoop::registerFd(int fdin, EventLoopEntry entry) {
|
void EventLoop::registerFd(int fdin, EventLoopEntry entry) {
|
||||||
pollfd fd = {0};
|
pollfd fd = {0};
|
||||||
|
@ -18,16 +22,21 @@ void EventLoop::registerFd(int fdin, EventLoopEntry entry) {
|
||||||
|
|
||||||
#define BUFFER_SIZE (256)
|
#define BUFFER_SIZE (256)
|
||||||
|
|
||||||
void EventLoop::run() {
|
[[noreturn]] void EventLoop::run() {
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
ssize_t bytesRead;
|
ssize_t bytesRead;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma ide diagnostic ignored "EndlessLoop"
|
|
||||||
while (!this->isClosed) {
|
while (!this->isClosed) {
|
||||||
res = poll(this->pfds.data(), this->pfds.size(), 1000);
|
res = poll(this->pfds.data(), this->pfds.size(), 1000);
|
||||||
|
|
||||||
|
if (res == 0)
|
||||||
|
for (auto &value: this->window->getPanels()) {
|
||||||
|
auto session = value.getSession().getSession();
|
||||||
|
|
||||||
|
libssh2_keepalive_send(session, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -40,7 +49,7 @@ void EventLoop::run() {
|
||||||
bytesRead = libssh2_channel_read(this->outs[i].channel, buffer, BUFFER_SIZE);
|
bytesRead = libssh2_channel_read(this->outs[i].channel, buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
write(this->outs[i].out, buffer, bytesRead);
|
write(this->outs[i].fdout, buffer, bytesRead);
|
||||||
} else if (bytesRead < 0 && bytesRead != LIBSSH2_ERROR_EAGAIN) {
|
} else if (bytesRead < 0 && bytesRead != LIBSSH2_ERROR_EAGAIN) {
|
||||||
std::cout << bytesRead << std::endl;
|
std::cout << bytesRead << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -62,8 +71,6 @@ void EventLoop::run() {
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
|
||||||
}
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
//
|
||||||
|
// Created by oupson on 01/03/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <gtkmm/treemodelsort.h>
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
|
|
||||||
|
#include "panel.hpp"
|
||||||
|
|
||||||
|
Panel::Panel(EventLoop &eventLoop, const char *host, int port, const char *username, const char *password) : path("/") {
|
||||||
|
this->openSession(host, port, username, password);
|
||||||
|
this->vte.spawnShell(eventLoop, this->session);
|
||||||
|
|
||||||
|
this->paned.pack2(*this->vte.asGtkWidget());
|
||||||
|
this->paned.pack1(this->mScrolledWindow);
|
||||||
|
mScrolledWindow.add(mTreeView);
|
||||||
|
|
||||||
|
mScrolledWindow.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
|
||||||
|
// mScrolledWindow.set_expand();
|
||||||
|
|
||||||
|
mScrolledWindow.set_size_request(50);
|
||||||
|
|
||||||
|
mRefTreeModel = Gtk::ListStore::create(fileModel);
|
||||||
|
|
||||||
|
auto sortModel = Gtk::TreeModelSort::create(mRefTreeModel);
|
||||||
|
mTreeView.set_model(sortModel);
|
||||||
|
|
||||||
|
sortModel->set_sort_column(0, Gtk::SortType::SORT_ASCENDING);
|
||||||
|
|
||||||
|
mTreeView.append_column("Name", fileModel.colName);
|
||||||
|
mTreeView.append_column("Size", fileModel.colSize);
|
||||||
|
|
||||||
|
mTreeView.signal_row_activated().connect(sigc::mem_fun(this, &Panel::onCellDoubleClicked));
|
||||||
|
|
||||||
|
auto pColumn1 = mTreeView.get_column(0);
|
||||||
|
pColumn1->set_sort_column(fileModel.colName);
|
||||||
|
|
||||||
|
auto pColumn2 = mTreeView.get_column(1);
|
||||||
|
pColumn2->set_sort_column(fileModel.colSize);
|
||||||
|
|
||||||
|
listFiles();
|
||||||
|
|
||||||
|
this->paned.show_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::openSession(const char *host, int port, const char *username, const char *password) {
|
||||||
|
session.openConnection(host, port, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::onCellDoubleClicked(const Gtk::TreePath &treePath, [[maybe_unused]] Gtk::TreeViewColumn *column) {
|
||||||
|
auto row = *this->mTreeView.get_selection()->get_selected();
|
||||||
|
std::string nPath = row.get_value(fileModel.colName);
|
||||||
|
|
||||||
|
this->path.append(nPath);
|
||||||
|
|
||||||
|
listFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::listFiles() {
|
||||||
|
LIBSSH2_SFTP_HANDLE *dir;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
do {
|
||||||
|
dir = libssh2_sftp_opendir(session.getSftp(), this->path.c_str());
|
||||||
|
} while (dir == nullptr && libssh2_session_last_errno(session.getSession()) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
if (dir == nullptr && libssh2_session_last_errno(session.getSession()) < 0) {
|
||||||
|
char *error;
|
||||||
|
int errorLen;
|
||||||
|
libssh2_session_last_error(session.getSession(), &error, &errorLen, true);
|
||||||
|
|
||||||
|
throw SessionConnectException(fmt::format("unable to opendir \"{}\": {}", this->path.c_str(), error));
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
|
|
||||||
|
this->mRefTreeModel->clear();
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = libssh2_sftp_readdir(dir, buffer, sizeof(buffer) - 1, &attrs);
|
||||||
|
|
||||||
|
if (rc > 0 && !(buffer[0] == '.' && buffer[1] == 0)) {
|
||||||
|
auto row = *mRefTreeModel->append();
|
||||||
|
row[this->fileModel.colName] = buffer;
|
||||||
|
row[this->fileModel.colSize] = attrs.filesize;
|
||||||
|
//std::cerr << buffer << std::endl;
|
||||||
|
}
|
||||||
|
} while (rc > 0 || rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
char *error;
|
||||||
|
int errorLen;
|
||||||
|
libssh2_session_last_error(session.getSession(), &error, &errorLen, true);
|
||||||
|
throw SessionConnectException(fmt::format("unable to readdir \"{}\": {}", this->path.c_str(), error));
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = libssh2_sftp_closedir(dir);
|
||||||
|
} while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
char *error;
|
||||||
|
int errorLen;
|
||||||
|
libssh2_session_last_error(session.getSession(), &error, &errorLen, true);
|
||||||
|
throw SessionConnectException(fmt::format("unable to closedir \"{}\": {}", this->path.c_str(), error));
|
||||||
|
}
|
||||||
|
}
|
14
src/ssh.cpp
14
src/ssh.cpp
|
@ -2,22 +2,26 @@
|
||||||
// Created by oupson on 01/03/2022.
|
// Created by oupson on 01/03/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "ssh.hpp"
|
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
|
||||||
|
#include "ssh.hpp"
|
||||||
|
|
||||||
Session::Session() {
|
Session::Session() {
|
||||||
this->session = nullptr;
|
this->session = nullptr;
|
||||||
this->channel = nullptr;
|
this->channel = nullptr;
|
||||||
this->sock = -1;
|
this->sock = -1;
|
||||||
|
this->sftpSession = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Session::~Session() {
|
Session::~Session() {
|
||||||
|
// TODO
|
||||||
|
|
||||||
if (this->isConnected()) {
|
if (this->isConnected()) {
|
||||||
this->disconnect();
|
this->disconnect();
|
||||||
}
|
}
|
||||||
|
@ -134,6 +138,10 @@ void Session::openConnection(const char *addr, int port, const char *username, c
|
||||||
throw SessionConnectException(fmt::format("Failed to authenticate: {}", error));
|
throw SessionConnectException(fmt::format("Failed to authenticate: {}", error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
this->sftpSession = libssh2_sftp_init(this->session);
|
||||||
|
} while (this->sftpSession == nullptr && libssh2_session_last_errno(this->session) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
this->channel = libssh2_channel_open_session(session);
|
this->channel = libssh2_channel_open_session(session);
|
||||||
} while (this->channel == nullptr && libssh2_session_last_errno(this->session) == LIBSSH2_ERROR_EAGAIN);
|
} while (this->channel == nullptr && libssh2_session_last_errno(this->session) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
@ -154,6 +162,8 @@ void Session::openConnection(const char *addr, int port, const char *username, c
|
||||||
do {
|
do {
|
||||||
rc = libssh2_channel_shell(this->channel);
|
rc = libssh2_channel_shell(this->channel);
|
||||||
} while (rc == LIBSSH2_ERROR_EAGAIN);
|
} while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::disconnect() {
|
void Session::disconnect() {
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
// Created by oupson on 28/02/2022.
|
// Created by oupson on 28/02/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "vte.hpp"
|
|
||||||
#include "term_windows.hpp"
|
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <gtkmm/headerbar.h>
|
#include <gtkmm/headerbar.h>
|
||||||
|
@ -13,7 +12,11 @@
|
||||||
#include <gtkmm/grid.h>
|
#include <gtkmm/grid.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
FooTermWindow::FooTermWindow() {
|
#include "term_windows.hpp"
|
||||||
|
#include "vte.hpp"
|
||||||
|
#include "panel.hpp"
|
||||||
|
|
||||||
|
FooTermWindow::FooTermWindow() : eventLoop(this) {
|
||||||
this->set_default_size(800, 600);
|
this->set_default_size(800, 600);
|
||||||
this->add(notebook);
|
this->add(notebook);
|
||||||
|
|
||||||
|
@ -105,12 +108,16 @@ void FooTermWindow::on_button_click() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Vte *vte = new Vte();
|
auto *panel = new Panel(
|
||||||
vte->spawnShell(this->eventLoop, host.c_str(), port, username.c_str(), password.c_str());
|
this->eventLoop,
|
||||||
|
host.c_str(),
|
||||||
|
port,
|
||||||
|
username.c_str(),
|
||||||
|
password.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
Gtk::Widget *widget = vte->asGtkWidget();
|
this->notebook.append_page(panel->getPaned(), host, true);
|
||||||
this->notebook.append_page(*widget, host, true);
|
panel->getPaned().show_all();
|
||||||
widget->show();
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
20
src/vte.cpp
20
src/vte.cpp
|
@ -7,11 +7,10 @@
|
||||||
#include "ssh.hpp"
|
#include "ssh.hpp"
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <thread> // std::thread
|
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
static void got_child_exited([[maybe_unused]] VteTerminal *vte, gint status, [[maybe_unused]] Vte *window) {
|
static void got_child_exited([[maybe_unused]] VteTerminal *vte, [[maybe_unused]] gint status, [[maybe_unused]] Vte *window) {
|
||||||
// TODO WHEN LOCAL TERMINAL
|
// TODO WHEN LOCAL TERMINAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +28,13 @@ termStateCallback([[maybe_unused]] VteTerminal *terminal, GPid pid, GError *erro
|
||||||
|
|
||||||
Vte::Vte() {
|
Vte::Vte() {
|
||||||
this->terminal = vte_terminal_new();
|
this->terminal = vte_terminal_new();
|
||||||
|
|
||||||
|
#if VTE_CHECK_VERSION(0, 62, 0)
|
||||||
vte_terminal_set_enable_sixel(VTE_TERMINAL(this->terminal), true);
|
vte_terminal_set_enable_sixel(VTE_TERMINAL(this->terminal), true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vte::spawnShell(EventLoop &eventLoop, const char *host, int port, const char *username, const char *password) {
|
void Vte::spawnShell(EventLoop &eventLoop, Session& session) {
|
||||||
int master, slave;
|
int master, slave;
|
||||||
|
|
||||||
struct termios settings{};
|
struct termios settings{};
|
||||||
|
@ -45,21 +47,19 @@ void Vte::spawnShell(EventLoop &eventLoop, const char *host, int port, const cha
|
||||||
VtePty *pty = vte_pty_new_foreign_sync(master, nullptr, nullptr);
|
VtePty *pty = vte_pty_new_foreign_sync(master, nullptr, nullptr);
|
||||||
vte_terminal_set_pty(VTE_TERMINAL(this->terminal), pty);
|
vte_terminal_set_pty(VTE_TERMINAL(this->terminal), pty);
|
||||||
|
|
||||||
auto *s = new Session();
|
|
||||||
s->openConnection(host, port, username, password);
|
|
||||||
|
|
||||||
EventLoopEntry entry1{};
|
EventLoopEntry entry1{};
|
||||||
entry1.out = slave;
|
entry1.fdout = slave;
|
||||||
entry1.entryType = EventLoopEntry::CHANNEL;
|
entry1.entryType = EventLoopEntry::CHANNEL;
|
||||||
entry1.channel = s->getChannel();
|
entry1.channel = session.getChannel();
|
||||||
|
|
||||||
eventLoop.registerFd(s->getSock(), entry1);
|
eventLoop.registerFd(session.getSock(), entry1);
|
||||||
|
|
||||||
|
|
||||||
EventLoopEntry entry2{};
|
EventLoopEntry entry2{};
|
||||||
entry2.out = slave;
|
entry2.fdout = slave;
|
||||||
entry2.entryType = EventLoopEntry::DESCRIPTOR;
|
entry2.entryType = EventLoopEntry::DESCRIPTOR;
|
||||||
entry2.channel = s->getChannel();
|
entry2.channel = session.getChannel();
|
||||||
|
|
||||||
eventLoop.registerFd(slave, entry2);
|
eventLoop.registerFd(slave, entry2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue