Annotation of src/usr.bin/finger/net.c, Revision 1.14
1.14 ! deraadt 1: /* $OpenBSD: net.c,v 1.13 2015/01/16 06:40:07 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.1 deraadt 48: netfinger(name)
49: char *name;
50: {
1.5 kstailey 51: FILE *fp;
52: int c, lastc;
1.1 deraadt 53: int s;
1.5 kstailey 54: char *host;
1.7 itojun 55: struct addrinfo hints, *res0, *res;
56: int error;
57: char hbuf[NI_MAXHOST];
1.1 deraadt 58:
1.5 kstailey 59: lastc = 0;
1.3 millert 60: if (!(host = strrchr(name, '@')))
1.1 deraadt 61: return;
1.5 kstailey 62: *host++ = '\0';
1.7 itojun 63: memset(&hints, 0, sizeof(hints));
64: hints.ai_family = PF_UNSPEC;
65: hints.ai_socktype = SOCK_STREAM;
66: error = getaddrinfo(host, "finger", &hints, &res0);
67: if (error) {
68: warnx("%s", gai_strerror(error));
69: return;
70: }
71:
72: s = -1;
73: for (res = res0; res; res = res->ai_next) {
74: if ((s = socket(res->ai_family, res->ai_socktype,
1.14 ! deraadt 75: res->ai_protocol)) == -1) {
1.7 itojun 76: continue;
1.1 deraadt 77: }
1.14 ! deraadt 78: if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
1.7 itojun 79: (void)close(s);
80: s = -1;
81: continue;
82: }
83:
84: break;
1.1 deraadt 85: }
1.7 itojun 86:
1.14 ! deraadt 87: if (s == -1) {
1.7 itojun 88: perror("finger");
89: freeaddrinfo(res0);
1.1 deraadt 90: return;
91: }
92:
93: /* have network connection; identify the host connected with */
1.7 itojun 94: if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1.8 deraadt 95: NULL, 0, NI_NUMERICHOST) != 0) {
96: strlcpy(hbuf, "(invalid)", sizeof hbuf);
1.1 deraadt 97: }
1.7 itojun 98: (void)printf("[%s/%s]\n", host, hbuf);
99:
100: freeaddrinfo(res0);
1.1 deraadt 101:
102: /* -l flag for remote fingerd */
103: if (lflag)
104: write(s, "/W ", 3);
105: /* send the name followed by <CR><LF> */
106: (void)write(s, name, strlen(name));
107: (void)write(s, "\r\n", 2);
108:
109: /*
110: * Read from the remote system; once we're connected, we assume some
111: * data. If none arrives, we hang until the user interrupts.
112: *
113: * If we see a <CR> or a <CR> with the high bit set, treat it as
114: * a newline; if followed by a newline character, only output one
115: * newline.
116: *
117: * Otherwise, all high bits are stripped; if it isn't printable and
118: * it isn't a space, we can simply set the 7th bit. Every ASCII
119: * character with bit 7 set is printable.
1.5 kstailey 120: */
121: if ((fp = fdopen(s, "r")) != NULL)
1.1 deraadt 122: while ((c = getc(fp)) != EOF) {
123: c &= 0x7f;
124: if (c == '\r') {
125: if (lastc == '\r')
126: continue;
127: c = '\n';
128: lastc = '\r';
129: } else {
130: if (!isprint(c) && !isspace(c))
131: c |= 0x40;
132: if (lastc != '\r' || c != '\n')
133: lastc = c;
134: else {
135: lastc = '\n';
136: continue;
137: }
138: }
139: putchar(c);
140: }
141: if (lastc != '\n')
142: putchar('\n');
143: (void)fclose(fp);
144: }