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