示例#1
0
文件: scp.c 项目: CUEBoxer/OpenStudio
int ssh_scp_close(ssh_scp scp){
  char buffer[128];
  int err;
  if(scp->channel != NULL){
    if(channel_send_eof(scp->channel) == SSH_ERROR){
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    /* avoid situations where data are buffered and
     * not yet stored on disk. This can happen if the close is sent
     * before we got the EOF back
     */
    while(!channel_is_eof(scp->channel)){
      err=channel_read(scp->channel,buffer,sizeof(buffer),0);
      if(err==SSH_ERROR)
        break;
    }
    if(channel_close(scp->channel) == SSH_ERROR){
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    channel_free(scp->channel);
    scp->channel=NULL;
  }
  scp->state=SSH_SCP_NEW;
  return SSH_OK;
}
示例#2
0
/**
 * @brief Close a channel.
 *
 * This sends an end of file and then closes the channel. You won't be able
 * to recover any data the server was going to send or was in buffers.
 *
 * @param channel       The channel to close.
 *
 * @return SSH_SUCCESS on success\n
 *         SSH_ERROR on error
 *
 * @see channel_free()
 * @see channel_eof()
 */
int channel_close(CHANNEL *channel){
  SSH_SESSION *session = channel->session;
  int rc = 0;

  enter_function();

  if (channel->local_eof == 0) {
    rc = channel_send_eof(channel);
  }

  if (rc != SSH_OK) {
    leave_function();
    return rc;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_CLOSE) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->remote_channel)) < 0) {
    goto error;
  }

  rc = packet_send(session);
  ssh_log(session, SSH_LOG_PACKET,
      "Sent a close on client channel (%d:%d)",
      channel->local_channel,
      channel->remote_channel);

  if(rc == SSH_OK) {
    channel->open = 0;
  }

  leave_function();
  return rc;
error:
  buffer_free(session->out_buffer);

  leave_function();
  return rc;
}
示例#3
0
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);

	}
}
示例#4
0
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);
}
示例#5
0
/**
 * 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;
}