os/ossrv/genericopenlibs/cstdlib/TSTLIB/FINGER.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* FINGER.C
     2  * 
     3  * Portions Copyright (c) 1993-2004 Nokia Corporation and/or its subsidiary(-ies).
     4  * All rights reserved.
     5  */
     6 
     7 /*
     8  * Copyright (c) 1989, 1993
     9  *	The Regents of the University of California.  All rights reserved.
    10  *
    11  * This code is derived from software contributed to Berkeley by
    12  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
    13  *
    14  * Redistribution and use in source and binary forms, with or without
    15  * modification, are permitted provided that the following conditions
    16  * are met:
    17  * 1. Redistributions of source code must retain the above copyright
    18  *    notice, this list of conditions and the following disclaimer.
    19  * 2. Redistributions in binary form must reproduce the above copyright
    20  *    notice, this list of conditions and the following disclaimer in the
    21  *    documentation and/or other materials provided with the distribution.
    22  * 3. All advertising materials mentioning features or use of this software
    23  *    must display the following acknowledgement:
    24  *	This product includes software developed by the University of
    25  *	California, Berkeley and its contributors.
    26  * 4. Neither the name of the University nor the names of its contributors
    27  *    may be used to endorse or promote products derived from this software
    28  *    without specific prior written permission.
    29  *
    30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    40  * SUCH DAMAGE.
    41  */
    42 
    43 #include <sys/types.h>
    44 #include <sys/socket.h>
    45 #include <libc/netinet/in.h>
    46 #include <libc/arpa/inet.h>
    47 #include <netdb.h>
    48 #include <unistd.h>
    49 #include <stdio.h>
    50 #include <ctype.h>
    51 #include <string.h>
    52 #include <stdlib.h>
    53 
    54 int main (int argc, char* argv[])
    55 {
    56 	int c, lastc;
    57 	struct in_addr defaddr;
    58 	struct hostent *hp, def;
    59 	struct sockaddr_in sin;
    60 	int s, i;
    61 	char *alist[1], *host;
    62 	char request[100];
    63 	char input[80];
    64 	char* name;
    65 
    66 	if (argc >= 2)
    67 		{
    68 		name = argv[1];
    69 		}
    70 	else
    71 		{
    72 		printf("user@hostname? ");
    73 		fflush(stdout);
    74 		name = input;
    75 		do 
    76 			{
    77 			c = getchar();
    78 			if (c=='\b')		/* DIY backspace processing */
    79 				{
    80 				if (name > input)
    81 					name--;
    82 				continue;
    83 				}
    84 			if (c=='\n' || c=='\r')
    85 				break;
    86 			*name++ = c;
    87 			}
    88 		while (name < input+78);
    89 		*name++ = '\0';
    90 		name = input;
    91 		}
    92 	host = strrchr(name, '@');
    93 	if (host==0)
    94 		{
    95 		printf("Usage: finger user@hostname\n");
    96 		exit(-2);
    97 		}
    98 	*host++ = NULL;
    99 
   100 	/* Step 1 - resolve the IP address */
   101 
   102 	printf("\nLooking up IP address of %s...\n", host);
   103 
   104 	if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != INADDR_ANY) 
   105 		{
   106 		def.h_name = host;
   107 		def.h_addr_list = alist;
   108 		def.h_addr = (char *)&defaddr;
   109 		def.h_length = sizeof(struct in_addr);
   110 		def.h_addrtype = AF_INET;
   111 		def.h_aliases = 0;
   112 		hp = &def;
   113 		} 
   114 	else
   115 		{
   116 		hp = gethostbyname(host);
   117 		if(!hp) 
   118 			{
   119 			(void)fprintf(stderr, "finger: unknown host: %s\n", host);
   120 			exit(-3);
   121 			}
   122 		}
   123 	sin.sin_family = hp->h_addrtype;
   124 	memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
   125 	if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
   126 		perror("finger: socket");
   127 		exit(-4);
   128 	}
   129 
   130 	(void)printf("\n    %s => %s\n", hp->h_name, inet_ntoa(sin.sin_addr));
   131 
   132 	/* Step 2 - Connect to the finger port on the target host */
   133 
   134 	printf("\nConnecting to %s...", host);
   135 	fflush(stdout);
   136 
   137 	sin.sin_port = htons(IPPORT_FINGER);
   138 	if (connect(s, (struct sockaddr *)&sin, sizeof (sin))) {
   139 		perror("finger: connect");
   140 		exit(-5);
   141 	}
   142 
   143 	printf("OK\n");
   144 
   145 	/* Step 3 - Finger the user and read the result... */
   146 
   147 	printf("\nFinger %s@%s\n", name, host);
   148 
   149 	/* send the name followed by <CR><LF> */
   150 	sprintf(request, "%s\r\n", name);
   151 	if (write(s, request, strlen(request)) < 0) {
   152 		perror("finger: write");
   153 		close(s);
   154 		exit(-6);
   155 	}
   156 
   157 	/* Read from the remote system; once we're connected, we assume some
   158 	 * data.  If none arrives, we hang until the user interrupts.
   159 	 *
   160 	 * If we see a <CR> or a <CR> with the high bit set, treat it as
   161 	 * a newline; if followed by a newline character, only output one
   162 	 * newline.
   163 	 *
   164 	 * Otherwise, all high bits are stripped; if it isn't printable and
   165 	 * it isn't a space, we can simply set the 7th bit.  Every ASCII
   166 	 * character with bit 7 set is printable.
   167 	 */
   168 	lastc = '\n';
   169 
   170 	while (recv(s, &request[0], 1, 0) > 0) {
   171 		c = request[0];
   172 		if (c == 0x0d) {
   173 			if (lastc == '\r')	/* ^M^M - skip dupes */
   174 				continue;
   175 			c = '\n';
   176 			lastc = '\r';
   177 		} else {
   178 			if (!isprint(c) && !isspace(c)) {
   179 				c &= 0x7f;
   180 				c |= 0x40;
   181 			}
   182 			if (lastc != '\r' || c != '\n')
   183 				lastc = c;
   184 			else {
   185 				lastc = '\n';
   186 				continue;
   187 			}
   188 		}
   189 		putchar(c);
   190 	}
   191 	if (lastc != '\n')
   192 		putchar('\n');
   193 	close(s);
   194 
   195 	/* Step 4 - Check the time on the remote machine as well */
   196 
   197 	if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
   198 		perror("finger: socket");
   199 		exit(-7);
   200 	}
   201 
   202 	sin.sin_port = htons(IPPORT_DAYTIME);
   203 	if (connect(s, (struct sockaddr *)&sin, sizeof (sin))) {
   204 		perror("finger: connect");
   205 		exit(-8);
   206 	}
   207 
   208 	i = recv(s, request, sizeof(request)-1, 0);
   209 	if (i<0)
   210 		{
   211 		perror("finger: recv");
   212 		exit(-9);
   213 		}
   214 	request[i] = '\0';
   215 
   216 	printf("\nThe time on %s is %s\n", host, request);
   217 	close(s);
   218 
   219 	return 0;
   220 }