net.c revision 14631
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1989, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * This code is derived from software contributed to Berkeley by 61590Srgrimes * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 1. Redistributions of source code must retain the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer. 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 3. All advertising materials mentioning features or use of this software 171590Srgrimes * must display the following acknowledgement: 181590Srgrimes * This product includes software developed by the University of 191590Srgrimes * California, Berkeley and its contributors. 201590Srgrimes * 4. Neither the name of the University nor the names of its contributors 211590Srgrimes * may be used to endorse or promote products derived from this software 221590Srgrimes * without specific prior written permission. 231590Srgrimes * 241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341590Srgrimes * SUCH DAMAGE. 351590Srgrimes */ 361590Srgrimes 371590Srgrimes#ifndef lint 381590Srgrimesstatic char sccsid[] = "@(#)net.c 8.3 (Berkeley) 1/2/94"; 391590Srgrimes#endif /* not lint */ 401590Srgrimes 411590Srgrimes#include <sys/types.h> 421590Srgrimes#include <sys/socket.h> 431590Srgrimes#include <netinet/in.h> 441590Srgrimes#include <arpa/inet.h> 451590Srgrimes#include <netdb.h> 461590Srgrimes#include <db.h> 471590Srgrimes#include <unistd.h> 481590Srgrimes#include <pwd.h> 491590Srgrimes#include <utmp.h> 501590Srgrimes#include <stdio.h> 511590Srgrimes#include <ctype.h> 521590Srgrimes#include <string.h> 5312909Swollman#include <sys/uio.h> 541590Srgrimes#include "finger.h" 551590Srgrimes 561590Srgrimesvoid 571590Srgrimesnetfinger(name) 581590Srgrimes char *name; 591590Srgrimes{ 601590Srgrimes extern int lflag; 6114631Solah extern int Tflag; 621590Srgrimes register FILE *fp; 631590Srgrimes register int c, lastc; 641590Srgrimes struct in_addr defaddr; 651590Srgrimes struct hostent *hp, def; 661590Srgrimes struct servent *sp; 671590Srgrimes struct sockaddr_in sin; 681590Srgrimes int s; 691590Srgrimes char *alist[1], *host; 7012909Swollman struct iovec iov[3]; 7112909Swollman struct msghdr msg; 721590Srgrimes 731590Srgrimes if (!(host = rindex(name, '@'))) 741590Srgrimes return; 751590Srgrimes *host++ = NULL; 761590Srgrimes if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != -1) { 771590Srgrimes def.h_name = host; 781590Srgrimes def.h_addr_list = alist; 791590Srgrimes def.h_addr = (char *)&defaddr; 801590Srgrimes def.h_length = sizeof(struct in_addr); 811590Srgrimes def.h_addrtype = AF_INET; 821590Srgrimes def.h_aliases = 0; 831590Srgrimes hp = &def; 841590Srgrimes } else if (!(hp = gethostbyname(host))) { 851590Srgrimes (void)fprintf(stderr, 861590Srgrimes "finger: unknown host: %s\n", host); 871590Srgrimes return; 881590Srgrimes } 891590Srgrimes if (!(sp = getservbyname("finger", "tcp"))) { 901590Srgrimes (void)fprintf(stderr, "finger: tcp/finger: unknown service\n"); 911590Srgrimes return; 921590Srgrimes } 931590Srgrimes sin.sin_family = hp->h_addrtype; 941590Srgrimes bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length); 951590Srgrimes sin.sin_port = sp->s_port; 961590Srgrimes if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { 971590Srgrimes perror("finger: socket"); 981590Srgrimes return; 991590Srgrimes } 1001590Srgrimes 1011590Srgrimes /* have network connection; identify the host connected with */ 1021590Srgrimes (void)printf("[%s]\n", hp->h_name); 1031590Srgrimes 10412909Swollman msg.msg_name = (void *)&sin; 10512909Swollman msg.msg_namelen = sizeof sin; 10612909Swollman msg.msg_iov = iov; 10712909Swollman msg.msg_iovlen = 0; 10812909Swollman msg.msg_control = 0; 10912909Swollman msg.msg_controllen = 0; 11012909Swollman msg.msg_flags = MSG_EOF; 11112909Swollman 1121590Srgrimes /* -l flag for remote fingerd */ 11312909Swollman if (lflag) { 11412909Swollman iov[msg.msg_iovlen].iov_base = "/W "; 11512909Swollman iov[msg.msg_iovlen++].iov_len = 3; 11612909Swollman } 1171590Srgrimes /* send the name followed by <CR><LF> */ 11812909Swollman iov[msg.msg_iovlen].iov_base = name; 11912909Swollman iov[msg.msg_iovlen++].iov_len = strlen(name); 12012909Swollman iov[msg.msg_iovlen].iov_base = "\r\n"; 12112909Swollman iov[msg.msg_iovlen++].iov_len = 2; 1221590Srgrimes 12314631Solah /* -T disables T/TCP: compatibility option to finger broken hosts */ 12414631Solah if (Tflag && connect(s, (struct sockaddr *)&sin, sizeof (sin))) { 12514631Solah perror("finger: connect"); 12614631Solah return; 12714631Solah } 12814631Solah 12912909Swollman if (sendmsg(s, &msg, MSG_EOF) < 0) { 13012909Swollman perror("finger: sendmsg"); 13112909Swollman close(s); 13212909Swollman return; 13312909Swollman } 13412909Swollman 1351590Srgrimes /* 1361590Srgrimes * Read from the remote system; once we're connected, we assume some 1371590Srgrimes * data. If none arrives, we hang until the user interrupts. 1381590Srgrimes * 1391590Srgrimes * If we see a <CR> or a <CR> with the high bit set, treat it as 1401590Srgrimes * a newline; if followed by a newline character, only output one 1411590Srgrimes * newline. 1421590Srgrimes * 1431590Srgrimes * Otherwise, all high bits are stripped; if it isn't printable and 1441590Srgrimes * it isn't a space, we can simply set the 7th bit. Every ASCII 1451590Srgrimes * character with bit 7 set is printable. 1468874Srgrimes */ 14712909Swollman if (fp = fdopen(s, "r")) { 14812909Swollman int lastc = '\n'; 14912909Swollman 1501590Srgrimes while ((c = getc(fp)) != EOF) { 1511590Srgrimes if (c == 0x0d) { 1521590Srgrimes if (lastc == '\r') /* ^M^M - skip dupes */ 1531590Srgrimes continue; 1541590Srgrimes c = '\n'; 1551590Srgrimes lastc = '\r'; 1561590Srgrimes } else { 15714472Sache if (!isprint(c) && !isspace(c)) { 15814472Sache c &= 0x7f; 1591590Srgrimes c |= 0x40; 16014472Sache } 1611590Srgrimes if (lastc != '\r' || c != '\n') 1621590Srgrimes lastc = c; 1631590Srgrimes else { 1641590Srgrimes lastc = '\n'; 1651590Srgrimes continue; 1661590Srgrimes } 1671590Srgrimes } 1681590Srgrimes putchar(c); 1691590Srgrimes } 17012909Swollman if (lastc != '\n') 17112909Swollman putchar('\n'); 17212909Swollman 17312909Swollman if (ferror(fp)) { 17412909Swollman /* 17512909Swollman * Assume that whatever it was set errno... 17612909Swollman */ 17712909Swollman perror("finger: read"); 17812909Swollman } 17912909Swollman (void)fclose(fp); 18012909Swollman } 1811590Srgrimes} 182