added demo of signal/uid handling feature
[tridge/junkcode.git] / netpipe.c
1 #include <stdio.h>
2 #include <strings.h>
3 #include <sys/types.h>
4 #include <sys/wait.h>
5 #include <sys/time.h>
6 #include <sys/socket.h>
7 #include <sys/ioctl.h>
8 #include <netinet/in.h>
9 #include <netdb.h>
10
11 #include <signal.h>
12
13 #include <errno.h>
14
15
16 int FROM = 6005;
17 int TO = 6000;
18 char host_name[100];
19 struct hostent *hp;
20 struct sockaddr_in sock_in;
21 struct sockaddr_in sock_out;
22 int s;
23 struct sockaddr in_addr;
24 int in_addrlen;
25 int in_fd,out_fd;
26 #define BUFSIZE 4096
27 char buffer[BUFSIZE];
28
29 void transfer(int from,int to)
30 {
31   int num_ready,num_read,ret;
32   ioctl(from, FIONREAD, &num_ready);
33
34
35   num_read = read(from,buffer,num_ready<BUFSIZE?num_ready:BUFSIZE);
36   
37   if (num_read == 0)
38     {
39       fprintf(stderr,"read 0 bytes. exiting.\n");
40       exit(0);
41     }
42
43   ret = write(to,buffer,num_read);
44
45   if (ret < 0)
46         perror("(child) write");
47
48   fprintf(stderr,"transfer(%d,%d): %d:%d\n",from,to,num_ready,ret);
49 }
50
51
52 int main(int argc,char *argv[])
53 {
54
55   if (argc < 3)
56         {
57           printf("Usage: netpipe <from_port> <to_port>\n");
58           return 0;
59         }
60
61   FROM = atoi(argv[1]);
62   TO = atoi(argv[2]);
63   
64   /* get my host name */
65   if (gethostname(host_name, sizeof(host_name)) == -1) 
66     {
67       perror("gethostname");
68       return -1;
69     } 
70
71   /* get host info */
72   if ((hp = gethostbyname(host_name)) == 0) 
73     {
74       /* Probly doesn't run TCP/IP. oh well. */
75       fprintf(stderr, "Gethostbyname: Unknown host.\n");
76       return -1;
77     }
78
79   memset(&sock_in, 0, sizeof(sock_in));
80   memcpy(&sock_in.sin_addr, hp->h_addr, hp->h_length);
81   sock_in.sin_port = htons( FROM );
82   sock_in.sin_family = hp->h_addrtype;
83   sock_in.sin_addr.s_addr = INADDR_ANY;
84   s = socket(hp->h_addrtype, SOCK_STREAM, 0);
85   if (s == -1) 
86     {
87       perror("socket");
88       return -1;
89     }
90
91   /* now we've got a socket - we need to bind it */
92   while (bind(s, (struct sockaddr * ) &sock_in,sizeof(sock_in)) < 0) 
93     {
94       perror("bind");
95       close(s);
96       return -1;
97     }
98
99   /* ready to listen */
100   if (listen(s, 5) == -1) 
101     {
102       perror("listen");
103       close(s);
104       return -1;
105     }
106
107
108   /* now accept incoming connections - forking a new process
109      for each incoming connection */
110   fprintf(stderr,"waiting for a connection\n");
111   while (in_fd = accept(s,&in_addr,&in_addrlen))
112     {
113       if (fork()==0)
114         {
115           fprintf(stderr,"child is starting in_fd=%d\n",in_fd);
116           
117           /* create a socket to write to */
118           out_fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
119           if (out_fd == -1) 
120             {
121               perror("(child) socket");
122               return -1;
123             }
124           
125           /* and connect it to the destination */
126           sock_out = sock_in;
127           sock_out.sin_port = htons(TO);
128           if (connect(out_fd,(struct sockaddr *)&sock_out,sizeof(sock_out))<0)
129             {
130               perror("(child) connect");
131               close(out_fd);
132               return -1;
133             }
134
135           /* now just do some reading and writing */
136           fprintf(stderr,"(child) entering select loop\n");
137           while (1)
138             {
139               fd_set fds;
140               int select_ret;
141
142               FD_ZERO(&fds);
143               FD_SET(in_fd, &fds);
144               FD_SET(out_fd, &fds);
145
146               if ((select_ret = select(255,&fds,NULL,NULL,NULL)) <= 0)
147                 {
148                   perror("(child) select");
149                   close(in_fd);
150                   close(out_fd);
151                   return -1;
152                 }
153
154               if (FD_ISSET(in_fd, &fds)) 
155                 transfer(in_fd,out_fd);
156
157               if (FD_ISSET(out_fd, &fds)) 
158                 transfer(out_fd,in_fd);
159                          
160             }
161
162         }
163     }
164
165   fprintf(stderr,"in_fd=%d. exiting.\n",in_fd);
166   close(s);
167 }
168
169
170
171
172
173
174
175
176