summaryrefslogtreecommitdiff
authorjosef <josef>2002-10-20 19:22:38 (UTC)
committer josef <josef>2002-10-20 19:22:38 (UTC)
commitd5433091ba9741f0fae104d038b906e353065e2d (patch) (side-by-side diff)
tree70def8957a6b38f8b6cfb45fa352b5a77f2298a1
parent557c615b4b07adb798283981f3769dd817a80bf1 (diff)
downloadopie-d5433091ba9741f0fae104d038b906e353065e2d.zip
opie-d5433091ba9741f0fae104d038b906e353065e2d.tar.gz
opie-d5433091ba9741f0fae104d038b906e353065e2d.tar.bz2
Some fixes for receiving files via {x,y,z}modem:
- let transfer dialog reset progress bar when finished - typo: s/Sent/Received in received confirmation dialog - specify filename for xmodem (the man page is not very clear about this, but it doesn't work without filename!) - add --overwrite Here's the big problem: For user security, I'd rather use --rename than --overwrite (or make it configurable). But: * --rename is not supported at all by rx/rz/... * --overwrite is not supported by ymodem * --overwrite is always used by xmodem even if not used I want to kick the authors of rz now... Anybody knows a solution?
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/filereceive.cpp7
-rw-r--r--noncore/apps/opie-console/transferdialog.cpp7
2 files changed, 12 insertions, 2 deletions
diff --git a/noncore/apps/opie-console/filereceive.cpp b/noncore/apps/opie-console/filereceive.cpp
index e517862..e387273 100644
--- a/noncore/apps/opie-console/filereceive.cpp
+++ b/noncore/apps/opie-console/filereceive.cpp
@@ -1,157 +1,162 @@
#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 );
+ if( m_type == SX )
+ // FIXME: file name should be configurable - currently we ensure it
+ // doesn't get overwritten by -E (--rename)
+ execlp("rz", "rz", typus, "--overwrite", QObject::tr("SynchronizedFile").latin1(), NULL );
+ else
+ execlp("rz", "rz", typus, "--overwrite", 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 );
for (int i = 0; i < len; i++ ) {
// printf("%c", ar[i] );
}
ar.resize( len );
QString str( ar );
}
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/transferdialog.cpp b/noncore/apps/opie-console/transferdialog.cpp
index ac5b1d0..f89723c 100644
--- a/noncore/apps/opie-console/transferdialog.cpp
+++ b/noncore/apps/opie-console/transferdialog.cpp
@@ -1,261 +1,266 @@
#include <qlayout.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qmessagebox.h>
#include <qprogressbar.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <opie/ofiledialog.h>
#include "file_layer.h"
#include "receive_layer.h"
#include "metafactory.h"
#include "mainwindow.h"
#include "transferdialog.h"
TransferDialog::TransferDialog(QWidget *parent, MainWindow *mainwindow, const char *name)
: QDialog(parent, 0l, true), m_win(mainwindow)
{
m_lay = 0l;
m_recvlay = 0l;
QVBoxLayout *vbox, *vbox2;
QHBoxLayout *hbox, *hbox2, *hbox3;
QLabel *file, *mode, *progress, *status;
QButtonGroup *group;
QRadioButton *mode_send, *mode_receive;
m_autocleanup = 0;
group = new QButtonGroup(QObject::tr("Transfer mode"), this);
mode_send = new QRadioButton(QObject::tr("Send"), group);
mode_receive = new QRadioButton(QObject::tr("Receive"), group);
group->insert(mode_send, id_send);
group->insert(mode_receive, id_receive);
vbox2 = new QVBoxLayout(group, 2);
vbox2->addSpacing(10);
hbox3 = new QHBoxLayout(vbox2, 2);
hbox3->add(mode_send);
hbox3->add(mode_receive);
mode_send->setChecked(true);
m_transfermode = id_send;
file = new QLabel(QObject::tr("Send file"), this);
mode = new QLabel(QObject::tr("Transfer protocol"), this);
progress = new QLabel(QObject::tr("Progress"), this);
status = new QLabel(QObject::tr("Status"), this);
statusbar = new QLabel(QObject::tr("Ready"), this);
statusbar->setFrameStyle(QFrame::Panel | QFrame::Sunken);
protocol = new QComboBox(this);
QStringList list = m_win->factory()->fileTransferLayers();
for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
protocol->insertItem((*it));
filename = new QLineEdit(this);
progressbar = new QProgressBar(this);
progressbar->setProgress(0);
selector = new QPushButton("...", this);
ok = new QPushButton(QObject::tr("Start transfer"), this);
cancel = new QPushButton(QObject::tr("Cancel"), this);
vbox = new QVBoxLayout(this, 2);
vbox->add(group);
vbox->add(file);
hbox = new QHBoxLayout(vbox, 0);
hbox->add(filename);
hbox->add(selector);
vbox->add(mode);
vbox->add(protocol);
vbox->add(progress);
vbox->add(progressbar);
vbox->add(status);
vbox->add(statusbar);
vbox->addStretch(1);
hbox2 = new QHBoxLayout(vbox, 2);
hbox2->add(ok);
hbox2->add(cancel);
setCaption(QObject::tr("File transfer"));
show();
connect(selector, SIGNAL(clicked()), SLOT(slotFilename()));
connect(ok, SIGNAL(clicked()), SLOT(slotTransfer()));
connect(cancel, SIGNAL(clicked()), SLOT(slotCancel()));
connect(group, SIGNAL(clicked(int)), SLOT(slotMode(int)));
}
TransferDialog::~TransferDialog()
{
}
void TransferDialog::slotFilename()
{
QString f;
f = OFileDialog::getOpenFileName(0);
if(!f.isNull()) filename->setText(f);
}
void TransferDialog::slotTransfer()
{
if((m_transfermode == id_send) && (filename->text().isEmpty()))
{
QMessageBox::information(this,
QObject::tr("Attention"),
QObject::tr("No file has been specified."));
return;
}
ok->setEnabled(false);
cleanup();
m_autocleanup = 0;
if(m_transfermode == id_send) statusbar->setText(QObject::tr("Sending..."));
else statusbar->setText(QObject::tr("Receiving..."));
if(m_transfermode == id_send)
{
m_lay = m_win->factory()->newFileTransfer(protocol->currentText(), m_win->currentSession()->layer());
m_lay->sendFile(filename->text());
connect(m_lay, SIGNAL(progress(const QString&, int, int, int, int, int)),
SLOT(slotProgress(const QString&, int, int, int, int, int)));
connect(m_lay, SIGNAL(error(int, const QString&)), SLOT(slotError(int, const QString&)));
connect(m_lay, SIGNAL(sent()), SLOT(slotSent()));
}
else
{
m_recvlay = m_win->factory()->newReceive(protocol->currentText(), m_win->currentSession()->layer());
m_recvlay->receive();
connect(m_recvlay, SIGNAL(progress(const QString&, int, int, int, int, int)),
SLOT(slotProgress(const QString&, int, int, int, int, int)));
connect(m_recvlay, SIGNAL(error(int, const QString&)), SLOT(slotError(int, const QString&)));
connect(m_recvlay, SIGNAL(received(const QString&)), SLOT(slotReceived(const QString&)));
}
}
void TransferDialog::cleanup()
{
if(m_lay)
{
m_lay->cancel();
delete m_lay;
m_lay = 0l;
}
if(m_recvlay)
{
m_recvlay->cancel();
delete m_recvlay;
m_recvlay = 0l;
}
}
void TransferDialog::slotCancel()
{
ok->setEnabled(true);
statusbar->setText(QObject::tr("Ready"));
if((m_lay) || (m_recvlay))
{
cleanup();
if(m_autocleanup) close();
else
{
QMessageBox::information(this,
QObject::tr("Cancelled"),
QObject::tr("The file transfer has been cancelled."));
}
}
else
{
close();
}
}
void TransferDialog::slotProgress(const QString& file, int progress, int speed, int hours, int minutes, int seconds)
{
progressbar->setProgress(progress);
}
void TransferDialog::slotError(int error, const QString& message)
{
statusbar->setText(QObject::tr("Ready"));
switch(error)
{
case FileTransferLayer::NotSupported:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("Operation not supported."));
break;
case FileTransferLayer::StartError:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("Transfer could not be started."));
break;
case FileTransferLayer::NoError:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("No error."));
break;
case FileTransferLayer::Undefined:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("Undefined error occured."));
break;
case FileTransferLayer::Incomplete:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("Incomplete transfer."));
break;
case FileTransferLayer::Unknown:
default:
QMessageBox::critical(this,
QObject::tr("Error"),
QObject::tr("Unknown error occured."));
break;
}
m_autocleanup = 1;
}
void TransferDialog::slotSent()
{
+ progressbar->setProgress(100);
QMessageBox::information(this, QObject::tr("Sent"), QObject::tr("File has been sent."));
ok->setEnabled(true);
+ progressbar->setProgress(0);
statusbar->setText(QObject::tr("Ready"));
m_autocleanup = 1;
}
void TransferDialog::slotReceived(const QString& file)
{
- QMessageBox::information(this, QObject::tr("Sent"), QObject::tr("File has been received as %1.").arg(file));
+ progressbar->setProgress(100);
+ QMessageBox::information(this, QObject::tr("Received"), QObject::tr("File has been received."));
+ //QMessageBox::information(this, QObject::tr("Sent"), QObject::tr("File has been received as %1.").arg(file));
ok->setEnabled(true);
+ progressbar->setProgress(0);
statusbar->setText(QObject::tr("Ready"));
m_autocleanup = 1;
}
void TransferDialog::slotMode(int id)
{
if(id == id_send)
{
selector->setEnabled(true);
filename->setEnabled(true);
}
else
{
selector->setEnabled(false);
filename->setEnabled(false);
}
m_transfermode = id;
}