/*
  tcp.c - tcp handling for lrzsz
  Copyright (C) 1997 Uwe Ohse

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.

  originally written by Uwe Ohse
*/

#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <signal.h>

#include "zglobal.h"
#include <stdlib.h>
#include "error.h"

static RETSIGTYPE
tcp_alarm_handler(int dummy)
{
	dummy++; /* doesn't need to do anything */
}

typedef union {
	struct sockaddr sa;
	struct sockaddr_in in;
} sock_addr;

/* server/lsz:
 * Get a TCP socket, bind it, listen, figure out the port,
 * and build the magic string for lrz in "buf".
 */
int 
tcp_server (char *buf)
{
	int sock;
	sock_addr s;
	sock_addr t;
	int on=1;
	socklen_t len;

	if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		error(1,errno,"socket");
	}
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
		error(1,errno,"setsockopt (reuse address)");
	}
	memset (&s, 0, sizeof (s));
	s.in.sin_family = AF_INET;
	s.in.sin_port=0; /* let system fill it in */
	s.in.sin_addr.s_addr=htonl(INADDR_ANY);
	if (bind(sock, &s.sa, sizeof (s)) < 0) {
		error(1,errno,"bind");
	}
	len=sizeof(t);
	if (getsockname (sock, &t.sa, &len)) {
		error(1,errno,"getsockname");
	}
	sprintf(buf,"[%s] <%d>\n",inet_ntoa(t.in.sin_addr),ntohs(t.in.sin_port));

	if (listen(sock, 1) < 0) {
		error(1,errno,"listen");
	}
	getsockname (sock, &t.sa, &len);

	return (sock);
}

/* server/lsz: accept a connection */
int 
tcp_accept (int d)
{
	int so;
	sock_addr s;
	socklen_t namelen;
	int num=0;

	namelen = sizeof(s);
	memset((char*)&s,0, namelen);

retry:
	signal(SIGALRM, tcp_alarm_handler);
	alarm(30);
	if ((so = accept(d, &s.sa, &namelen)) < 0) {
		if (errno == EINTR) {
			if (++num<=5)
				goto retry;
		}
		error(1,errno,"accept");
	}
	alarm(0);
	return so;
}

/* client/lrz:
 * "Connect" to the TCP socket decribed in "buf" and
 * return the connected socket.
 */
int 
tcp_connect (char *buf)
{
	int sock;
	sock_addr s_in;
	char *p;
	char *q;

	memset(&s_in,0,sizeof(s_in));
	s_in.in.sin_family = AF_INET;

	/* i _really_ distrust scanf & co. Or maybe i distrust bad input */
	if (*buf!='[') {
		error(1,0,_("tcp_connect: illegal format1\n"));
	}
	p=strchr(buf+1,']');
	if (!p) {
		error(1,0,_("tcp_connect: illegal format2\n"));
	}
	*p++=0;
	s_in.in.sin_addr.s_addr=inet_addr(buf+1);
#ifndef INADDR_NONE
#define INADDR_NONE (-1)
#endif
	if (s_in.in.sin_addr.s_addr== (unsigned long) INADDR_NONE) {
		struct hostent *h=gethostbyname(buf+1);
		if (!h)
			error(1,0,_("tcp_connect: illegal format3\n"));
		memcpy(& s_in.in.sin_addr.s_addr,h->h_addr,h->h_length);
	}
	while (isspace((unsigned char)(*p)))
		p++;
	if (*p!='<') {
		error(1,0,_("tcp_connect: illegal format4\n"));
	}
	q=strchr(p+1,'>');
	if (!q)
		error(1,0,_("tcp_connect: illegal format5\n"));
	s_in.in.sin_port = htons(strtol(p+1,NULL,10));

	if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		error(1,errno,"socket");
	}

	signal(SIGALRM, tcp_alarm_handler);
	alarm(30);
	if (connect (sock, &s_in.sa, sizeof (s_in)) < 0) {
		error(1,errno,"connect");
	}
	alarm(0);
	return (sock);
}
