File: io.c

package info (click to toggle)
proxytunnel 1.9.0%2Bsvn250-6
  • links: PTS
  • area: main
  • in suites: buster, stretch
  • size: 452 kB
  • ctags: 368
  • sloc: ansic: 2,082; makefile: 79; pascal: 18
file content (130 lines) | stat: -rw-r--r-- 3,855 bytes parent folder | download | duplicates (4)
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
/* Proxytunnel - (C) 2001-2008 Jos Visser / Mark Janssen    */
/* Contact:                  josv@osp.nl / maniac@maniac.nl */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/* io.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "proxytunnel.h"
#include "io.h"


/*
 * Read one line of data from the tunnel. Line is terminated by a
 * newline character. Result is stored in buf.
 */
int readline(PTSTREAM *pts) {
	char *p = buf;
	char c = 0;
	int i = 0;

	/* Read one character at a time into buf, until a newline is encountered. */
	while ( c != 10 && ( i < SIZE - 1 ) ) {
		if( stream_read( pts, &c ,1) < 0) {
			my_perror( "Socket read error" );
			exit( 1 );
		}

		*p = c;
		p++;
		i++;
	}

	*p = 0;

	if( args_info.verbose_flag ) {
		/* Copy line of data into dstr without trailing newline */
		char *dstr = malloc(sizeof(buf) + 1);
		strlcpy( dstr, buf, strlen(buf) - 1);
		if (strcmp(dstr, ""))
			message( " <- %s\n", dstr );
	}
	return strlen( buf );
}

/*
 * Bond stream1 and stream2 together; any data received in stream1 is relayed
 * to stream2, and vice-versa.
 */
void cpio(PTSTREAM *stream1, PTSTREAM *stream2) {
	fd_set readfds;
	fd_set writefds;
	fd_set exceptfds;
	int in_max_fd, out_max_fd, max_fd;

	/* Find the biggest file descriptor for select() */
	in_max_fd = MAX(stream_get_incoming_fd(stream1), stream_get_incoming_fd(stream2));
	out_max_fd = MAX(stream_get_outgoing_fd(stream1), stream_get_outgoing_fd(stream2));
	max_fd = MAX(in_max_fd, out_max_fd);

	/* We are never interested in sockets being available for write */
	FD_ZERO( &writefds );

	if( args_info.verbose_flag )
		message( "\nTunnel established.\n" );

	/* Only diamonds are forever :-) */
	while( 1==1 ) {
		/* Clear the interesting socket sets */
		FD_ZERO( &readfds );
		FD_ZERO( &exceptfds );

		/* We want to know whether stream1 or stream2 is ready for reading */
		FD_SET( stream_get_incoming_fd(stream1), &readfds );
		FD_SET( stream_get_incoming_fd(stream2), &readfds );

		/* And we want to know about exceptional conditions on either stream */
		FD_SET( stream_get_incoming_fd(stream1), &exceptfds );
		FD_SET( stream_get_outgoing_fd(stream1), &exceptfds );
		FD_SET( stream_get_incoming_fd(stream2), &exceptfds );
		FD_SET( stream_get_outgoing_fd(stream2), &exceptfds );

		/* Wait until something happens on the registered sockets/files */
		if ( select( max_fd + 1, &readfds, &writefds, &exceptfds, 0 ) < 0 ) {
			perror("select error");
			exit(1);
		}

		/*
		 * Is stream1 ready for read? If so, copy a block of data
		 * from stream1 to stream2. Or else if stream2
		 * is ready for read, copy a block of data from the
		 * stream2 to stream1. Otherwise an exceptional condition
		 * is flagged and the program is terminated.
		 */
		if ( FD_ISSET( stream_get_incoming_fd(stream1), &readfds ) ) {
			if ( stream_copy(stream1, stream2 ) )
				break;
		} else if( FD_ISSET( stream_get_incoming_fd(stream2), &readfds ) ) {
			if( stream_copy(stream2, stream1 ) )
				break;
		} else {
			my_perror( "Exceptional condition" );
			break;
		}
	}
	closeall();
}

// vim:noexpandtab:ts=4