xref: /openbsd-src/regress/usr.bin/nc/util.c (revision 5a9255e7fde1eff660134511e5a28e2366fbe25a)
1*5a9255e7Sbluhm /*	$OpenBSD: util.c,v 1.3 2021/07/06 11:50:34 bluhm Exp $	*/
2d80889b6Sbluhm 
3d80889b6Sbluhm /*
4d80889b6Sbluhm  * Copyright (c) 2020 Alexander Bluhm <bluhm@openbsd.org>
5d80889b6Sbluhm  *
6d80889b6Sbluhm  * Permission to use, copy, modify, and distribute this software for any
7d80889b6Sbluhm  * purpose with or without fee is hereby granted, provided that the above
8d80889b6Sbluhm  * copyright notice and this permission notice appear in all copies.
9d80889b6Sbluhm  *
10d80889b6Sbluhm  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11d80889b6Sbluhm  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12d80889b6Sbluhm  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13d80889b6Sbluhm  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14d80889b6Sbluhm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15d80889b6Sbluhm  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16d80889b6Sbluhm  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17d80889b6Sbluhm  */
18d80889b6Sbluhm 
19d80889b6Sbluhm #include <sys/types.h>
20d80889b6Sbluhm #include <sys/socket.h>
21d80889b6Sbluhm 
22d80889b6Sbluhm #include <err.h>
23d80889b6Sbluhm #include <errno.h>
24d80889b6Sbluhm #include <netdb.h>
25d80889b6Sbluhm #include <stdio.h>
26d80889b6Sbluhm #include <stdlib.h>
27d80889b6Sbluhm #include <string.h>
28d80889b6Sbluhm #include <unistd.h>
29d80889b6Sbluhm 
30d80889b6Sbluhm #include "util.h"
31d80889b6Sbluhm 
32d80889b6Sbluhm void
task_enqueue(struct task * todo,int ch,const char * msg)33f214d6d2Sbluhm task_enqueue(struct task *todo, int ch, const char *msg)
34f214d6d2Sbluhm {
35f214d6d2Sbluhm 	switch (ch) {
36f214d6d2Sbluhm 	case 'E':
37f214d6d2Sbluhm 		todo->t_type = TEOF;
38f214d6d2Sbluhm 		todo->t_msg = NULL;
39f214d6d2Sbluhm 		break;
40f214d6d2Sbluhm 	case 'N':
41f214d6d2Sbluhm 		todo->t_type = TDWN;
42f214d6d2Sbluhm 		todo->t_msg = NULL;
43f214d6d2Sbluhm 		break;
44f214d6d2Sbluhm 	case 'r':
45f214d6d2Sbluhm 		todo->t_type = TRCV;
46f214d6d2Sbluhm 		todo->t_msg = msg;
47f214d6d2Sbluhm 		break;
48f214d6d2Sbluhm 	case 's':
49f214d6d2Sbluhm 		todo->t_type = TSND;
50f214d6d2Sbluhm 		todo->t_msg = msg;
51f214d6d2Sbluhm 		break;
52f214d6d2Sbluhm 	}
53f214d6d2Sbluhm }
54f214d6d2Sbluhm 
55f214d6d2Sbluhm void
task_run(int s,struct task * todolist,size_t tlen)56f214d6d2Sbluhm task_run(int s, struct task *todolist, size_t tlen)
57f214d6d2Sbluhm {
58f214d6d2Sbluhm 	size_t t;
59f214d6d2Sbluhm 
60f214d6d2Sbluhm 	for (t = 0; t < tlen; t++) {
61f214d6d2Sbluhm 		switch(todolist[t].t_type) {
62f214d6d2Sbluhm 		case TEOF:
63f214d6d2Sbluhm 			receive_eof(s);
64f214d6d2Sbluhm 			break;
65f214d6d2Sbluhm 		case TDWN:
66f214d6d2Sbluhm 			send_shutdown(s);
67f214d6d2Sbluhm 			break;
68f214d6d2Sbluhm 		case TRCV:
69f214d6d2Sbluhm 			receive_line(s, todolist[t].t_msg);
70f214d6d2Sbluhm 			break;
71f214d6d2Sbluhm 		case TSND:
72f214d6d2Sbluhm 			send_line(s, todolist[t].t_msg);
73f214d6d2Sbluhm 			break;
74f214d6d2Sbluhm 		}
75f214d6d2Sbluhm 	}
76f214d6d2Sbluhm }
77f214d6d2Sbluhm 
78f214d6d2Sbluhm void
print_sockname(int s)79d80889b6Sbluhm print_sockname(int s)
80d80889b6Sbluhm {
81d80889b6Sbluhm 	struct sockaddr_storage ss;
82d80889b6Sbluhm 	socklen_t slen;
83d80889b6Sbluhm 	char host[NI_MAXHOST], port[NI_MAXSERV];
84d80889b6Sbluhm 
85d80889b6Sbluhm 	slen = sizeof(ss);
86d80889b6Sbluhm 	if (getsockname(s, (struct sockaddr *)&ss, &slen) == -1)
87d80889b6Sbluhm 		err(1, "getsockname");
88d80889b6Sbluhm 	if (getnameinfo((struct sockaddr *)&ss, ss.ss_len, host, sizeof(host),
89d80889b6Sbluhm 	    port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV))
90d80889b6Sbluhm 		errx(1, "getnameinfo");
91d80889b6Sbluhm 	printf("%s\n", port);
92d80889b6Sbluhm 	if (fflush(stdout) != 0)
93d80889b6Sbluhm 		err(1, "fflush stdout");
94d80889b6Sbluhm 	fprintf(stderr, "sock: %s %s\n", host, port);
95d80889b6Sbluhm }
96d80889b6Sbluhm 
97d80889b6Sbluhm void
print_peername(int s)98d80889b6Sbluhm print_peername(int s)
99d80889b6Sbluhm {
100d80889b6Sbluhm 	struct sockaddr_storage ss;
101d80889b6Sbluhm 	socklen_t slen;
102d80889b6Sbluhm 	char host[NI_MAXHOST], port[NI_MAXSERV];
103d80889b6Sbluhm 
104d80889b6Sbluhm 	slen = sizeof(ss);
105d80889b6Sbluhm 	if (getpeername(s, (struct sockaddr *)&ss, &slen) == -1)
106d80889b6Sbluhm 		err(1, "getpeername");
107d80889b6Sbluhm 	if (getnameinfo((struct sockaddr *)&ss, ss.ss_len, host, sizeof(host),
108d80889b6Sbluhm 	    port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV))
109d80889b6Sbluhm 		errx(1, "getnameinfo");
110d80889b6Sbluhm 	fprintf(stderr, "peer: %s %s\n", host, port);
111d80889b6Sbluhm }
112d80889b6Sbluhm 
113d80889b6Sbluhm void
receive_eof(int s)114f214d6d2Sbluhm receive_eof(int s)
115f214d6d2Sbluhm {
116f214d6d2Sbluhm 	char buf[100];
117f214d6d2Sbluhm 	size_t len;
118f214d6d2Sbluhm 	ssize_t n;
119f214d6d2Sbluhm 
120f214d6d2Sbluhm 	n = recv(s, buf, sizeof(buf) - 1, 0);
121f214d6d2Sbluhm 	if (n == -1)
122f214d6d2Sbluhm 		err(1, "recv");
123f214d6d2Sbluhm 	if (n == 0) {
124f214d6d2Sbluhm 		fprintf(stderr, "<<< EOF\n");
125f214d6d2Sbluhm 		return;
126f214d6d2Sbluhm 	}
127f214d6d2Sbluhm 	len = n;
128f214d6d2Sbluhm 	buf[len] = '\0';
129f214d6d2Sbluhm 	if (buf[len - 1] == '\n')
130f214d6d2Sbluhm 		buf[--len] = '\0';
131f214d6d2Sbluhm 	fprintf(stderr, "<<< %s\n", buf);
132f214d6d2Sbluhm 	errx(1, "expected receive EOF, got '%s'", buf);
133f214d6d2Sbluhm }
134f214d6d2Sbluhm 
135f214d6d2Sbluhm void
send_shutdown(int s)136f214d6d2Sbluhm send_shutdown(int s)
137f214d6d2Sbluhm {
138f214d6d2Sbluhm 	if (shutdown(s, SHUT_WR) == -1)
139f214d6d2Sbluhm 		err(1, "shutdown");
140f214d6d2Sbluhm }
141f214d6d2Sbluhm 
142f214d6d2Sbluhm void
receive_line(int s,const char * msg)143d80889b6Sbluhm receive_line(int s, const char *msg)
144d80889b6Sbluhm {
145d80889b6Sbluhm 	char buf[100];
146d80889b6Sbluhm 	size_t off, len;
147d80889b6Sbluhm 	ssize_t n;
148d80889b6Sbluhm 
149d80889b6Sbluhm 	len = 0;
150f214d6d2Sbluhm 	while (len < sizeof(buf) - 1) {
151d80889b6Sbluhm 		off = len;
152f214d6d2Sbluhm 		n = recv(s, buf + off, sizeof(buf) - 1 - off, 0);
153d80889b6Sbluhm 		if (n == -1)
154d80889b6Sbluhm 			err(1, "recv");
155d80889b6Sbluhm 		if (n == 0) {
156d80889b6Sbluhm 			fprintf(stderr, "<<< EOF\n");
157d80889b6Sbluhm 			break;
158d80889b6Sbluhm 		}
159d80889b6Sbluhm 		len += n;
160d80889b6Sbluhm 		buf[len] = '\0';
161d80889b6Sbluhm 		if (buf[len - 1] == '\n')
162d80889b6Sbluhm 			fprintf(stderr, "<<< %s", buf + off);
163d80889b6Sbluhm 		else
164d80889b6Sbluhm 			fprintf(stderr, "<<< %s\n", buf + off);
165d80889b6Sbluhm 		if (strchr(buf + off, '\n') != NULL)
166d80889b6Sbluhm 			break;
167d80889b6Sbluhm 	}
168d80889b6Sbluhm 	if (len == 0)
169d80889b6Sbluhm 		errx(1, "empty receive buffer");
170d80889b6Sbluhm 	if (buf[len - 1] != '\n')
171d80889b6Sbluhm 		errx(1, "new line missing in receive buffer");
172d80889b6Sbluhm 	buf[--len] = '\0';
173d80889b6Sbluhm 	if (strcmp(msg, buf) != 0)
174d80889b6Sbluhm 		errx(1, "expected receive '%s', got '%s'", msg, buf);
175d80889b6Sbluhm }
176d80889b6Sbluhm 
177d80889b6Sbluhm void
send_line(int s,const char * msg)178d80889b6Sbluhm send_line(int s, const char *msg)
179d80889b6Sbluhm {
180d80889b6Sbluhm 	char buf[100];
181d80889b6Sbluhm 	size_t off, len;
182d80889b6Sbluhm 	ssize_t n;
183d80889b6Sbluhm 
184d80889b6Sbluhm 	len = strlcpy(buf, msg, sizeof(buf));
185d80889b6Sbluhm 	if (len >= sizeof(buf))
186d80889b6Sbluhm 		errx(1, "message too long for send buffer");
187d80889b6Sbluhm 	if (buf[len] != '\n') {
188d80889b6Sbluhm 		buf[len++] = '\n';
189d80889b6Sbluhm 		if (len >= sizeof(buf))
190d80889b6Sbluhm 			errx(1, "new line too long for send buffer");
191d80889b6Sbluhm 		buf[len] = 0;
192d80889b6Sbluhm 	}
193d80889b6Sbluhm 
194d80889b6Sbluhm 	off = 0;
195d80889b6Sbluhm 	while (off < len) {
196d80889b6Sbluhm 		fprintf(stderr, ">>> %s", buf + off);
197d80889b6Sbluhm 		n = send(s, buf + off, len - off, 0);
198d80889b6Sbluhm 		if (n == -1)
199d80889b6Sbluhm 			err(1, "send");
200d80889b6Sbluhm 		off += n;
201d80889b6Sbluhm 	}
202d80889b6Sbluhm }
203