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>