Annotation of embedaddon/lrzsz/src/tcp.c, revision 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>