summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/filetransfer.cpp142
-rw-r--r--noncore/apps/opie-console/filetransfer.h38
-rw-r--r--noncore/apps/opie-console/io_layer.cpp3
-rw-r--r--noncore/apps/opie-console/io_layer.h7
-rw-r--r--noncore/apps/opie-console/io_serial.cpp7
-rw-r--r--noncore/apps/opie-console/io_serial.h1
-rw-r--r--noncore/apps/opie-console/sz_transfer.cpp121
7 files changed, 212 insertions, 107 deletions
diff --git a/noncore/apps/opie-console/filetransfer.cpp b/noncore/apps/opie-console/filetransfer.cpp
new file mode 100644
index 0000000..78982bd
--- a/dev/null
+++ b/noncore/apps/opie-console/filetransfer.cpp
@@ -0,0 +1,142 @@
+#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 "filetransfer.h"
+
+bool FileTransfer::terminate = false;
+pid_t FileTransfer::m_pid;
+
+FileTransfer::FileTransfer( Type t, IOLayer* lay )
+ : FileTransferLayer( lay ), m_type( t ) {
+ signal( SIGCHLD, signal_handler );
+}
+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_fd = layer()->rawIO();
+//
+// m_fd = ::open("/dev/ttyS0", O_RDWR);
+
+
+ if ( pipe( m_comm ) < 0 )
+ m_comm[0] = m_comm[1] = 0;
+ if ( pipe( m_info ) < 0 )
+ m_info[0] = m_info[1] = 0;
+
+ qWarning("output:"+file );
+ m_pid = fork();
+ switch( m_pid ) {
+ case 0:{
+ setupChild();
+ /* exec */
+ char* verbose = "-vv";
+ char* binray = "-b";
+
+
+ /* we should never return from here */
+ execlp("sz", "sz", verbose, binray, file.latin1(), 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 )
+ 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] );
+
+ terminate = false;
+ fd_set fds;
+ struct timeval timeout;
+ int sel;
+
+ /* replace by QSocketNotifier!!! */
+ while (!terminate) {
+ FD_ZERO( &fds );
+ FD_SET( m_comm[0], &fds );
+ sel = select( m_comm[0]+1, &fds, NULL, NULL, &timeout );
+ if (sel ) {
+ if ( FD_ISSET(m_comm[0], &fds ) ) {
+ printf("out:");
+ QByteArray ar(4096);
+ int len = read(m_comm[0], ar.data(), 4096 );
+ for (int i = 0; i < len; i++ ) {
+ // printf("%c", ar[i] );
+ }
+ printf("\n");
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+void FileTransfer::sendFile( const QFile& file ) {
+ sendFile( file.name() );
+}
+void FileTransfer::signal_handler(int ) {
+ int status;
+ signal( SIGCHLD, signal_handler );
+ waitpid( m_pid, &status, WNOHANG );
+ terminate = true;
+}
+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 );
+}
diff --git a/noncore/apps/opie-console/filetransfer.h b/noncore/apps/opie-console/filetransfer.h
new file mode 100644
index 0000000..06c6d12
--- a/dev/null
+++ b/noncore/apps/opie-console/filetransfer.h
@@ -0,0 +1,38 @@
+#ifndef OPIE_FILE_TRANSFER_H
+#define OPIE_FILE_TRANSFER_H
+
+#include <sys/types.h>
+
+#include <qfile.h>
+
+#include "file_layer.h"
+
+class QSocketNotifier;
+class OProcess;
+class FileTransfer : public FileTransferLayer{
+ Q_OBJECT
+public:
+ enum Type {
+ SZ = 0,
+ SX,
+ SY
+ };
+ FileTransfer( Type t, IOLayer* );
+ ~FileTransfer();
+
+ void sendFile( const QString& file );
+ void sendFile( const QFile& );
+
+private slots:
+ void setupChild();
+private:
+ static pid_t m_pid;
+ int m_fd;
+ int m_info[2];
+ int m_comm[2];
+ Type m_type;
+ static void signal_handler(int);
+ static bool terminate;
+};
+
+#endif
diff --git a/noncore/apps/opie-console/io_layer.cpp b/noncore/apps/opie-console/io_layer.cpp
index 563a252..79d47f5 100644
--- a/noncore/apps/opie-console/io_layer.cpp
+++ b/noncore/apps/opie-console/io_layer.cpp
@@ -1,14 +1,17 @@
#include "io_layer.h"
IOLayer::IOLayer()
: QObject()
{
}
IOLayer::IOLayer(const Profile &)
: QObject()
{
}
IOLayer::~IOLayer() {
}
+int IOLayer::rawIO()const{
+ return -1;
+}
diff --git a/noncore/apps/opie-console/io_layer.h b/noncore/apps/opie-console/io_layer.h
index b891b2b..7745021 100644
--- a/noncore/apps/opie-console/io_layer.h
+++ b/noncore/apps/opie-console/io_layer.h
@@ -1,87 +1,94 @@
#ifndef OPIE_IO_LAYER_H
#define OPIE_IO_LAYER_H
#include <qobject.h>
#include <qpe/config.h>
#include "profile.h"
/**
* This is the base class for IO Layers
* It will used to sent and recv data( QByteArray )
* it
*/
class IOLayer : public QObject {
Q_OBJECT
public:
enum Error {
NoError = -1,
Refuse = 0,
CouldNotOpen =1,
ClosedUnexpected =2,
ClosedError =3,
Terminate = 4
/* add more errors here */
};
/**
* a small c'tor
*/
IOLayer();
/**
* create an IOLayer instance from a config file
* the currently set group stores the profile/session
* information
*/
IOLayer( const Profile& );
/**
* destructor
*/
virtual ~IOLayer();
/**
* a small internal identifier
*/
virtual QString identifier() const = 0;
/**
* a short name
*/
virtual QString name() const = 0;
+
+ /**
+ * a file descriptor which opens
+ * the device for io but does not
+ * do any ioctling on it...
+ */
+ virtual int rawIO()const;
signals:
/**
* received input as QCString
*/
virtual void received( const QByteArray& ) = 0;
/**
* an error occured
* int for the error number
* and QString for a text
*/
virtual void error( int, const QString& ) = 0;
public slots:
/**
* send a QCString to the device
*/
virtual void send( const QByteArray& ) = 0;
/**
* bool open
*/
virtual bool open() = 0;
/**
* close the io
*/
virtual void close() = 0;
/**
* closes and reloads the settings
*/
virtual void reload( const Profile& ) = 0;
};
#endif
diff --git a/noncore/apps/opie-console/io_serial.cpp b/noncore/apps/opie-console/io_serial.cpp
index 929aeff..845f4be 100644
--- a/noncore/apps/opie-console/io_serial.cpp
+++ b/noncore/apps/opie-console/io_serial.cpp
@@ -1,177 +1,182 @@
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <unistd.h>
#include "io_serial.h"
IOSerial::IOSerial(const Profile &config) : IOLayer(config) {
m_read = 0l;
m_error = 0l;
m_fd = 0;
reload(config);
}
IOSerial::~IOSerial() {
if (m_fd) {
close();
}
}
void IOSerial::send(const QByteArray &data) {
if (m_fd) {
write(m_fd, data.data(), data.size());
} else {
emit error(Refuse, tr("Not connected"));
}
}
void IOSerial::close() {
if (m_fd) {
delete m_read;
delete m_error;
::close(m_fd);
m_fd = 0;
} else {
emit error(Refuse, tr("Not connected"));
}
}
bool IOSerial::open() {
qWarning("open");
if (!m_fd) {
qWarning("going to open %s", m_device.latin1());
struct termios tty;
m_fd = ::open(m_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (m_fd < 0) {
qWarning(" fd < 0 ");
emit error(CouldNotOpen, strerror(errno));
return FALSE;
}
tcgetattr(m_fd, &tty);
/* Baud rate */
int speed = baud(m_baud);
if (speed == -1) {
qWarning("speed -1");
emit error(Refuse, tr("Invalid baud rate"));
}
cfsetospeed(&tty, speed);
cfsetispeed(&tty, speed);
/* Take care of Space / Mark parity */
if (m_dbits == 7 && (m_parity == ParitySpace || m_parity == ParityMark)) {
m_dbits = 8;
}
/* Data bits */
switch (m_dbits) {
case 5: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5; break;
case 6: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6; break;
case 7: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7; break;
case 8: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; break;
default: break;
}
/* Raw, no echo mode */
tty.c_iflag = IGNBRK;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cflag |= CLOCAL | CREAD;
/* Stop bits */
if (m_sbits == 2) {
tty.c_cflag |= CSTOPB;
} else {
tty.c_cflag &= ~CSTOPB;
}
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 5;
/* Flow control */
if (m_flow & FlowSW)
tty.c_iflag |= IXON | IXOFF;
else
tty.c_iflag &= ~(IXON|IXOFF|IXANY);
if (m_flow & FlowHW)
tty.c_cflag |= CRTSCTS;
else
tty.c_cflag &= ~CRTSCTS;
/* Parity */
tty.c_cflag &= ~(PARENB | PARODD);
if (m_parity & ParityEven)
tty.c_cflag |= PARENB;
else if (m_parity & ParityOdd)
tty.c_cflag |= (PARENB | PARODD);
/* Set the changes */
tcsetattr(m_fd, TCSANOW, &tty);
/* Notifications on read & errors */
m_read = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
m_error = new QSocketNotifier(m_fd, QSocketNotifier::Exception, this);
connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived()));
connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured()));
return TRUE;
} else {
qWarning("opened");
emit error(Refuse, tr("Device is already connected"));
m_fd = 0;
return FALSE;
}
}
void IOSerial::reload(const Profile &config) {
m_device = config.readEntry("Device", SERIAL_DEFAULT_DEVICE);
qWarning( "Dev" +m_device );
qWarning( "Conf:" +config.readEntry("Device") );
m_baud = config.readNumEntry("Baud", SERIAL_DEFAULT_BAUD);
m_parity = config.readNumEntry("Parity", SERIAL_DEFAULT_PARITY);
m_dbits = config.readNumEntry("DataBits", SERIAL_DEFAULT_DBITS);
m_sbits = config.readNumEntry("StopBits", SERIAL_DEFAULT_SBITS);
m_flow = config.readNumEntry("Flow", SERIAL_DEFAULT_FLOW);
}
int IOSerial::baud(int baud) const {
switch (baud) {
case 300: return B300; break;
case 600: return B600; break;
case 1200: return B1200; break;
case 2400: return B2400; break;
case 4800: return B4800; break;
case 9600: return B9600; break;
case 19200: return B19200; break;
case 38400: return B38400; break;
case 57600: return B57600; break;
case 115200: return B115200; break;
}
return -1;
}
void IOSerial::errorOccured() {
emit error(ClosedUnexpected, strerror(errno));
close();
}
void IOSerial::dataArrived() {
- QByteArray array(4096);
+ QByteArray array(4097);
int len = read(m_fd, array.data(), 4096);
if (len == 0)
close();
if (len < 0)
return;
array.resize( len );
emit received(array);
}
QString IOSerial::identifier() const {
return "serial";
}
QString IOSerial::name() const {
return "RS232 Serial IO Layer";
}
+int IOSerial::rawIO()const {
+ int fd = ::open(m_device, O_RDWR );
+
+ return fd;
+};
diff --git a/noncore/apps/opie-console/io_serial.h b/noncore/apps/opie-console/io_serial.h
index 521dac6..00a6d2c 100644
--- a/noncore/apps/opie-console/io_serial.h
+++ b/noncore/apps/opie-console/io_serial.h
@@ -1,63 +1,64 @@
#ifndef OPIE_IO_SERIAL
#define OPIE_IO_SERIAL
#include <qsocketnotifier.h>
#include "io_layer.h"
/* Default values to be used if the profile information is incomplete */
#define SERIAL_DEFAULT_DEVICE "/dev/ttyS0"
#define SERIAL_DEFAULT_BAUD 9600
#define SERIAL_DEFAULT_PARITY 0
#define SERIAL_DEFAULT_DBITS 8
#define SERIAL_DEFAULT_SBITS 1
#define SERIAL_DEFAULT_FLOW 0
/* IOSerial implements a RS232 IO Layer */
class IOSerial : public IOLayer {
Q_OBJECT
public:
enum Parity {
ParityNone = 0,
ParityEven,
ParityOdd,
ParitySpace,
ParityMark
};
enum Flow {
FlowHW = 0x01,
FlowSW = 0x02
};
IOSerial(const Profile &);
~IOSerial();
QString identifier() const;
QString name() const;
+ int rawIO()const;
signals:
void received(const QByteArray &);
void error(int, const QString &);
public slots:
void send(const QByteArray &);
bool open();
void close();
void reload(const Profile &);
protected:
int baud(int baud) const;
protected slots:
void dataArrived();
void errorOccured();
protected:
QSocketNotifier *m_read;
QSocketNotifier *m_error;
QString m_device;
int m_baud;
int m_parity;
int m_dbits;
int m_sbits;
int m_flow;
int m_fd;
};
#endif /* OPIE_IO_SERIAL */
diff --git a/noncore/apps/opie-console/sz_transfer.cpp b/noncore/apps/opie-console/sz_transfer.cpp
index 41917c0..0a315cf 100644
--- a/noncore/apps/opie-console/sz_transfer.cpp
+++ b/noncore/apps/opie-console/sz_transfer.cpp
@@ -1,176 +1,85 @@
#include "sz_transfer.h"
#include <qfile.h>
#include <opie/oprocess.h>
#include <stdio.h>
#include <sys/termios.h>
-/* following function ripped out of minicom's sysdep2.c */
-
-
-/*
- * Set cbreak mode.
- * Mode 0 = normal.
- * Mode 1 = cbreak, no echo
- * Mode 2 = raw, no echo.
- * Mode 3 = only return erasechar (for wkeys.c)
- *
- * Returns: the current erase character.
- */
-
-static struct termios savetty;
-int setcbreak(int mode)
-{
-#if 1
- struct termios tty;
- static int init = 0;
- static int erasechar;
-
-
- if (init == 0) {
- tcgetattr(0, &savetty);
- erasechar = savetty.c_cc[VERASE];
- init++;
- }
-
- if (mode == 3) return(erasechar);
-
-
-
- /* Always return to default settings first */
- tcsetattr(0, TCSADRAIN, &savetty);
-
- if (mode == 0) {
- return(erasechar);
- }
-
- tcgetattr(0, &tty);
- if (mode == 1) {
- tty.c_oflag &= ~OPOST;
- tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
- tty.c_lflag &= ~(ICANON | ISIG | ECHO);
- tty.c_iflag &= ~(ICRNL|INLCR);
- tty.c_cflag |= CREAD;
- tty.c_cc[VTIME] = 5;
- tty.c_cc[VMIN] = 1;
- }
- if (mode == 2) { /* raw */
- tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
- IXANY | IXON | IXOFF | INPCK | ISTRIP);
- tty.c_iflag |= (BRKINT | IGNPAR);
- tty.c_oflag &= ~OPOST;
- tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
- tty.c_lflag &= ~(ICANON | ISIG | ECHO);
- tty.c_cflag |= CREAD;
- tty.c_cc[VTIME] = 5;
- tty.c_cc[VMIN] = 1;
- }
- tcsetattr(0, TCSADRAIN, &tty);
- return(erasechar);
-#else
- struct sgttyb args;
- static int init = 0;
- static int erasechar;
-
- if (init == 0) {
- (void) ioctl(0, TIOCGETP, &savetty);
- (void) ioctl(0, TIOCGETC, &savetty2);
- erasechar = savetty.sg_erase;
- init++;
- }
-
- if (mode == 3) return(erasechar);
-
- if (mode == 0) {
- (void) ioctl(0, TIOCSETP, &savetty);
- (void) ioctl(0, TIOCSETC, &savetty2);
- return(erasechar);
- }
-
- (void) ioctl(0, TIOCGETP, &args);
- if (mode == 1) {
- args.sg_flags |= CBREAK;
- args.sg_flags &= ~(ECHO|RAW);
- }
- if (mode == 2) {
- args.sg_flags |= RAW;
- args.sg_flags &= ~(ECHO|CBREAK);
- }
- (void) ioctl(0, TIOCSETP, &args);
- return(erasechar);
-#endif
-
-}
SzTransfer::SzTransfer(Type t, IOLayer *layer) : FileTransferLayer(layer), m_t(t)
{
}
SzTransfer::~SzTransfer() {
}
void SzTransfer::sendFile(const QFile& file) {
sendFile(file.name());
}
void SzTransfer::sendFile(const QString& file) {
//setcbreak(2); /* raw no echo */
proc = new OProcess;
*proc << "sz";
- *proc << "-v" << "-v" << "-v" << "-b" << file;
- connect(proc, SIGNAL(processExited(OProcess *)),
+ *proc << "-v" << "-v" << "-b" << file;
+ connect(proc, SIGNAL(processExited(OProcess *)),
this, SLOT(sent()));
- connect(proc, SIGNAL(receivedStdout(OProcess *, char *, int)),
+ connect(proc, SIGNAL(receivedStdout(OProcess *, char *, int)),
this, SLOT(SzReceivedStdout(OProcess *, char *, int)));
connect(proc, SIGNAL(receivedStderr(OProcess *, char *, int)),
this, SLOT(SzReceivedStderr(OProcess *, char *, int)));
connect(layer(), SIGNAL(received(const QByteArray &)),
this, SLOT(receivedStdin(const QByteArray &)));
proc->start(OProcess::NotifyOnExit, OProcess::All);
}
void SzTransfer::SzReceivedStdout(OProcess *, char *buffer, int buflen) {
- //qWarning("recieved from sz %d bytes", buflen);
+ qWarning("recieved from sz on stdout %d bytes", buflen);
QByteArray data(buflen);
data.fill(*buffer, buflen);
+ for (uint i = 0; i < data.count(); i++ ) {
+ printf("%c", buffer[i] );
+ }
+ printf("\n");
// send out through the io layer
- (layer())->send(data);
+ layer()->send(data);
}
void SzTransfer::SzReceivedStderr(OProcess *, char *buffer, int length) {
// parse and show data in a progress dialog/widget
- printf("\n");
- for (int i = 0; i < length; i++)
- printf("%c", buffer[i]);
+ printf("stderr:\n");
+ //for (int i = 0; i < length; i++)
+ // printf("%c", buffer[i]);
+ //printf("\n");
}
void SzTransfer::receivedStdin(const QByteArray &data) {
- //qWarning("recieved from io_serial %d bytes", data.size());
-
+ qWarning("recieved from io_serial %d bytes", data.size());
+
// recieved data from the io layer goes to sz
proc->writeStdin(data.data(), data.size());
}
void SzTransfer::sent() {
qWarning("sent file");
//setcbreak(0); /* default */
delete proc;
disconnect(layer(), SIGNAL(received(const QByteArray &)),
this, SLOT(receivedStdin(const QByteArray &)));
}