nchan.c revision 1.2
1#include "includes.h" 2RCSID("$Id: nchan.c,v 1.2 1999/10/16 22:29:01 markus Exp $"); 3 4#include "ssh.h" 5 6#include "buffer.h" 7#include "channels.h" 8#include "packet.h" 9#include "nchan.h" 10 11void 12dump_chan(Channel *c){ 13 debug("chan %d type %d flags 0x%x", c->self, c->type, c->flags); 14} 15void 16chan_rcvd_ieof(Channel *c){ 17 dump_chan(c); 18 if(c->flags & CHAN_IEOF_RCVD){ 19 debug("chan_rcvd_ieof twice: %d",c->self); 20 return; 21 } 22 debug("rcvd_CHAN_IEOF %d",c->self); 23 c->flags |= CHAN_IEOF_RCVD; 24 /* cannot clear input buffer. remaining data has to be sent to client */ 25 chan_del_if_dead(c); 26} 27void 28chan_rcvd_oclose(Channel *c){ 29 dump_chan(c); 30 if(c->flags & CHAN_OCLOSE_RCVD){ 31 debug("chan_rcvd_oclose twice: %d",c->self); 32 return; 33 } 34 debug("rcvd_CHAN_OCLOSE %d",c->self); 35 c->flags |= CHAN_OCLOSE_RCVD; 36 /* our peer can no longer consume, so there is not need to read */ 37 chan_shutdown_read(c); 38 buffer_consume(&c->output, buffer_len(&c->output)); 39 /* Note: for type==OPEN IEOF is sent by channel_output_poll() */ 40 chan_del_if_dead(c); 41} 42void 43chan_send_ieof(Channel *c){ 44 if(c->flags & CHAN_IEOF_SENT){ 45 /* this is ok: it takes some time before we get OCLOSE */ 46 /* debug("send_chan_ieof twice %d", c->self); */ 47 return; 48 } 49 debug("send_CHAN_IEOF %d", c->self); 50 packet_start(CHAN_IEOF); 51 packet_put_int(c->remote_id); 52 packet_send(); 53 c->flags |= CHAN_IEOF_SENT; 54 dump_chan(c); 55} 56void 57chan_send_oclose(Channel *c){ 58 if(c->flags & CHAN_OCLOSE_SENT){ 59 debug("send_chan_oclose twice %d", c->self); 60 return; 61 } 62 debug("send_CHAN_OCLOSE %d", c->self); 63 packet_start(CHAN_OCLOSE); 64 packet_put_int(c->remote_id); 65 packet_send(); 66 c->flags |= CHAN_OCLOSE_SENT; 67 dump_chan(c); 68} 69void 70chan_shutdown_write(Channel *c){ 71 if(c->flags & CHAN_SHUT_WR){ 72 debug("chan_shutdown_write twice %d",c->self); 73 return; 74 } 75 debug("chan_shutdown_write %d", c->self); 76 if(shutdown(c->sock, SHUT_WR)<0) 77 error("chan_shutdown_write failed %.100s", strerror(errno)); 78 c->flags |= CHAN_SHUT_WR; 79 /* clear output buffer, since there is noone going to read the data 80 we just closed the output-socket */ 81 /* buffer_consume(&c->output, buffer_len(&c->output)); */ 82} 83void 84chan_shutdown_read(Channel *c){ 85 if(c->flags & CHAN_SHUT_RD){ 86 /* chan_shutdown_read is called for read-errors and OCLOSE */ 87 /* debug("chan_shutdown_read twice %d",c->self); */ 88 return; 89 } 90 debug("chan_shutdown_read %d", c->self); 91 if(shutdown(c->sock, SHUT_RD)<0) 92 error("chan_shutdown_read failed %.100s", strerror(errno)); 93 c->flags |= CHAN_SHUT_RD; 94} 95void 96chan_del_if_dead(Channel *c){ 97 if(c->flags == CHAN_CLOSED){ 98 debug("channel %d closing",c->self); 99 channel_free(c->self); 100 } 101} 102