File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lrzsz / src / tcp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Thu Oct 24 15:49:50 2019 UTC (4 years, 11 months ago) by misho
Branches: lrzsz, MAIN
CVS tags: v0_12_20p5, HEAD
lrzsz ver 0.12.20

    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>