xref: /original-bsd/old/cpnull/cpnull.c (revision 6b7db209)
1 /* @(#)cpnull.c	4.1 82/03/05 */
2 
3 #include <stdio.h>
4 #include <signal.h>
5 #include <sys/types.h>
6 #include <stat.h>
7 #include <wellknown.h>
8 #include <sys/ioctl.h>
9 #include <net/in.h>
10 /*
11  * cpnull machine blocks
12  */
13 int	rem;
14 char	*index(), *rindex(), *malloc();
15 int	errs;
16 int	broken();
17 int	lostconn();
18 
19 int	errno;
20 char	sys_errlist[];
21 int	vflag;
22 
23 main(argc, argv)
24 	int argc;
25 	char **argv;
26 {
27 	char *host, *remotedir;
28 	int x, i, f;
29 	char buf[BUFSIZ];
30 	int blocks;
31 	time_t then, now;
32 
33 	argc--, argv++;
34 	if (argc > 0 && !strcmp(*argv, "-r"))
35 		remote();
36 	if (argc > 0 && !strcmp(*argv, "-v"))
37 		vflag++, argc--, argv++;
38 	if (argc < 2) {
39 		fprintf(stderr, "usage: cpnull machine blocks\n");
40 		exit(1);
41 	}
42 	signal(SIGPIPE, broken);
43 	host = *argv++; argc--;
44 	rem = rexec(&host, IPPORT_SHELLSERVER, "cpnull -r", 0, 0);
45 	if (rem < 0)
46 		exit(1);
47 	blocks = atoi(*argv);
48 	sprintf(buf, "C%d\n", blocks * BUFSIZ);
49 	write(rem, buf, strlen(buf));
50 	if (response() < 0)
51 		exit(1);
52 	printf("sending %d blocks\n", blocks);
53 	time(&then);
54 	for (i = 0; i < blocks; i++)  {
55 		if (vflag && (i % 100 == 0))
56 			printf("%d\n", i);
57 		write(rem, buf, BUFSIZ);
58 	}
59 	(void) response();
60 	time(&now);
61 	if (then == now)
62 		printf("< 1 second to transfer\n");
63 	else
64 		printf("%d bytes %d seconds %d baud\n",
65 		    blocks * BUFSIZ, now - then,
66 		    (blocks * BUFSIZ * 8) / (now - then));
67 	exit(errs);
68 }
69 
70 response()
71 {
72 	char resp, c, rbuf[BUFSIZ], *cp = rbuf;
73 
74 	if (read(rem, &resp, 1) != 1) {
75 		printf("Response read != 1\n");
76 		lostconn();
77 	}
78 	switch (resp) {
79 
80 	case 0:
81 		return (0);
82 
83 	default:
84 		*cp++ = resp;
85 		/* fall into... */
86 	case 1:
87 	case 2:
88 		do {
89 			if (read(rem, &c, 1) != 1) {
90 				printf("response loop != 1\n");
91 				write(2, rbuf, cp-rbuf);
92 				write(2, "\n", 1);
93 				lostconn();
94 			}
95 			*cp++ = c;
96 		} while (cp < &rbuf[BUFSIZ] && c != '\n');
97 		write(2, rbuf, cp - rbuf);
98 		if (resp == 1)
99 			return (-1);
100 		exit(1);
101 	}
102 }
103 
104 broken()
105 {
106 
107 	fprintf(stderr, "SIGPIPE.\n");
108 }
109 
110 lostconn()
111 {
112 
113 	fprintf(stderr, "Lost connection.\n");
114 	exit(1);
115 }
116 
117 remote()
118 {
119 	char namebuf[BUFSIZ], buf[BUFSIZ], *name, *cp, c;
120 	int i, size;
121 	char *whopp;
122 #define	SCREWUP(str)	{ whopp = str; goto screwup; }
123 
124 	cp = namebuf;
125 	if (read(0, cp, 1) <= 0)
126 		exit(0);
127 	if (*cp++ == '\n')
128 		SCREWUP("unexpected '\\n'");
129 	do
130 		if (read(0, cp, 1) != 1)
131 			exit(1);
132 	while (*cp++ != '\n');
133 	*--cp = 0;
134 	cp = namebuf;
135 	if (*cp++ != 'C')
136 		SCREWUP("expected control record");
137 	size = 0;
138 	while (*cp >= '0' && *cp <= '9')
139 		size = size * 10 + (*cp++ - '0');
140 	if (*cp++ != 0)
141 		SCREWUP("size not delimited");
142 	write(rem, "\0", 1);
143 	for (i = 0; i < size; i += BUFSIZ) {
144 		int amt = BUFSIZ;
145 		char *cp = buf;
146 
147 		if (i + amt > size)
148 			amt = size - i;
149 		do {
150 			int j = read(0, cp, amt);
151 
152 			if (j <= 0)
153 				exit(1);
154 			amt -= j;
155 			cp += j;
156 		} while (amt > 0);
157 		amt = BUFSIZ;
158 		if (i + amt > size)
159 			amt = size - i;
160 	}
161 	write(rem, "\0", 1);
162 	exit(0);
163 perr:
164 	sprintf(buf, "\01%s: %s\n", cp, sys_errlist[errno]);
165 	write(rem, buf, strlen(buf));
166 	exit(1);
167 screwup:
168 	sprintf(buf, "\02Procotol screwup: %s.\n", whopp);
169 	write(rem, buf, strlen(buf));
170 	exit(1);
171 }
172