1 /*
2 
3 $Header: io.c[1.10] Sun Aug 30 19:21:18 1992 nickel@cs.tu-berlin.de proposed $
4 This file is part of socket(1).
5 Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>
6 Please read the file COPYRIGHT for further details.
7 
8 */
9 
10 #define _BSD			/* AIX *loves* this */
11 
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #ifdef ISC
15 #include <sys/bsdtypes.h>
16 #endif
17 #include <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include "globals.h"
23 
24 /* read from from, write to to. select(2) has returned, so input
25  * must be available. */
do_read_write(from,to)26 int do_read_write(from, to)
27 int from, to ;
28 {
29     int size ;
30     char input_buffer[BUFSIZ] ;
31 
32     if ((size = read(from, input_buffer, BUFSIZ)) == -1) {
33 	perror2("read") ;
34 	return -1 ;
35     }
36     if (size == 0) {		/* end-of-file condition */
37 	if (from == active_socket) {
38 	    /* if it was the socket, the connection is closed */
39 	    if (verboseflag) {
40 		fprintf(stderr, "connection closed by peer\n") ;
41 	    }
42 	    return -1 ;
43 	} else {
44 	    if (quitflag) {
45 		/* we close connection later */
46 		if (verboseflag) {
47 		    fprintf(stderr, "connection closed\n") ;
48 		}
49 		return -1 ;
50 	    } else if (verboseflag) {
51 		fprintf(stderr, "end of input on stdin\n") ;
52 	    }
53 	    readonlyflag = 1 ;
54 	    return 1 ;
55 	}
56     }
57     return do_write(input_buffer, size, to) ;
58 
59 }
60 
61 /* write the buffer; in successive pieces, if necessary. */
do_write(buffer,size,to)62 int do_write(buffer, size, to)
63 char *buffer ;
64 int size, to ;
65 {
66     char buffer2[2 * BUFSIZ] ;	/* expanding lf's to crlf's can
67 				 * make the block twice as big at most */
68     int written ;
69 
70     if (crlfflag) {
71 	if (to == active_socket) {
72 	    add_crs(buffer, buffer2, &size) ;
73 	} else {
74 	    strip_crs(buffer, buffer2, &size) ;
75 	}
76     } else {
77 	bcopy(buffer, buffer2, size) ;
78     }
79     while (size > 0) {
80 	written = write(to, buffer2, size) ;
81 	if (written == -1) {
82 	    /* this should not happen */
83 	    perror2("write") ;
84 	    fprintf(stderr, "%s: error writing to %s\n",
85 		    progname,
86 		    to == active_socket ? "socket" : "stdout") ;
87 	    return -1 ;
88 	}
89 	size -= written ;
90     }
91     return 1 ;
92 }
93 
94 /* all IO to and from the socket is handled here. The main part is
95  * a loop around select(2). */
do_io()96 void do_io()
97 {
98     fd_set readfds ;
99     int fdset_width ;
100     int selret ;
101 
102     fdset_width = (IN > active_socket ? IN : active_socket) + 1 ;
103     while (1) {			/* this loop is exited sideways */
104 	/* set up file descriptor set for select(2) */
105 	FD_ZERO(&readfds) ;
106 	if (!readonlyflag) {
107 	    FD_SET(IN, &readfds) ;
108 	}
109 	if (!writeonlyflag) {
110 	    FD_SET(active_socket, &readfds) ;
111 	}
112 
113 	do {
114 	    /* wait until input is available */
115 	    selret = select(fdset_width, &readfds, NULL, NULL, NULL) ;
116 	    /* EINTR happens when the process is stopped */
117 	    if (selret < 0 && errno != EINTR) {
118 		perror2("select") ;
119 		exit(1) ;
120 	    }
121 	} while (selret <= 0) ;
122 
123 	/* do the appropriate read and write */
124 	if (FD_ISSET(active_socket, &readfds)) {
125 	    if (do_read_write(active_socket, OUT) < 0) {
126 		break ;
127 	    }
128 	} else {
129 	    if (do_read_write(IN, active_socket) < 0) {
130 		break ;
131 	    }
132 	}
133     }
134 }
135