1*37660Sbostic /* 2*37660Sbostic * Copyright (c) 1989 The Regents of the University of California. 3*37660Sbostic * All rights reserved. 4*37660Sbostic * 5*37660Sbostic * This code is derived from software contributed to Berkeley by 6*37660Sbostic * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. 7*37660Sbostic * 8*37660Sbostic * Redistribution and use in source and binary forms are permitted 9*37660Sbostic * provided that the above copyright notice and this paragraph are 10*37660Sbostic * duplicated in all such forms and that any documentation, 11*37660Sbostic * advertising materials, and other materials related to such 12*37660Sbostic * distribution and use acknowledge that the software was developed 13*37660Sbostic * by the University of California, Berkeley. The name of the 14*37660Sbostic * University may not be used to endorse or promote products derived 15*37660Sbostic * from this software without specific prior written permission. 16*37660Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*37660Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*37660Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*37660Sbostic */ 20*37660Sbostic 21*37660Sbostic #ifndef lint 22*37660Sbostic static char sccsid[] = "@(#)net.c 5.1 (Berkeley) 05/06/89"; 23*37660Sbostic #endif /* not lint */ 24*37660Sbostic 25*37660Sbostic #include <sys/types.h> 26*37660Sbostic #include <sys/socket.h> 27*37660Sbostic #include <netinet/in.h> 28*37660Sbostic #include <netdb.h> 29*37660Sbostic #include <stdio.h> 30*37660Sbostic #include <ctype.h> 31*37660Sbostic 32*37660Sbostic netfinger(name) 33*37660Sbostic char *name; 34*37660Sbostic { 35*37660Sbostic extern int lflag; 36*37660Sbostic register FILE *fp; 37*37660Sbostic register int c, lastc; 38*37660Sbostic struct in_addr defaddr; 39*37660Sbostic struct hostent *hp, def; 40*37660Sbostic struct servent *sp; 41*37660Sbostic struct sockaddr_in sin; 42*37660Sbostic int s; 43*37660Sbostic char *alist[1], *host, *rindex(); 44*37660Sbostic u_long inet_addr(); 45*37660Sbostic 46*37660Sbostic if (!(host = rindex(name, '@'))) 47*37660Sbostic return; 48*37660Sbostic *host++ = NULL; 49*37660Sbostic if (!(hp = gethostbyname(host))) { 50*37660Sbostic defaddr.s_addr = inet_addr(host); 51*37660Sbostic if (defaddr.s_addr == -1) { 52*37660Sbostic (void)fprintf(stderr, 53*37660Sbostic "finger: unknown host: %s\n", host); 54*37660Sbostic return; 55*37660Sbostic } 56*37660Sbostic def.h_name = host; 57*37660Sbostic def.h_addr_list = alist; 58*37660Sbostic def.h_addr = (char *)&defaddr; 59*37660Sbostic def.h_length = sizeof(struct in_addr); 60*37660Sbostic def.h_addrtype = AF_INET; 61*37660Sbostic def.h_aliases = 0; 62*37660Sbostic hp = &def; 63*37660Sbostic } 64*37660Sbostic if (!(sp = getservbyname("finger", "tcp"))) { 65*37660Sbostic (void)fprintf(stderr, "finger: tcp/finger: unknown service\n"); 66*37660Sbostic return; 67*37660Sbostic } 68*37660Sbostic sin.sin_family = hp->h_addrtype; 69*37660Sbostic bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length); 70*37660Sbostic sin.sin_port = sp->s_port; 71*37660Sbostic if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { 72*37660Sbostic perror("finger: socket"); 73*37660Sbostic return; 74*37660Sbostic } 75*37660Sbostic 76*37660Sbostic /* have network connection; identify the host connected with */ 77*37660Sbostic (void)printf("[%s]\n", hp->h_name); 78*37660Sbostic if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 79*37660Sbostic perror("finger: connect"); 80*37660Sbostic (void)close(s); 81*37660Sbostic return; 82*37660Sbostic } 83*37660Sbostic 84*37660Sbostic /* -l flag for remote fingerd */ 85*37660Sbostic if (lflag) 86*37660Sbostic write(s, "/W ", 3); 87*37660Sbostic /* send the name followed by <CR><LF> */ 88*37660Sbostic (void)write(s, name, strlen(name)); 89*37660Sbostic (void)write(s, "\r\n", 2); 90*37660Sbostic 91*37660Sbostic /* 92*37660Sbostic * read back what we get from the remote system. 93*37660Sbostic * 94*37660Sbostic * Note: once we connected to the remote site, we assume some data. 95*37660Sbostic * If it can't/won't send any data, we hang here until Mr. User 96*37660Sbostic * gets sufficiently bored to hit ^C. 97*37660Sbostic * 98*37660Sbostic * Some systems use the return key as a line terminator. These 99*37660Sbostic * systems tend to also set the parity bit on every byte. If we 100*37660Sbostic * see a <CR> with the 8th bit set, treat it as a newline character. 101*37660Sbostic * 0x8d == <CR> with high bit set. 102*37660Sbostic * 103*37660Sbostic * Otherwise, all high bits are stripped; if it isn't printable and 104*37660Sbostic * it isn't a space, we can simply set the 7th bit. Every ASCII 105*37660Sbostic * character with bit 7 set is printable. 106*37660Sbostic */ 107*37660Sbostic if (fp = fdopen(s, "r")) 108*37660Sbostic while ((c = getc(fp)) != EOF) { 109*37660Sbostic if (c == 0x8d) 110*37660Sbostic c = '\n'; 111*37660Sbostic c &= 0x7f; 112*37660Sbostic if (!isprint(c) && !isspace(c)) 113*37660Sbostic c |= 0x40; 114*37660Sbostic lastc = c; 115*37660Sbostic putchar(c); 116*37660Sbostic } 117*37660Sbostic if (lastc != '\n') 118*37660Sbostic putchar('\n'); 119*37660Sbostic (void)fclose(fp); 120*37660Sbostic } 121