00001 #include <unistd.h>
00002 #include <fcntl.h>
00003 #include <signal.h>
00004 #include <errno.h>
00005
00006 #include <qsocketnotifier.h>
00007
00008 #include "io_layer.h"
00009 #include "procctl.h"
00010 #include "filereceive.h"
00011
00012 FileReceive::FileReceive( Type t, IOLayer* lay, const QString& dir )
00013 : ReceiveLayer(lay, dir ), m_type( t )
00014 {
00015 m_fd = -1;
00016 m_not = 0l;
00017 m_proc = 0l;
00018 }
00019 FileReceive::~FileReceive() {
00020 }
00021 void FileReceive::receive() {
00022 receive( currentDir() );
00023 }
00024 void FileReceive::receive( const QString& dir ) {
00025 m_prog = -1;
00026 m_fd = layer()->rawIO();
00027 m_curDir = dir;
00028
00029 if (pipe( m_comm ) < 0 )
00030 m_comm[0] = m_comm[1] = 0;
00031 if (pipe( m_info ) < 0 )
00032 m_info[0] = m_info[1] = 0;
00033
00034 m_pid = fork();
00035 switch( m_pid ) {
00036 case -1:
00037
00038 slotExec();
00039 break;
00040
00041 case 0: {
00042 setupChild();
00043 char* typus = NULL;
00044 switch(m_type ) {
00045 case SZ:
00046 break;
00047 case SX:
00048 typus = "-X";
00049 break;
00050 case SY:
00051 typus = "--ymodem";
00052 break;
00053 }
00054
00055
00056 if( m_type == SX )
00057
00058
00059 execlp("rz", "rz", typus, "--overwrite", QObject::tr("SynchronizedFile").latin1(), NULL );
00060 else
00061 execlp("rz", "rz", typus, "--overwrite", NULL );
00062
00063 char resultByte = 1;
00064 if (m_info[1] )
00065 ::write(m_info[1], &resultByte, 1 );
00066
00067 _exit( -1 );
00068 break;
00069 }
00070 default: {
00071 if ( m_info[1] )
00072 close( m_info[1] );
00073
00074 if ( m_info[0] ) for (;;) {
00075 char resultByte; int len;
00076 len = read(m_info[0], &resultByte, 1 );
00077
00078 if ( len == 1 ) {
00079 emit error( StartError, tr("Could not start") );
00080 return;
00081 }
00082 if ( len == -1 )
00083 if ( (errno == ECHILD ) || (errno == EINTR ) )
00084 continue;
00085
00086
00087 break;
00088 }
00089
00090 if ( m_info[0] )
00091 close( m_info[0] );
00092
00093 m_not = new QSocketNotifier(m_comm[0], QSocketNotifier::Read );
00094 connect(m_not, SIGNAL(activated(int) ),
00095 this, SLOT(slotRead() ) );
00096 if ( pipe(m_term) < 0 )
00097 m_term[0] = m_term[1] = 0;
00098
00099 ProcCtl::self()->add(m_pid, m_term[1] );
00100 m_proc = new QSocketNotifier(m_term[0], QSocketNotifier::Read );
00101 connect(m_proc, SIGNAL(activated(int) ),
00102 this, SLOT(slotExec() ) );
00103
00104 }
00105 break;
00106
00107 }
00108
00109 }
00110 void FileReceive::cancel() {
00111 ::kill(m_pid, 9 );
00112 }
00113 void FileReceive::setupChild() {
00114 changeDir( currentDir() );
00115
00116
00117
00118
00119 if (m_info[0] )
00120 close(m_info[0] );
00121
00122
00123
00124
00125 if (m_info[1] )
00126 fcntl(m_info[1], F_SETFD, FD_CLOEXEC );
00127
00128 if (m_comm[0] )
00129 close( m_comm[0] );
00130
00131
00132
00133
00134
00135
00136 dup2( m_fd, STDIN_FILENO );
00137 dup2( m_fd, STDOUT_FILENO );
00138 dup2( m_comm[1], STDERR_FILENO );
00139 }
00140 void FileReceive::slotRead() {
00141 QByteArray ar(4096);
00142 int len = read(m_comm[0], ar.data(), 4096 );
00143 for (int i = 0; i < len; i++ ) {
00144
00145 }
00146 ar.resize( len );
00147 QString str( ar );
00148 }
00149 void FileReceive::slotExec() {
00150 char buf[2];
00151 ::read(m_term[0], buf, 1 );
00152 delete m_proc;
00153 delete m_not;
00154 m_not = m_proc = 0l;
00155 close( m_term[0] );
00156 close( m_term[1] );
00157 close( m_comm[0] );
00158 close( m_comm[1] );
00159 layer()->closeRawIO(m_fd);
00160 emit received(QString::null);
00161
00162 }