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