317 lines
7.2 KiB
C
317 lines
7.2 KiB
C
/*
|
|
*
|
|
* Finger support...
|
|
*
|
|
* Finger server 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.
|
|
*
|
|
* Fixed the jacking around with \n in unix systems so finger wouldn't
|
|
* send a continuous stream of characters - sheesh! - K5JB
|
|
*/
|
|
|
|
#include "config.h"
|
|
#ifdef _FINGER
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "sokname.h"
|
|
#include "global.h"
|
|
#include "mbuf.h"
|
|
#include "timer.h"
|
|
#include "internet.h"
|
|
#include "icmp.h"
|
|
#include "netuser.h"
|
|
#include "tcp.h"
|
|
#include "ftp.h"
|
|
#include "telnet.h"
|
|
#include "iface.h"
|
|
#include "ax25.h"
|
|
#include "lapb.h"
|
|
#include "finger.h"
|
|
#include "session.h"
|
|
#include "nr4.h"
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
/* on amateur radio, unwritten convention is just end lines with CR, but
|
|
* NOS keys on LF so we have to stick with the CR/LF convention here.
|
|
* Made this discovery with k28. Since MS-DOS files have CR/LF, they get
|
|
* no special treatment, but Unix file \n is replaced by \r\n and OS9/OSK
|
|
* files get \r replaced with \r\n.
|
|
*/
|
|
|
|
struct tcb *fing_tcb = NULLTCB;
|
|
int16 finger_notify = 1;
|
|
void free();
|
|
|
|
finger1(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
extern int32 ip_addr;
|
|
struct socket lsocket;
|
|
void fing_state();
|
|
void rcv_fing();
|
|
int atoi();
|
|
|
|
if (fing_tcb)
|
|
return;
|
|
/* start finger daemon */
|
|
lsocket.address = ip_addr;
|
|
if(argc < 2)
|
|
lsocket.port = FINGER_PORT;
|
|
else
|
|
lsocket.port = atoi(argv[1]);
|
|
fing_tcb = open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, rcv_fing,
|
|
NULLVFP, fing_state, 0, NULLCHAR);
|
|
return;
|
|
}
|
|
/*
|
|
* Handle incoming finger connections and closures.
|
|
*
|
|
*/
|
|
void
|
|
fing_state(tcb,unused,new)
|
|
struct tcb *tcb;
|
|
char unused, /* old state */
|
|
new; /* new state */
|
|
{
|
|
struct finger *fing;
|
|
void snd_fing(),log();
|
|
char *psocket();
|
|
#ifdef SOKNAME
|
|
char *puname();
|
|
#endif
|
|
|
|
switch(new){
|
|
case ESTABLISHED:
|
|
log(tcb,"open Finger");
|
|
fing = (struct finger *) malloc(sizeof(struct finger));
|
|
|
|
tcb->user = (char *)fing; /* Upward pointer */
|
|
fing->tcb = tcb; /* Downward pointer */
|
|
if (finger_notify) {
|
|
printf("You're being fingered by %s!\n",
|
|
#ifdef SOKNAME
|
|
puname(&tcb->conn.remote));
|
|
#else
|
|
psocket(&tcb->conn.remote));
|
|
#endif
|
|
fflush(stdout);
|
|
}
|
|
return;
|
|
case CLOSED:
|
|
if (tcb == fing_tcb)
|
|
fing_tcb = NULLTCB;
|
|
if (tcb->user != NULLCHAR)
|
|
free(tcb->user);
|
|
del_tcp(tcb);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Stop the finger server.
|
|
*/
|
|
|
|
finger0()
|
|
{
|
|
if (fing_tcb != NULLTCB) {
|
|
close_tcp(fing_tcb);
|
|
fing_tcb = NULLTCB;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#ifndef _TELNET /* interesting dupe found */
|
|
/*
|
|
* Send a short message on a tcb
|
|
*/
|
|
|
|
static void
|
|
sndmsg(tcb, msg)
|
|
struct tcb *tcb; /* tcb to send on */
|
|
char *msg; /* message to send */
|
|
{
|
|
struct mbuf *bp;
|
|
|
|
bp = qdata(msg,(int16)strlen(msg));
|
|
send_tcp(tcb,bp);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Finger receive upcall. This is the guts of the finger server.
|
|
* The user to finger is read from the socket. If only a newline
|
|
* is read, then send the remote host a list of all known 'users' on
|
|
* this system.
|
|
*/
|
|
|
|
void
|
|
rcv_fing(tcb, unused)
|
|
register struct tcb *tcb;
|
|
int16 unused;
|
|
{
|
|
FILE *fuser;
|
|
void filedir(),sndmsg();
|
|
struct mbuf *mbuf, *bp;
|
|
char *buf,
|
|
*who,
|
|
*finger_file,
|
|
*path,
|
|
temp[80],
|
|
user[80];
|
|
int ch, cnt;
|
|
#if (UNIX || MAC || AMIGA || ATARI_ST || _OSK)
|
|
static int savedch = FALSE;
|
|
#endif
|
|
int size;
|
|
/* removed unnecessary assignment here - K5JB */
|
|
if (((struct finger *) tcb->user) == NULLFING) /* uh oh! */
|
|
return;
|
|
|
|
if(recv_tcp(tcb,&bp,FINGNAMELEN) == 0)
|
|
return;
|
|
if ((who = (char *)malloc(FINGNAMELEN + 1)) == NULLCHAR) { /* 8 or 11 bytes + 1 */
|
|
free_p(bp);
|
|
return;
|
|
}
|
|
|
|
cnt = pullup(&bp, who, FINGNAMELEN); /* get 'user' name */
|
|
who[cnt] = '\0'; /* NULL terminate it */
|
|
free_p(bp); /* all done with bp */
|
|
|
|
if (*who == '\015' || *who == '\012') { /* give him a user listing */
|
|
int found = 0;
|
|
|
|
path = (char *) malloc(strlen(fingerpath) + strlen(fingersuf)
|
|
+ 2);
|
|
/* create wildcard path to finger files */
|
|
strcpy(path, fingerpath);
|
|
strcat(path, "*");
|
|
strcat(path, fingersuf);
|
|
|
|
sndmsg(tcb, "Known users on this system:\015\012");
|
|
for (filedir(path, 0, user); user[0] != '\0';
|
|
filedir (path, 1, user)) {
|
|
found++;
|
|
*index(user, '.') = '\0';
|
|
sprintf(temp, " %s\015\012", user);
|
|
sndmsg(tcb, temp);
|
|
}
|
|
if (!found)
|
|
sndmsg(tcb, "None!\015\012");
|
|
|
|
free(path);
|
|
}
|
|
else {
|
|
buf = who;
|
|
while (*buf != '\015' && *buf != '\012' && *buf != '\0')
|
|
buf++;
|
|
*buf = '\0';
|
|
/*
|
|
* Create path to user's finger file and see if the
|
|
* the file exists.
|
|
*/
|
|
finger_file = (char *)malloc(strlen(fingerpath) + strlen(who)
|
|
+ strlen(fingersuf) + 1);
|
|
if (finger_file == NULLCHAR) { /* uh oh... */
|
|
free(who); /* clean up */
|
|
close_tcp(tcb); /* close socket */
|
|
return;
|
|
}
|
|
strcpy(finger_file, fingerpath);
|
|
strcat(finger_file, who);
|
|
strcat(finger_file, fingersuf);
|
|
|
|
if((fuser = fopen(finger_file, binmode[READ_BINARY])) == NULLFILE){
|
|
sprintf(temp, "User %s unknown on this system\015\012",who);
|
|
sndmsg(tcb, temp);
|
|
}
|
|
else { /* valid 'user' */
|
|
|
|
/*
|
|
* Here's a tricky routine to make sure we get
|
|
* everything in, including "\r\n". It's needed since
|
|
* UNIX files have only a '\n' for EOL. What is
|
|
* REALLY NEEDED is a standardized routine for filling
|
|
* mbufs from file input so that each server doesn't
|
|
* have to do it themselves! Ditto for emptying
|
|
* mbufs! The problem of "\r\n" doesn't rear its
|
|
* ugly head with MessyDOS, but with UNIX boxes...
|
|
*
|
|
* This is REALLY UGLY -- I'll redo it sometime - K5JB
|
|
* I can't stand it any longer! Now is the time - 6/15/91
|
|
* Went back and put CR/LF back in for Unix. At this point
|
|
* I will assume MS-DOS files used are correct - 1/7/92
|
|
*/
|
|
|
|
do{
|
|
size = tcb->window;
|
|
if ((mbuf = alloc_mbuf(size)) == NULLBUF) {
|
|
fclose(fuser); /* barf */
|
|
free(who);
|
|
free(finger_file);
|
|
return;
|
|
}
|
|
buf = mbuf->data; /* pointer to buffer */
|
|
|
|
#if (UNIX || MAC || AMIGA || ATARI_ST || _OSK)
|
|
if(savedch){ /* unlikely case */
|
|
*buf++ = '\015';
|
|
*buf++ = '\012';
|
|
mbuf->cnt += 2;
|
|
size -= 2;
|
|
savedch = FALSE;
|
|
}
|
|
#endif
|
|
while((ch = fgetc(fuser)) != EOF){
|
|
switch((char)ch) {
|
|
case '\032': /* NO ^Z's! - they clear screens */
|
|
break;
|
|
#if (UNIX || MAC || AMIGA || ATARI_ST || _OSK)
|
|
#ifdef _OSK
|
|
case '\012': /* OS9/K and maybe The Mac use \r as end of */
|
|
break; /* line so do this differently from Unix */
|
|
case '\015': /* convert CR to CR/LF */
|
|
ch = '\012';
|
|
#else
|
|
case '\r': /* ignore \r */
|
|
break;
|
|
case '\n': /* convert LF to CR/LF */
|
|
#endif
|
|
if(size == 1){ /* unlikely case, no room for 2 chars */
|
|
savedch = TRUE;
|
|
size = 0; /* make it a short one - drop out */
|
|
break;
|
|
}
|
|
*buf++ = '\015';
|
|
mbuf->cnt++;
|
|
size--;
|
|
/* and fall through */
|
|
#endif
|
|
default:
|
|
*buf++ = (char)ch;
|
|
mbuf->cnt++;
|
|
size--;
|
|
break;
|
|
}
|
|
if(size == 0)
|
|
break;
|
|
} /* !feof() */
|
|
send_tcp(tcb, mbuf); /* send info */
|
|
}while(ch != EOF); /* do - outside loop */
|
|
fclose(fuser);
|
|
}
|
|
free(finger_file);
|
|
}
|
|
free(who);
|
|
close_tcp(tcb); /* close socket */
|
|
return;
|
|
}
|
|
#endif
|