summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/filetransfer.cpp
blob: 78982bd2447a99edf4db12d8e62aa9c853cb1211 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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 );
}