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