Annotation of src/usr.bin/finger/net.c, Revision 1.15
1.15 ! tb 1: /* $OpenBSD: net.c,v 1.14 2019/06/28 13:35:01 deraadt Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /*
4: * Copyright (c) 1989 The Regents of the University of California.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
1.9 millert 18: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: #include <sys/socket.h>
36: #include <netinet/in.h>
37: #include <arpa/inet.h>
38: #include <netdb.h>
39: #include <stdio.h>
40: #include <string.h>
41: #include <ctype.h>
1.5 kstailey 42: #include <unistd.h>
1.6 mickey 43: #include <err.h>
1.5 kstailey 44: #include "finger.h"
45: #include "extern.h"
1.1 deraadt 46:
1.5 kstailey 47: void
1.15 ! tb 48: netfinger(char *name)
1.1 deraadt 49: {
1.5 kstailey 50: FILE *fp;
51: int c, lastc;
1.1 deraadt 52: int s;
1.5 kstailey 53: char *host;
1.7 itojun 54: struct addrinfo hints, *res0, *res;
55: int error;
56: char hbuf[NI_MAXHOST];
1.1 deraadt 57:
1.5 kstailey 58: lastc = 0;
1.3 millert 59: if (!(host = strrchr(name, '@')))
1.1 deraadt 60: return;
1.5 kstailey 61: *host++ = '\0';
1.7 itojun 62: memset(&hints, 0, sizeof(hints));
63: hints.ai_family = PF_UNSPEC;
64: hints.ai_socktype = SOCK_STREAM;
65: error = getaddrinfo(host, "finger", &hints, &res0);
66: if (error) {
67: warnx("%s", gai_strerror(error));
68: return;
69: }
70:
71: s = -1;
72: for (res = res0; res; res = res->ai_next) {
73: if ((s = socket(res->ai_family, res->ai_socktype,
1.14 deraadt 74: res->ai_protocol)) == -1) {
1.7 itojun 75: continue;
1.1 deraadt 76: }
1.14 deraadt 77: if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
1.7 itojun 78: (void)close(s);
79: s = -1;
80: continue;
81: }
82:
83: break;
1.1 deraadt 84: }
1.7 itojun 85:
1.14 deraadt 86: if (s == -1) {
1.7 itojun 87: perror("finger");
88: freeaddrinfo(res0);
1.1 deraadt 89: return;
90: }
91:
92: /* have network connection; identify the host connected with */
1.7 itojun 93: if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1.8 deraadt 94: NULL, 0, NI_NUMERICHOST) != 0) {
95: strlcpy(hbuf, "(invalid)", sizeof hbuf);
1.1 deraadt 96: }
1.7 itojun 97: (void)printf("[%s/%s]\n", host, hbuf);
98:
99: freeaddrinfo(res0);
1.1 deraadt 100:
101: /* -l flag for remote fingerd */
102: if (lflag)
103: write(s, "/W ", 3);
104: /* send the name followed by <CR><LF> */
105: (void)write(s, name, strlen(name));
106: (void)write(s, "\r\n", 2);
107:
108: /*
109: * Read from the remote system; once we're connected, we assume some
110: * data. If none arrives, we hang until the user interrupts.
111: *
112: * If we see a <CR> or a <CR> with the high bit set, treat it as
113: * a newline; if followed by a newline character, only output one
114: * newline.
115: *
116: * Otherwise, all high bits are stripped; if it isn't printable and
117: * it isn't a space, we can simply set the 7th bit. Every ASCII
118: * character with bit 7 set is printable.
1.5 kstailey 119: */
120: if ((fp = fdopen(s, "r")) != NULL)
1.1 deraadt 121: while ((c = getc(fp)) != EOF) {
122: c &= 0x7f;
123: if (c == '\r') {
124: if (lastc == '\r')
125: continue;
126: c = '\n';
127: lastc = '\r';
128: } else {
129: if (!isprint(c) && !isspace(c))
130: c |= 0x40;
131: if (lastc != '\r' || c != '\n')
132: lastc = c;
133: else {
134: lastc = '\n';
135: continue;
136: }
137: }
138: putchar(c);
139: }
140: if (lastc != '\n')
141: putchar('\n');
142: (void)fclose(fp);
143: }