diff --git a/example/RemoteTerm/README.md b/example/RemoteTerm/README.md new file mode 100644 index 0000000..78cc885 --- /dev/null +++ b/example/RemoteTerm/README.md @@ -0,0 +1,8 @@ +A simple example showing how to use QTermWidget to control and display a remote terminal. + +To run this example, you should: +1. Build client-side program. In my PC, I use 'apt-get' to install the QTermWidget library. +2. Start the shell-srv.py with specific paramenters.This will expose a shell via socket. +3. Start the client-side program from commandline with specific paramenters. + +Now you will get your own remote terminal work with QTermWidget. \ No newline at end of file diff --git a/example/RemoteTerm/RemoteTerm.pro b/example/RemoteTerm/RemoteTerm.pro new file mode 100644 index 0000000..21c36f7 --- /dev/null +++ b/example/RemoteTerm/RemoteTerm.pro @@ -0,0 +1,34 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-10-31T00:37:59 +# +#------------------------------------------------- + +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = RemoteTerm +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 + +SOURCES += \ + main.cpp \ + remoteterm.cpp + +HEADERS += \ + remoteterm.h + +unix:!macx: LIBS += -lqtermwidget5 diff --git a/example/RemoteTerm/main.cpp b/example/RemoteTerm/main.cpp new file mode 100644 index 0000000..f51df3a --- /dev/null +++ b/example/RemoteTerm/main.cpp @@ -0,0 +1,19 @@ +#include "remoteterm.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + if(a.arguments().size() != 3){ + qDebug() << "Example(client-side) for remote terminal of QTermWidget."; + qDebug() << QString("Usage: %1 ipaddr port").arg(a.arguments()[0]); + return 1; + } + QString ipaddr = a.arguments().at(1); + quint16 port = a.arguments().at(2).toUShort(); + RemoteTerm w(ipaddr,port); + w.show(); + + return a.exec(); +} diff --git a/example/RemoteTerm/remoteterm.cpp b/example/RemoteTerm/remoteterm.cpp new file mode 100644 index 0000000..551ac25 --- /dev/null +++ b/example/RemoteTerm/remoteterm.cpp @@ -0,0 +1,32 @@ +#include "remoteterm.h" +#include +#include +#include + +RemoteTerm::RemoteTerm(const QString &ipaddr, quint16 port, QWidget *parent) + : QTermWidget(0,parent) +{ + socket = new QTcpSocket(this); + + // Write what we input to remote terminal via socket + connect(this, &RemoteTerm::sendData,[this](const char *data, int size){ + this->socket->write(data, size); + }); + + // Read anything from remote terminal via socket and show it on widget. + connect(socket,&QTcpSocket::readyRead,[this](){ + QByteArray data = socket->readAll(); + write(this->getPtySlaveFd(), data.data(), data.size()); + }); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(atError())); + + // Here we start an empty pty. + this->startTerminalTeletype(); + + socket->connectToHost(ipaddr, port); +} + +void RemoteTerm::atError() +{ + qDebug() << socket->errorString(); +} diff --git a/example/RemoteTerm/remoteterm.h b/example/RemoteTerm/remoteterm.h new file mode 100644 index 0000000..c591ec4 --- /dev/null +++ b/example/RemoteTerm/remoteterm.h @@ -0,0 +1,19 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include + +class QTcpSocket; + +class RemoteTerm : public QTermWidget +{ + Q_OBJECT +public: + RemoteTerm(const QString &ipaddr, quint16 port, QWidget *parent = 0); +public slots: + void atError(); +private: + QTcpSocket *socket; +}; + +#endif // WIDGET_H diff --git a/example/RemoteTerm/shell-srv.py b/example/RemoteTerm/shell-srv.py new file mode 100644 index 0000000..dc0cb62 --- /dev/null +++ b/example/RemoteTerm/shell-srv.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import sys +import os +import socket +import pty + +def usage(program): + print "Example(server-side) for remote terminal of QTermWidget." + print "Usage: %s ipaddr port" %program + + +def main(): + if len(sys.argv) != 3: + usage(sys.argv[0]) + sys.exit(1) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.bind((sys.argv[1], int(sys.argv[2]))) + s.listen(0) + print "[+]Start Server." + except Exception as e: + print "[-]Error Happened: %s" %e.message + sys.exit(2) + + while True: + c = s.accept() + os.dup2(c[0].fileno(), 0) + os.dup2(c[0].fileno(), 1) + os.dup2(c[0].fileno(), 2) + + # It's important to use pty to spawn the shell. + pty.spawn("/bin/sh") + c[0].close() + +if __name__ == "__main__": + main()