Annotation of embedaddon/lrzsz/src/tcp.c, revision 1.1.1.1
1.1 misho 1: /*
2: tcp.c - tcp handling for lrzsz
3: Copyright (C) 1997 Uwe Ohse
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 2, or (at your option)
8: any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18: 02111-1307, USA.
19:
20: originally written by Uwe Ohse
21: */
22:
23: #include "config.h"
24:
25: #include <sys/types.h>
26: #include <sys/socket.h>
27: #include <netinet/in.h>
28: #include <netdb.h>
29: #ifdef HAVE_ARPA_INET_H
30: #include <arpa/inet.h>
31: #endif
32: #include <errno.h>
33: #include <ctype.h>
34: #include <stdio.h>
35: #include <signal.h>
36:
37: #include "zglobal.h"
38: #include <stdlib.h>
39: #include "error.h"
40:
41: static RETSIGTYPE
42: tcp_alarm_handler(int dummy LRZSZ_ATTRIB_UNUSED)
43: {
44: /* doesn't need to do anything */
45: }
46:
47:
48: /* server/lsz:
49: * Get a TCP socket, bind it, listen, figure out the port,
50: * and build the magic string for lrz in "buf".
51: */
52: int
53: tcp_server (char *buf)
54: {
55: int sock;
56: struct sockaddr_in s;
57: struct sockaddr_in t;
58: int on=1;
59: size_t len;
60:
61: if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
62: error(1,errno,"socket");
63: }
64: if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
65: error(1,errno,"setsockopt (reuse address)");
66: }
67: memset (&s, 0, sizeof (s));
68: s.sin_family = AF_INET;
69: s.sin_port=0; /* let system fill it in */
70: s.sin_addr.s_addr=htonl(INADDR_ANY);
71: if (bind(sock, (struct sockaddr *)&s, sizeof (s)) < 0) {
72: error(1,errno,"bind");
73: }
74: len=sizeof(t);
75: if (getsockname (sock, (struct sockaddr *) &t, &len)) {
76: error(1,errno,"getsockname");
77: }
78: sprintf(buf,"[%s] <%d>\n",inet_ntoa(t.sin_addr),ntohs(t.sin_port));
79:
80: if (listen(sock, 1) < 0) {
81: error(1,errno,"listen");
82: }
83: getsockname (sock, (struct sockaddr *) &t, &len);
84:
85: return (sock);
86: }
87:
88: /* server/lsz: accept a connection */
89: int
90: tcp_accept (int d)
91: {
92: int so;
93: struct sockaddr_in s;
94: size_t namelen;
95: int num=0;
96:
97: namelen = sizeof(s);
98: memset((char*)&s,0, namelen);
99:
100: retry:
101: signal(SIGALRM, tcp_alarm_handler);
102: alarm(30);
103: if ((so = accept(d, (struct sockaddr*)&s, &namelen)) < 0) {
104: if (errno == EINTR) {
105: if (++num<=5)
106: goto retry;
107: }
108: error(1,errno,"accept");
109: }
110: alarm(0);
111: return so;
112: }
113:
114: /* client/lrz:
115: * "Connect" to the TCP socket decribed in "buf" and
116: * return the connected socket.
117: */
118: int
119: tcp_connect (char *buf)
120: {
121: int sock;
122: struct sockaddr_in s_in;
123: char *p;
124: char *q;
125:
126: memset(&s_in,0,sizeof(s_in));
127: s_in.sin_family = AF_INET;
128:
129: /* i _really_ distrust scanf & co. Or maybe i distrust bad input */
130: if (*buf!='[') {
131: error(1,0,_("tcp_connect: illegal format1\n"));
132: }
133: p=strchr(buf+1,']');
134: if (!p) {
135: error(1,0,_("tcp_connect: illegal format2\n"));
136: }
137: *p++=0;
138: s_in.sin_addr.s_addr=inet_addr(buf+1);
139: #ifndef INADDR_NONE
140: #define INADDR_NONE (-1)
141: #endif
142: if (s_in.sin_addr.s_addr== (unsigned long) INADDR_NONE) {
143: struct hostent *h=gethostbyname(buf+1);
144: if (!h)
145: error(1,0,_("tcp_connect: illegal format3\n"));
146: memcpy(& s_in.sin_addr.s_addr,h->h_addr,h->h_length);
147: }
148: while (isspace((unsigned char)(*p)))
149: p++;
150: if (*p!='<') {
151: error(1,0,_("tcp_connect: illegal format4\n"));
152: }
153: q=strchr(p+1,'>');
154: if (!q)
155: error(1,0,_("tcp_connect: illegal format5\n"));
156: s_in.sin_port = htons(strtol(p+1,NULL,10));
157:
158: if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
159: error(1,errno,"socket");
160: }
161:
162: signal(SIGALRM, tcp_alarm_handler);
163: alarm(30);
164: if (connect (sock, (struct sockaddr *) &s_in, sizeof (s_in)) < 0) {
165: error(1,errno,"connect");
166: }
167: alarm(0);
168: return (sock);
169: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>