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