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