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>