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