-rw-r--r-- | noncore/apps/opie-console/filereceive.cpp | 159 | ||||
-rw-r--r-- | noncore/apps/opie-console/filereceive.h | 42 | ||||
-rw-r--r-- | noncore/apps/opie-console/filetransfer.cpp | 7 | ||||
-rw-r--r-- | noncore/apps/opie-console/opie-console.pro | 8 | ||||
-rw-r--r-- | noncore/apps/opie-console/receive_layer.cpp | 33 | ||||
-rw-r--r-- | noncore/apps/opie-console/receive_layer.h | 22 | ||||
-rw-r--r-- | noncore/apps/opie-console/test/console.pro | 6 | ||||
-rw-r--r-- | noncore/apps/opie-console/test/sender.ui | 22 | ||||
-rw-r--r-- | noncore/apps/opie-console/test/senderui.cpp | 7 | ||||
-rw-r--r-- | noncore/apps/opie-console/test/senderui.h | 1 |
10 files changed, 292 insertions, 15 deletions
diff --git a/noncore/apps/opie-console/filereceive.cpp b/noncore/apps/opie-console/filereceive.cpp new file mode 100644 index 0000000..26b3dec --- a/dev/null +++ b/noncore/apps/opie-console/filereceive.cpp @@ -0,0 +1,159 @@ +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> + +#include <qsocketnotifier.h> + +#include "io_layer.h" +#include "procctl.h" +#include "filereceive.h" + +FileReceive::FileReceive( Type t, IOLayer* lay, const QString& dir ) + : ReceiveLayer(lay, dir ), m_type( t ) +{ + m_fd = -1; + m_not = 0l; + m_proc = 0l; +} +FileReceive::~FileReceive() { +} +void FileReceive::receive() { + receive( currentDir() ); +} +void FileReceive::receive( const QString& dir ) { + m_prog = -1; + m_fd = layer()->rawIO(); + m_curDir = dir; + + if (pipe( m_comm ) < 0 ) + m_comm[0] = m_comm[1] = 0; + if (pipe( m_info ) < 0 ) + m_info[0] = m_info[1] = 0; + + m_pid = fork(); + switch( m_pid ) { + case -1: + //emit error + slotExec(); + break; + /* child */ + case 0: { + setupChild(); + char* typus = NULL; + switch(m_type ) { + case SZ: + break; + case SX: + typus = "-X"; + break; + case SY: + typus = "--ymodem"; + break; + } + + /* we should never return from here */ + execlp("rz", "rz", typus, NULL ); + + char resultByte = 1; + if (m_info[1] ) + ::write(m_info[1], &resultByte, 1 ); + + _exit( -1 ); + break; + } + default: { + if ( m_info[1] ) + close( m_info[1] ); + + if ( m_info[0] ) for (;;) { + char resultByte; int len; + len = read(m_info[0], &resultByte, 1 ); + /* len == 1 start up failed */ + if ( len == 1 ) { + emit error( StartError, tr("Could not start") ); + return; + } + if ( len == -1 ) + if ( (errno == ECHILD ) || (errno == EINTR ) ) + continue; + + // len == 0 or something like this + break; + } + + if ( m_info[0] ) + close( m_info[0] ); + + m_not = new QSocketNotifier(m_comm[0], QSocketNotifier::Read ); + connect(m_not, SIGNAL(activated(int) ), + this, SLOT(slotRead() ) ); + if ( pipe(m_term) < 0 ) + m_term[0] = m_term[1] = 0; + + ProcCtl::self()->add(m_pid, m_term[1] ); + m_proc = new QSocketNotifier(m_term[0], QSocketNotifier::Read ); + connect(m_proc, SIGNAL(activated(int) ), + this, SLOT(slotExec() ) ); + + } + break; + + } + +} +void FileReceive::cancel() { + ::kill(m_pid, 9 ); +} +void FileReceive::setupChild() { + changeDir( currentDir() ); + /* + * we do not want to read from our + * information channel + */ + if (m_info[0] ) + close(m_info[0] ); + /* + * FD_CLOEXEC will close the + * fd on successfull exec + */ + if (m_info[1] ) + fcntl(m_info[1], F_SETFD, FD_CLOEXEC ); + + if (m_comm[0] ) + close( m_comm[0] ); + /* + * now set the communication + * m_fd STDIN_FILENO + * STDOUT_FILENO + * STDERR_FILENO + */ + dup2( m_fd, STDIN_FILENO ); + dup2( m_fd, STDOUT_FILENO ); + dup2( m_comm[1], STDERR_FILENO ); +} +void FileReceive::slotRead() { + QByteArray ar(4096); + int len = read(m_comm[0], ar.data(), 4096 ); + qWarning("slot read %d", len); + for (int i = 0; i < len; i++ ) { + // printf("%c", ar[i] ); + } + ar.resize( len ); + QString str( ar ); + qWarning(str.simplifyWhiteSpace() ); +} +void FileReceive::slotExec() { + char buf[2]; + ::read(m_term[0], buf, 1 ); + delete m_proc; + delete m_not; + m_not = m_proc = 0l; + close( m_term[0] ); + close( m_term[1] ); + close( m_comm[0] ); + close( m_comm[1] ); + layer()->closeRawIO(m_fd); + emit received(QString::null); + +} diff --git a/noncore/apps/opie-console/filereceive.h b/noncore/apps/opie-console/filereceive.h new file mode 100644 index 0000000..a525439 --- a/dev/null +++ b/noncore/apps/opie-console/filereceive.h @@ -0,0 +1,42 @@ +#ifndef OPIE_FILE_RECEIVE_H +#define OPIE_FILE_RECEIVE_H + +/** + * This is the receive Implementation + * for X-Modem/Y-Modem/Z-Modem + */ +#include <sys/types.h> + +#include "receive_layer.h" + +class QSocketNotifier; +class FileReceive : public ReceiveLayer { + Q_OBJECT +public: + enum Type { + SZ = 0, + SX, + SY + }; + FileReceive( Type t, IOLayer* lay, const QString& startDir = QString::null ); + ~FileReceive(); + void receive(); + void receive( const QString& dir ); + void cancel(); +private slots: + void setupChild(); + void slotRead(); + void slotExec(); +private: + pid_t m_pid; + int m_fd; + int m_prog; + int m_info[2]; + int m_comm[2]; + int m_term[2]; + Type m_type; + QSocketNotifier* m_not; + QSocketNotifier* m_proc; +}; + +#endif diff --git a/noncore/apps/opie-console/filetransfer.cpp b/noncore/apps/opie-console/filetransfer.cpp index 14787f6..8ca0df2 100644 --- a/noncore/apps/opie-console/filetransfer.cpp +++ b/noncore/apps/opie-console/filetransfer.cpp @@ -1,98 +1,100 @@ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <qcstring.h> #include <qsocketnotifier.h> #include <opie/oprocess.h> #include "procctl.h" #include "filetransfer.h" FileTransfer::FileTransfer( Type t, IOLayer* lay ) : FileTransferLayer( lay ), m_type( t ), m_pid ( 0 ) { signal(SIGPIPE, SIG_IGN ); + m_pid = 0; m_not = 0l; m_proc = 0l; } FileTransfer::~FileTransfer() { } /** * now we will send the file. * * we request an fd. The IOLayer should be closed * then we will setup a pipe for progress communication * then we will dup2 the m_fd in the forked process * to do direct IO from and to the fd */ void FileTransfer::sendFile( const QString& file ) { m_prog =-1; m_fd = layer()->rawIO(); // // m_fd = ::open("/dev/ttyS0", O_RDWR); m_file = file; if ( pipe( m_comm ) < 0 ) m_comm[0] = m_comm[1] = 0; if ( pipe( m_info ) < 0 ) m_info[0] = m_info[1] = 0; m_pid = fork(); switch( m_pid ) { case -1: emit error( StartError, tr("Was not able to fork") ); + slotExec(); break; case 0:{ setupChild(); qWarning("output:"+file ); /* exec */ char* verbose = "-vv"; char* binray = "-b"; char* typus; switch(m_type ) { case SZ: typus = ""; break; case SX: typus = "-X"; break; case SY: typus = "--ymodem"; break; } /* we should never return from here */ execlp("sz", "sz", verbose, binray, file.latin1(), typus, NULL ); /* communication for error!*/ char resultByte =1; if (m_info[1] ) write(m_info[1], &resultByte, 1 ); _exit( -1 ); break; } default:{ if ( m_info[1] ) close( m_info[1] ); if ( m_info[0] ) for (;;) { char resultByte; int len; len = read(m_info[0], &resultByte, 1 ); /* len == 1 start up failed */ if ( len == 1 ) { emit error( StartError, tr("Could not start") ); return; } if ( len == -1 ) if ( (errno == ECHILD ) || (errno == EINTR ) ) continue; // len == 0 or something like this @@ -132,122 +134,123 @@ void FileTransfer::sendFile( const QFile& file ) { */ void FileTransfer::setupChild() { /* * we do not want to read from our * information channel */ if (m_info[0] ) close(m_info[0] ); /* * FD_CLOEXEC will close the * fd on successfull exec */ if (m_info[1] ) fcntl(m_info[1], F_SETFD, FD_CLOEXEC ); if (m_comm[0] ) close( m_comm[0] ); /* * now set the communication * m_fd STDIN_FILENO * STDOUT_FILENO * STDERR_FILENO */ dup2( m_fd, STDIN_FILENO ); dup2( m_fd, STDOUT_FILENO ); dup2( m_comm[1], STDERR_FILENO ); } /* * read from the stderr of the child * process */ void FileTransfer::slotRead() { QByteArray ar(4096); int len = read(m_comm[0], ar.data(), 4096 ); qWarning("slot read %d", len); for (int i = 0; i < len; i++ ) { // printf("%c", ar[i] ); } ar.resize( len ); QString str( ar ); qWarning(str.simplifyWhiteSpace() ); QStringList lis = QStringList::split(' ', str ); /* * Transfer finished.. either complete or incomplete */ if ( lis[0].simplifyWhiteSpace() == "Transfer" ) { qWarning("sent!!!!"); - emit sent(); return; } /* * do progress reading */ slotProgress( lis ); } /* * find the progress */ void FileTransfer::slotProgress( const QStringList& list ) { if ( m_type != SZ ) return; bool complete = true; int min, sec; int bps; unsigned long sent, total; min = sec = bps = -1; sent = total = 0; // Data looks like this // 0 1 2 3 4 5 // Bytes Sent 65536/11534336 BPS:7784 ETA 24:33 QStringList progi = QStringList::split('/', list[2].simplifyWhiteSpace() ); sent = progi[0].toULong(&complete ); if (!complete ) return; total = progi[1].toULong(&complete ); if (!complete || total == 0) { return; } qWarning("%s, %d, %d", progi.join("/").latin1(), sent, total ); double pro = (double)sent/total; int prog = pro * 100; // speed progi = QStringList::split(':', list[3].simplifyWhiteSpace() ); bps = progi[1].toInt(); // time progi = QStringList::split(':', list[5].simplifyWhiteSpace() ); min = progi[0].toInt(); sec = progi[1].toInt(); if ( prog > m_prog ) { m_prog = prog; emit progress(m_file, m_prog, bps, -1, min , sec ); } } void FileTransfer::cancel() { if(m_pid > 0) ::kill(m_pid,9 ); - delete m_not; + } void FileTransfer::slotExec() { qWarning("exited!"); char buf[2]; ::read(m_term[0], buf, 1 ); delete m_proc; delete m_not; m_proc = m_not = 0l; close( m_term[0] ); close( m_term[1] ); close( m_comm[0] ); close( m_comm[1] ); + layer()->closeRawIO( m_fd ); emit sent(); + m_pid = 0; } diff --git a/noncore/apps/opie-console/opie-console.pro b/noncore/apps/opie-console/opie-console.pro index 8e39a48..0b4676b 100644 --- a/noncore/apps/opie-console/opie-console.pro +++ b/noncore/apps/opie-console/opie-console.pro @@ -1,68 +1,72 @@ TEMPLATE = app #CONFIG = qt warn_on release CONFIG = qt debug DESTDIR = $(OPIEDIR)/bin HEADERS = io_layer.h io_serial.h io_irda.h io_bt.h\ file_layer.h filetransfer.h \ metafactory.h \ session.h \ mainwindow.h \ profile.h \ profileconfig.h \ profilemanager.h \ configwidget.h \ tabwidget.h \ configdialog.h \ emulation_layer.h \ vt102emulation.h \ common.h \ history.h \ screen.h \ keytrans.h \ widget_layer.h \ transferdialog.h \ profiledialogwidget.h \ profileeditordialog.h \ default.h \ terminalwidget.h \ iolayerbase.h \ serialconfigwidget.h irdaconfigwidget.h \ btconfigwidget.h modemconfigwidget.h \ atconfigdialog.h dialdialog.h \ emulation_widget.h procctl.h \ - function_keyboard.h script.h + function_keyboard.h \ + receive_layer.h filereceive.h \ + script.h SOURCES = io_layer.cpp io_serial.cpp io_irda.cpp io_bt.cpp \ file_layer.cpp filetransfer.cpp \ main.cpp \ metafactory.cpp \ session.cpp \ mainwindow.cpp \ profile.cpp \ profileconfig.cpp \ profilemanager.cpp \ tabwidget.cpp \ configdialog.cpp \ emulation_layer.cpp \ vt102emulation.cpp \ history.cpp \ screen.cpp \ keytrans.cpp \ widget_layer.cpp \ transferdialog.cpp \ profiledialogwidget.cpp \ profileeditordialog.cpp \ terminalwidget.cpp \ iolayerbase.cpp \ serialconfigwidget.cpp irdaconfigwidget.cpp \ btconfigwidget.cpp modemconfigwidget.cpp \ atconfigdialog.cpp dialdialog.cpp \ emulation_widget.cpp default.cpp procctl.cpp \ - function_keyboard.cpp script.cpp + function_keyboard.cpp \ + receive_layer.cpp filereceive.cpp \ + script.cpp INTERFACES = configurebase.ui editbase.ui INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include LIBS += -lqpe -lopie TARGET = opie-console diff --git a/noncore/apps/opie-console/receive_layer.cpp b/noncore/apps/opie-console/receive_layer.cpp new file mode 100644 index 0000000..05e2c67 --- a/dev/null +++ b/noncore/apps/opie-console/receive_layer.cpp @@ -0,0 +1,33 @@ +#include <unistd.h> + +#include <qstring.h> +#include <qfile.h> + +#include "io_layer.h" +#include "receive_layer.h" + +ReceiveLayer::ReceiveLayer( IOLayer* lay, const QString& startDir ) + : QObject(), m_curDir( startDir ), m_layer(lay ) +{ + +} +ReceiveLayer::~ReceiveLayer() { + +} +IOLayer* ReceiveLayer::layer() { + return m_layer; +} +QString ReceiveLayer::currentDir()const{ + if (m_curDir.isEmpty() ) + return QString::fromLocal8Bit( ::getwd(NULL) ); + return m_curDir; +} +void ReceiveLayer::changeDir( const QString& str) { + ::chdir( str.latin1() ); +} +void ReceiveLayer::receive( const QString& dir, Mode, Features ) { + receive( dir ); +} +void ReceiveLayer::cancel() { + +} diff --git a/noncore/apps/opie-console/receive_layer.h b/noncore/apps/opie-console/receive_layer.h index 0cfe16d..157c7e5 100644 --- a/noncore/apps/opie-console/receive_layer.h +++ b/noncore/apps/opie-console/receive_layer.h @@ -1,113 +1,121 @@ #ifndef OPIE_RECEIVE_LAYER_H #define OPIE_RECEIVE_LAYER_H #include <qobject.h> /** * An abstract Layer for receiving files * from an IOLayer connection * It gives us the possibility to listen * to get progress to stop listen * to get errors */ class IOLayer; class ReceiveLayer : public QObject { Q_OBJECT public: /** * How to receive files * How handhel \r\n? * ASCII or binary */ enum Mode { Ascii = 0l, Binary }; /** * What features to use * DISCUSS IT!!!! * see rz --help for more info */ enum Features { Append = 0, AllowRemoteCommands = 1, WriteToNull = 2, Escape = 4, Rename = 8, OpenSync = 16, ProtectExisting = 32, Resume = 64, KeepUppercase = 128, DisableRestrict = 256, Restricted = 512, Overwrite = 1024 }; /** - * which protocol to use? + * Error codes */ - enum Type{ - SZ = 0, - SX, - SY + enum Error { + Unknown = 0, + StartError }; /** * C'tor constructs an new Object * @param lay The Layer to be used * @param t The Type * @param startDir In which dir should files be received? */ - ReceiveLayer( IOLayer* lay, Type t, const QString& startDir = QString::null ); + ReceiveLayer( IOLayer* lay, const QString& startDir = QString::null ); virtual ~ReceiveLayer(); public slots: /** * start receiving in current dir * with protocol from the c'tor */ virtual void receive() = 0; /** * start to receive in dir with type * from the c'tor */ virtual void receive( const QString& dir ) = 0; /** * advanced method with features and Mode */ - virtual void receive( const QString& dir, Mode, Features ) {} + virtual void receive( const QString& dir, Mode, Features ); /** * cancel receive */ virtual void cancel(); signals: /** * error happend * error code as int * and a QString for UI translated string */ void error(int, const QString& ); /** * progress * @param file The completed path to the file which is received * @param speed the speed in bps * @param hour The hours remaining * @param minutes The miniutes remaining * @param seconds The seconds remaining */ void progress( const QString& file, int progress, int speed, int hour, int min, int seconds ); /** * completely received a file */ void received( const QString& file ); +protected: + QString m_curDir; + IOLayer* layer(); + /* from a variable set from the outside */ + QString currentDir()const; + void changeDir( const QString& ); +private: + IOLayer* m_layer; + }; #endif diff --git a/noncore/apps/opie-console/test/console.pro b/noncore/apps/opie-console/test/console.pro index af0e9f7..6de2cd0 100644 --- a/noncore/apps/opie-console/test/console.pro +++ b/noncore/apps/opie-console/test/console.pro @@ -1,15 +1,17 @@ TEMPLATE = app #CONFIG = qt warn_on release CONFIG = qt debug #DESTDIR = $(OPIEDIR)/bin HEADERS = ../io_layer.h ../io_serial.h ../sz_transfer.h ../file_layer.h\ - senderui.h ../profile.h ../filetransfer.h ../procctl.h + senderui.h ../profile.h ../filetransfer.h ../procctl.h \ + ../filereceive.h ../receive_layer.h SOURCES = ../io_layer.cpp ../io_serial.cpp \ ../profile.cpp ../sz_transfer.cpp ../file_layer.cpp\ - main.cpp senderui.cpp ../filetransfer.cpp ../procctl.cpp + main.cpp senderui.cpp ../filetransfer.cpp ../procctl.cpp \ + ../filereceive.cpp ../receive_layer.cpp INTERFACES = sender.ui INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include LIBS += -lqpe -lopie TARGET = test diff --git a/noncore/apps/opie-console/test/sender.ui b/noncore/apps/opie-console/test/sender.ui index b946b81..74b9790 100644 --- a/noncore/apps/opie-console/test/sender.ui +++ b/noncore/apps/opie-console/test/sender.ui @@ -1,78 +1,96 @@ <!DOCTYPE UI><UI> <class>Sender</class> <widget> <class>QWidget</class> <property stdset="1"> <name>name</name> <cstring>Form1</cstring> </property> <property stdset="1"> <name>geometry</name> <rect> <x>0</x> <y>0</y> - <width>596</width> + <width>592</width> <height>480</height> </rect> </property> <property stdset="1"> <name>caption</name> <string>Form1</string> </property> <vbox> <property stdset="1"> <name>margin</name> <number>11</number> </property> <property stdset="1"> <name>spacing</name> <number>6</number> </property> <widget> <class>QMultiLineEdit</class> <property stdset="1"> <name>name</name> <cstring>MultiLineEdit1</cstring> </property> </widget> <widget> <class>QPushButton</class> <property stdset="1"> <name>name</name> + <cstring>PushButton3</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Receive File</string> + </property> + </widget> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> <cstring>PushButton1</cstring> </property> <property stdset="1"> <name>text</name> <string>&Send</string> </property> </widget> <widget> <class>QPushButton</class> <property stdset="1"> <name>name</name> <cstring>PushButton2</cstring> </property> <property stdset="1"> <name>text</name> <string>Send &File</string> </property> </widget> </vbox> </widget> <connections> <connection> <sender>PushButton1</sender> <signal>clicked()</signal> <receiver>Form1</receiver> <slot>slotSend()</slot> </connection> - <slot access="public">slotSend()</slot> <connection> <sender>PushButton2</sender> <signal>clicked()</signal> <receiver>Form1</receiver> <slot>slotSendFile()</slot> </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>Form1</receiver> + <slot>slotRev()</slot> + </connection> + <slot access="public">slotRev()</slot> + <slot access="public">slotSend()</slot> <slot access="public">slotSendFile()</slot> </connections> </UI> diff --git a/noncore/apps/opie-console/test/senderui.cpp b/noncore/apps/opie-console/test/senderui.cpp index 8bc1676..2ce3f6d 100644 --- a/noncore/apps/opie-console/test/senderui.cpp +++ b/noncore/apps/opie-console/test/senderui.cpp @@ -1,68 +1,75 @@ #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/termios.h> #include <qmultilineedit.h> #include <qsocketnotifier.h> #include "../profile.h" #include "../io_serial.h" #include "../filetransfer.h" +#include "../filereceive.h" #include <opie/oprocess.h> #include "senderui.h" SenderUI::SenderUI() : Sender() { /* we do that manually */ Profile prof; QString str = "/dev/ttyS0"; prof.writeEntry("Device",str ); prof.writeEntry("Baud", 115200 ); qWarning("prof " + prof.readEntry("Device") + " " + str); ser = new IOSerial(prof); connect(ser, SIGNAL(received(const QByteArray& ) ), this, SLOT(got(const QByteArray&) ) ); if ( ser->open() ) qWarning("opened!!!"); else qWarning("could not open"); } SenderUI::~SenderUI() { } void SenderUI::slotSendFile() { sz = new FileTransfer(FileTransfer::SY, ser); sz->sendFile("/home/ich/bootopie-v06-13.jffs2"); connect (sz, SIGNAL(sent()), this, SLOT(fileTransComplete())); } void SenderUI::slotSend() { QCString str = MultiLineEdit1->text().utf8(); qWarning("sending: %s", str.data() ); ser->send( str ); } void SenderUI::got(const QByteArray& ar) { for ( uint i = 0; i < ar.count(); i++ ) { printf("%c", ar[i] ); } //printf("\n"); } void SenderUI::fileTransComplete() { qWarning("file transfer complete"); } void SenderUI::send() { } +void SenderUI::slotRev(){ +qWarning("Going to receive!"); +FileReceive *rev = new FileReceive( FileReceive::SZ, ser ); +rev->receive(); + +}
\ No newline at end of file diff --git a/noncore/apps/opie-console/test/senderui.h b/noncore/apps/opie-console/test/senderui.h index 5e613cd..c130dcf 100644 --- a/noncore/apps/opie-console/test/senderui.h +++ b/noncore/apps/opie-console/test/senderui.h @@ -1,33 +1,34 @@ #ifndef SENDER_UI_H #define SENDER_UI_H #include <qcstring.h> #include "sender.h" class IOSerial; class FileTransfer; class QSocketNotifier; class OProcess; class SenderUI : public Sender { Q_OBJECT public: SenderUI(); ~SenderUI(); public slots: void send(); void slotSendFile(); void slotSend(); + void slotRev(); void got(const QByteArray& ); void fileTransComplete(); private: IOSerial* ser; FileTransfer* sz; int m_fd; QSocketNotifier* m_sock; OProcess* m_proc; }; #endif |