1/*
2 * tcpsend [-t timeout] host port [files]
3 *
4 * open a TCP/IP connection to port on host and send files
5 *  Super lightweight LPR ???
6 * tcpsend.c,v 1.1 2000/10/14 21:11:23 papowell Exp
7 */
8
9#include <unistd.h>
10#include <stdlib.h>
11#include <sys/types.h>
12#include <fcntl.h>
13#include <sys/socket.h>
14#include <stdio.h>
15#include <netinet/in.h>
16#include <netdb.h>
17#include <arpa/inet.h>
18#include <errno.h>
19#include <string.h>
20#include <signal.h>
21
22char *Prog = "???";
23
24char *msg[] = {
25	"use: %s [-t timeout] host port [files]",
26	"  -t timeout  - try connecting for timeout seconds",
27	0
28};
29
30int max_try = 10;
31
32void do_send( int sock, int fd, char *name );
33void Set_linger( int sock, int n );
34
35void usage(void)
36{
37	int i;
38	fprintf( stderr, msg[0], Prog );
39	fprintf( stderr, "\n");
40	for( i = 1; msg[i]; ++i ){
41		fprintf( stderr, "%s\n", msg[i] );
42	}
43	exit(1);
44}
45
46char buffer[10*1024];
47
48int main( int argc, char **argv )
49{
50	int n, try;
51	int sock;	         /* socket */
52	char *s, *host, *port;
53	struct sockaddr_in dest_sin;     /* inet socket address */
54	struct hostent *host_ent = 0;
55
56	(void)signal( SIGPIPE, SIG_IGN );
57	if( argv[0] ) Prog = argv[0];
58	if( (s = strrchr(Prog,'/')) ){
59		Prog = s+1;
60	}
61	while( (n = getopt(argc, argv, "t:")) != EOF ){
62		switch(n){
63		case 't': max_try = atoi(optarg); break;
64		default: usage(); break;
65		}
66	}
67	if( argc - optind < 2 ) usage();
68
69
70	sock = -1;
71	memset(&dest_sin, 0, sizeof (dest_sin));
72
73	host = argv[optind++];
74	port = argv[optind++];
75
76	if( (host_ent = gethostbyname( host )) ){
77		dest_sin.sin_family = host_ent->h_addrtype;
78		if( host_ent->h_length > sizeof( dest_sin.sin_addr ) ){
79			fprintf(stderr,"%s: address length wrong\n", Prog);
80			exit(1);
81		}
82		memcpy(&dest_sin.sin_addr, host_ent->h_addr_list[0], host_ent->h_length );
83	} else
84		/* if( inet_pton( AF_INET, host, &dest_sin.sin_addr ) != 1 ){ */
85		if( (dest_sin.sin_addr.s_addr = inet_addr( host )) == -1 ){
86		fprintf(stderr,"%s: cannot find address for '%s'\n", Prog, host );
87		exit(1);
88	}
89	n = atoi(port);
90	if( n <= 0 ){
91		fprintf(stderr,"%s: bad port '%s'\n", Prog, port );
92		exit(1);
93	}
94	dest_sin.sin_port = htons(n);
95    /* we get the printable from the socket address */
96#if 0
97    fprintf(stderr, "connect to '%s',port %d\n",
98		inet_ntoa( dest_sin.sin_addr )),
99		(int) ntohs(dest_sin.sin_port) );
100#endif
101	try = 0;
102	do{
103		if( sock != -1 ) close(sock );
104		sock = -1;
105		sock = socket(AF_INET, SOCK_STREAM, 0 );
106#ifdef WINDOW_1
107int windowsize=1024;
108setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&windowsize, sizeof(windowsize));
109aaaaaa=fopen("/tmp/qqqqq", "a");
110fprintf(aaaaaa, "tcp_send: main\n");
111fclose(aaaaaa);
112#endif
113		if( sock == -1 ){
114			fprintf(stderr,"%s: socket() failed '%s'\n", Prog, strerror(errno) );
115			exit(1);
116		}
117		n = connect(sock, (void *)&dest_sin, sizeof(dest_sin) );
118		if( n == -1 && ++try < max_try ){
119			sleep(1);
120		} else {
121			break;
122		}
123	}while( n == -1 );
124	if( n == -1 ){
125		fprintf(stderr, "%s: connect to '%s',port %d failed after %d tries - %s\n",
126			Prog,
127			inet_ntoa( dest_sin.sin_addr),
128			(int) ntohs(dest_sin.sin_port), try, strerror(errno) );
129		exit(1);
130	}
131	if( optind == argc ){
132		do_send( sock, 0, "stdin" );
133	} else for(; optind < argc; ++optind ){
134		if( (n = open(argv[optind], O_RDONLY, 0)) == -1 ){
135			fprintf(stderr, "%s: cannot open '%s' - %s\n",
136				Prog, argv[optind], strerror(errno) );
137			exit(1);
138		}
139		do_send( sock, n, argv[optind] );
140		close(n);
141	}
142	/* we shut down the connection */
143	shutdown(sock,1);
144	while( (n = read(sock,&buffer,sizeof(buffer))) > 0 );
145	close(sock);
146	return(0);
147}
148
149void do_send( int sock, int fd, char *name )
150{
151	int cnt, n, i;
152	while( (n = read(fd,buffer,sizeof(buffer))) > 0 ){
153		for( cnt = i = 0; cnt >= 0 && i < n; i += cnt ){
154			cnt = write(sock,buffer+i,n-i);
155		}
156		if( cnt < 0 ){
157			fprintf(stderr, "%s: cannot write to remote host - %s\n",
158				Prog, strerror(errno) );
159			exit(1);
160		}
161	}
162	if( n < 0 ){
163		fprintf(stderr, "%s: cannot read from '%s' - %s\n",
164			Prog, name, strerror(errno) );
165		exit(1);
166	}
167}
168