sl@0: /* FINGER.C sl@0: * sl@0: * Portions Copyright (c) 1993-2004 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: */ sl@0: sl@0: /* sl@0: * Copyright (c) 1989, 1993 sl@0: * The Regents of the University of California. All rights reserved. sl@0: * sl@0: * This code is derived from software contributed to Berkeley by sl@0: * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the above copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * 3. All advertising materials mentioning features or use of this software sl@0: * must display the following acknowledgement: sl@0: * This product includes software developed by the University of sl@0: * California, Berkeley and its contributors. sl@0: * 4. Neither the name of the University nor the names of its contributors sl@0: * may be used to endorse or promote products derived from this software sl@0: * without specific prior written permission. sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND sl@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE sl@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE sl@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL sl@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS sl@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT sl@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY sl@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF sl@0: * SUCH DAMAGE. sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: int main (int argc, char* argv[]) sl@0: { sl@0: int c, lastc; sl@0: struct in_addr defaddr; sl@0: struct hostent *hp, def; sl@0: struct sockaddr_in sin; sl@0: int s, i; sl@0: char *alist[1], *host; sl@0: char request[100]; sl@0: char input[80]; sl@0: char* name; sl@0: sl@0: if (argc >= 2) sl@0: { sl@0: name = argv[1]; sl@0: } sl@0: else sl@0: { sl@0: printf("user@hostname? "); sl@0: fflush(stdout); sl@0: name = input; sl@0: do sl@0: { sl@0: c = getchar(); sl@0: if (c=='\b') /* DIY backspace processing */ sl@0: { sl@0: if (name > input) sl@0: name--; sl@0: continue; sl@0: } sl@0: if (c=='\n' || c=='\r') sl@0: break; sl@0: *name++ = c; sl@0: } sl@0: while (name < input+78); sl@0: *name++ = '\0'; sl@0: name = input; sl@0: } sl@0: host = strrchr(name, '@'); sl@0: if (host==0) sl@0: { sl@0: printf("Usage: finger user@hostname\n"); sl@0: exit(-2); sl@0: } sl@0: *host++ = NULL; sl@0: sl@0: /* Step 1 - resolve the IP address */ sl@0: sl@0: printf("\nLooking up IP address of %s...\n", host); sl@0: sl@0: if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != INADDR_ANY) sl@0: { sl@0: def.h_name = host; sl@0: def.h_addr_list = alist; sl@0: def.h_addr = (char *)&defaddr; sl@0: def.h_length = sizeof(struct in_addr); sl@0: def.h_addrtype = AF_INET; sl@0: def.h_aliases = 0; sl@0: hp = &def; sl@0: } sl@0: else sl@0: { sl@0: hp = gethostbyname(host); sl@0: if(!hp) sl@0: { sl@0: (void)fprintf(stderr, "finger: unknown host: %s\n", host); sl@0: exit(-3); sl@0: } sl@0: } sl@0: sin.sin_family = hp->h_addrtype; sl@0: memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length); sl@0: if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { sl@0: perror("finger: socket"); sl@0: exit(-4); sl@0: } sl@0: sl@0: (void)printf("\n %s => %s\n", hp->h_name, inet_ntoa(sin.sin_addr)); sl@0: sl@0: /* Step 2 - Connect to the finger port on the target host */ sl@0: sl@0: printf("\nConnecting to %s...", host); sl@0: fflush(stdout); sl@0: sl@0: sin.sin_port = htons(IPPORT_FINGER); sl@0: if (connect(s, (struct sockaddr *)&sin, sizeof (sin))) { sl@0: perror("finger: connect"); sl@0: exit(-5); sl@0: } sl@0: sl@0: printf("OK\n"); sl@0: sl@0: /* Step 3 - Finger the user and read the result... */ sl@0: sl@0: printf("\nFinger %s@%s\n", name, host); sl@0: sl@0: /* send the name followed by */ sl@0: sprintf(request, "%s\r\n", name); sl@0: if (write(s, request, strlen(request)) < 0) { sl@0: perror("finger: write"); sl@0: close(s); sl@0: exit(-6); sl@0: } sl@0: sl@0: /* Read from the remote system; once we're connected, we assume some sl@0: * data. If none arrives, we hang until the user interrupts. sl@0: * sl@0: * If we see a or a with the high bit set, treat it as sl@0: * a newline; if followed by a newline character, only output one sl@0: * newline. sl@0: * sl@0: * Otherwise, all high bits are stripped; if it isn't printable and sl@0: * it isn't a space, we can simply set the 7th bit. Every ASCII sl@0: * character with bit 7 set is printable. sl@0: */ sl@0: lastc = '\n'; sl@0: sl@0: while (recv(s, &request[0], 1, 0) > 0) { sl@0: c = request[0]; sl@0: if (c == 0x0d) { sl@0: if (lastc == '\r') /* ^M^M - skip dupes */ sl@0: continue; sl@0: c = '\n'; sl@0: lastc = '\r'; sl@0: } else { sl@0: if (!isprint(c) && !isspace(c)) { sl@0: c &= 0x7f; sl@0: c |= 0x40; sl@0: } sl@0: if (lastc != '\r' || c != '\n') sl@0: lastc = c; sl@0: else { sl@0: lastc = '\n'; sl@0: continue; sl@0: } sl@0: } sl@0: putchar(c); sl@0: } sl@0: if (lastc != '\n') sl@0: putchar('\n'); sl@0: close(s); sl@0: sl@0: /* Step 4 - Check the time on the remote machine as well */ sl@0: sl@0: if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { sl@0: perror("finger: socket"); sl@0: exit(-7); sl@0: } sl@0: sl@0: sin.sin_port = htons(IPPORT_DAYTIME); sl@0: if (connect(s, (struct sockaddr *)&sin, sizeof (sin))) { sl@0: perror("finger: connect"); sl@0: exit(-8); sl@0: } sl@0: sl@0: i = recv(s, request, sizeof(request)-1, 0); sl@0: if (i<0) sl@0: { sl@0: perror("finger: recv"); sl@0: exit(-9); sl@0: } sl@0: request[i] = '\0'; sl@0: sl@0: printf("\nThe time on %s is %s\n", host, request); sl@0: close(s); sl@0: sl@0: return 0; sl@0: }