home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
internet
/
tcpipsrc
/
Finger
/
c
/
fingcli
next >
Wrap
Text File
|
1994-08-20
|
7KB
|
298 lines
/*
*
* Finger support...
*
* Finger client routines. Written by Michael T. Horne - KA7AXD.
* Copyright 1988 by Michael T. Horne, All Rights Reserved.
* Permission granted for non-commercial use and copying, provided
* that this notice is retained.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "global.h"
#include "mbuf.h"
#include "domain.h"
#include "timer.h"
#include "internet.h"
#include "icmp.h"
#include "netuser.h"
#include "tcp.h"
#include "finger.h"
#include "session.h"
#include "misc.h"
#include "Terminal.h"
#include "vterm.h"
extern char badhost[], hostname[];
/* Open up a socket to a remote (or the local) host on its finger port. */
int dofinger(int argc, char **argv)
{
struct session *s;
struct tcb *tcb;
struct socket lsocket,
fsocket;
struct finger *finger;
char *host;
if (argc < 2)
{
cwprintf(NULL, "usage: %s [user | user@host | @host]\r\n", argv[0]);
return(1);
}
lsocket.address = ip_addr;
lsocket.port = lport++;
/* Extract user/host information. It can be of the form:
finger user, # finger local user
finger user@host, # finger remote user
finger @host # finger host (give system status)
*/
if ((finger = alloc_finger()) == NULLFING)
return(1);
if ((host = strchr(argv[1], '@')) == NULL)
{
fsocket.address = ip_addr; /* no host, use local */
if ((finger->user = malloc(strlen(argv[1]) + 3)) == NULL)
{
free_finger(finger);
return(1);
}
strcpy(finger->user, argv[1]);
strcat(finger->user, "\015\012");
}
else
{
*host++ = '\0'; /* null terminate user name */
if (*host == '\0')
{ /* must specify host */
cwprintf(NULL, "%s: no host specified\r\n", argv[0]);
cwprintf(NULL, "usage: %s [user | user@host | @host]\r\n", argv[0]);
free_finger(finger);
return(1);
}
if ((fsocket.address = resolve(host)) == 0)
{
cwprintf(NULL, "%s: ", argv[0]);
cwprintf(NULL, badhost, host);
free_finger(finger);
return(1);
}
if ((finger->user = malloc(strlen(argv[1])+3))==NULL)
{
free_finger(finger);
return 1;
}
strcpy(finger->user, argv[1]);
strcat(finger->user, "\015\012");
}
fsocket.port = FINGER_PORT; /* use finger wnp */
/* Allocate a session descriptor */
if ((s = newsession()) == NULLSESSION)
{
cwprintf(NULL, "Too many sessions\r\n");
free_finger(finger);
return 1;
}
finger->window = Window_Open(s, "Finger", term_NO_INPUT);
vterm_visible(finger->window->vt, 50, 10);
vterm_parse(finger->window->vt, argc-2, argv+2);
current = s;
s->cb.finger = finger;
finger->session = s;
s->window = finger->window;
if (!host) /* if no host specified */
host = hostname; /* use local host name */
if ((s->name = malloc(strlen(host)+1)) != NULLCHAR)
strcpy(s->name, host);
s->type = FINGER;
s->parse = NULLVFP;
tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
(void(*)())fingcli_rcv, NULLVFP, (void(*)())f_state, 0, (char *)finger);
finger->tcb = tcb;
tcb->user = (char *) finger;
go(s);
return 0;
}
/* Allocate a finger structure for the new session */
struct finger *alloc_finger(void)
{
struct finger *tmp;
if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
return(NULLFING);
tmp->session = NULLSESSION;
tmp->user = (char *) NULL;
tmp->window = NULL;
return(tmp);
}
/*
* Free a finger structure
*/
int free_finger(struct finger *finger)
{
if (finger != NULLFING)
{
if (finger->session != NULLSESSION)
freesession(finger->session);
if (finger->user != (char *) NULL)
free(finger->user);
free(finger);
}
return 0;
}
/* Finger receiver upcall routine */
void fingcli_rcv(register struct tcb *tcb, int16 cnt)
{
extern int ttyflow;
struct finger *finger = (struct finger *)tcb->user;
struct mbuf *bp;
register char *buf;
register char *s;
char *line;
/* Make sure it's a valid finger session */
if (finger == NULLFING)
{
return;
}
/* Hold output if we're not the current session */
if (finger->window == NULL && (mode != CONV_MODE || current == NULLSESSION
|| current->type != FINGER || ttyflow == 0))
return;
/* We process the incoming data stream and make sure it
meets our requirments. A check is made for control-Zs
since these characters lock up DoubleDos when sent to
the console (don't you just love it...). */
if (recv_tcp(tcb, &bp, cnt) > 0)
{
if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
{
cwprintf(finger->window, "Out of memory in FINGCLI\r\n");
free_p(bp);
return;
}
while (bp != NULLBUF)
{
buf = bp->data;
while(bp->cnt--)
{
switch(*buf)
{
/* case '\012': */ /* ignore LF */
case '\032': /* NO ^Z's! */
break;
/* case '\015':
*s++ = '\n';
break; */
default:
*s++ = *buf;
break;
}
buf++;
}
bp = free_mbuf(bp);
}
*s = '\0';
cwputs(finger->window, line);
free(line);
}
}
/* State change upcall routine */
void f_state(register struct tcb *tcb, char old, char new)
{
struct finger *finger;
char notify = 0;
extern char *tcpstates[];
extern char *reasons[];
extern char *unreach[];
extern char *exceed[];
struct mbuf *bp;
old = old;
finger = (struct finger *)tcb->user;
if (finger->window || (current != NULLSESSION && current->type == FINGER))
notify = 1;
switch(new)
{
case CLOSE_WAIT:
if (notify)
cwprintf(finger->window, "%s\r\n", tcpstates[new]);
close_tcp(tcb);
break;
case CLOSED: /* finish up */
if(notify)
{
cwprintf(finger->window, "%s (%s", tcpstates[new], reasons[tcb->reason]);
if (tcb->reason == NETWORK)
{
switch(tcb->type)
{
case DEST_UNREACH:
cwprintf(finger->window, ": %s unreachable", unreach[tcb->code]);
break;
case TIME_EXCEED:
cwprintf(finger->window, ": %s time exceeded", exceed[tcb->code]);
break;
}
}
cwprintf(finger->window, ")\r\n");
cmdmode();
}
if (finger != NULLFING)
{
if (finger->window)
{
finger->window->Attr = ATTR_REVERSE;
finger->window->Flags.flags.dont_destroy = FALSE;
finger->window->Session = NULL;
Window_CloseDown(finger->window);
}
free_finger(finger);
}
del_tcp(tcb);
break;
case ESTABLISHED:
if (notify)
{
cwprintf(finger->window, "%s\r\n", tcpstates[new]);
}
cwprintf(finger->window, "[%s]\r\n", finger->session->name);
bp = qdata(finger->user, (int16) strlen(finger->user));
send_tcp(tcb, bp);
break;
default:
if (notify)
cwprintf(finger->window, "%s\r\n",tcpstates[new]);
break;
}
}