genericopenlibs/cstdlib/TSTLIB/FINGER.C
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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 }