void select_loop(SSH_SESSION *session,CHANNEL *channel){ fd_set fds; struct timeval timeout; char buffer[10]; BUFFER *readbuf=buffer_new(); CHANNEL *channels[2]; int lus; int eof=0; int maxfd; int ret; while(channel){ /* when a signal is caught, ssh_select will return * with SSH_EINTR, which means it should be started * again. It lets you handle the signal the faster you * can, like in this window changed example. Of course, if * your signal handler doesn't call libssh at all, you're * free to handle signals directly in sighandler. */ do{ FD_ZERO(&fds); if(!eof) FD_SET(0,&fds); timeout.tv_sec=30; timeout.tv_usec=0; FD_SET(ssh_get_fd(session),&fds); maxfd=ssh_get_fd(session)+1; ret=select(maxfd,&fds,NULL,NULL,&timeout); if(ret==EINTR) continue; if(FD_ISSET(0,&fds)){ lus=read(0,buffer,10); if(lus) channel_write(channel,buffer,lus); else { eof=1; channel_send_eof(channel); } } if(FD_ISSET(ssh_get_fd(session),&fds)){ ssh_set_fd_toread(session); } channels[0]=channel; // set the first channel we want to read from channels[1]=NULL; ret=channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll if(signal_delayed) sizechanged(); } while (ret==EINTR || ret==SSH_EINTR); // we already looked for input from stdin. Now, we are looking for input from the channel if(channel && channel_is_closed(channel)){ channel_free(channel); channel=NULL; channels[0]=NULL; } if(channels[0]){ while(channel && channel_is_open(channel) && channel_poll(channel,0)){ lus=channel_read(channel,readbuf,0,0); if(lus==-1){ ssh_say(0,"error reading channel : %s\n",ssh_get_error(session)); return; } if(lus==0){ ssh_say(1,"EOF received\n"); channel_free(channel); channel=channels[0]=NULL; } else write(1,buffer_get(readbuf),lus); } while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */ lus=channel_read(channel,readbuf,0,1); if(lus==-1){ ssh_say(0,"error reading channel : %s\n",ssh_get_error(session)); return; } if(lus==0){ ssh_say(1,"EOF received\n"); channel_free(channel); channel=channels[0]=NULL; } else write(2,buffer_get(readbuf),lus); } } if(channel && channel_is_closed(channel)){ channel_free(channel); channel=NULL; } } buffer_free(readbuf); }
static void select_loop(ssh_session session,ssh_channel channel){ fd_set fds; struct timeval timeout; char buffer[4096]; /* channels will be set to the channels to poll. * outchannels will contain the result of the poll */ ssh_channel channels[2], outchannels[2]; int lus; int eof=0; int maxfd; int ret; while(channel){ do{ FD_ZERO(&fds); if(!eof) FD_SET(0,&fds); timeout.tv_sec=30; timeout.tv_usec=0; FD_SET(ssh_get_fd(session),&fds); maxfd=ssh_get_fd(session)+1; channels[0]=channel; // set the first channel we want to read from channels[1]=NULL; ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout); if(ret==EINTR) continue; if(FD_ISSET(0,&fds)){ lus=read(0,buffer,sizeof(buffer)); if(lus) channel_write(channel,buffer,lus); else { eof=1; channel_send_eof(channel); } } if(channel && channel_is_closed(channel)){ channel_free(channel); channel=NULL; channels[0]=NULL; } if(outchannels[0]){ while(channel && channel_is_open(channel) && channel_poll(channel,0)){ lus=channel_read(channel,buffer,sizeof(buffer),0); if(lus==-1){ fprintf(stderr, "Error reading channel: %s\n", ssh_get_error(session)); return; } if(lus==0){ channel_free(channel); channel=channels[0]=NULL; } else { ret = write(1, buffer, lus); if (ret < 0) { fprintf(stderr, "Error writing to stdin: %s", strerror(errno)); return; } } } while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */ lus=channel_read(channel,buffer,sizeof(buffer),1); if(lus==-1){ fprintf(stderr, "Error reading channel: %s\n", ssh_get_error(session)); return; } if(lus==0){ channel_free(channel); channel=channels[0]=NULL; } else { ret = write(2, buffer, lus); if (ret < 0) { fprintf(stderr, "Error writing to stderr: %s", strerror(errno)); return; } } } } if(channel && channel_is_closed(channel)){ channel_free(channel); channel=NULL; } } while (ret==EINTR || ret==SSH_EINTR); } }
/** * Launch a command over SSH * @param QString command The command to launch * @return bool true if it's ok, false else */ bool Kssh::launch(QString command) { this->init(); this->m_command = command; int result; ssh_channel channel = channel_new(this->m_session); if (channel == NULL) { Klog::error(QString("Impossible to open a new channel") + QString(ssh_get_error(this->m_session))); ssh_disconnect(this->m_session); ssh_finalize(); return false; } if (channel_open_session(channel) == SSH_ERROR) { Klog::error(QString("Impossible to open a session in the channel") + QString(ssh_get_error(this->m_session))); channel_close(channel); ssh_disconnect(this->m_session); ssh_finalize(); return false; } result = channel_request_exec(channel, this->m_command.toStdString().c_str()); if (result == SSH_ERROR) { Klog::error(QString("Impossible to launch command : ") + QString(ssh_get_error(this->m_session))); channel_close(channel); ssh_disconnect(this->m_session); ssh_finalize(); return false; } else { #ifdef DEBUG Klog::debug(QString("Execution de la commande : ") + this->m_command); #endif // read the buffer char *buf = NULL; buf = new char[512]; int rc = 0; do { if (channel_is_open(channel)) { rc = channel_read(channel, buf, sizeof(buf), 0); if (rc > 0) { this->m_return += QString::fromLatin1(buf, rc); } } } while (rc > 0); delete[] buf; channel_send_eof(channel); channel_close(channel); ssh_disconnect(this->m_session); ssh_finalize(); } return true; }