/* Internet Finger server */
/* Mods by KO4KS */
#include <stdio.h>
#include <string.h>
#include "global.h"
#include "files.h"
#include "mbuf.h"
#include "socket.h"
#include "session.h"
#include "proc.h"
#include "dirutil.h"
#include "commands.h"
#include "mailbox.h"

extern int ShowConfUsers __ARGS((int s));
extern int Sconv;
extern int Sftp;	/* Prototype socket for service */
extern int BbsUsers, FtpUsers;
#if defined(SCREENSAVER) || defined(TUTOR)
extern int Tutored;
#endif

static int Sfinger = -1;    /* Prototype socket for service */
static void fingerd __ARGS((int s,void *unused,void *p));
extern int dombusers __ARGS((int argc,char *argv[],void *p));
extern int dombmailstats __ARGS((int argc,char *argv[],void *p));
extern char *skipwhite __ARGS((char *cp));

extern int cb_lookup __ARGS((int, char *, FILE *));


/* Start up finger service */
int
finstart(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return (installserver (argc, argv, &Sfinger, "Finger listener", IPPORT_FINGER,
		"fingerd", fingerd, 1024, NULL));
}

#define FLINE 128

static void
fingerd(s,unused,p)
int s;
void *unused;
void *p;
{
char user[80], *uptr;
int ulen,found;
FILE *fp;
char *file,*cp;
char line[FLINE+1];
int doconf = 0, dobbs = 0;
#ifdef USERLOG
int outsave;
char *newargv[2];
#endif

	sockmode(s,SOCK_ASCII);
	sockowner(s,Curproc);
	log(s,"open Finger");
	recvline(s,user,80);
	rip(user);
	uptr = skipwhite(user);
	ulen = strlen(uptr);
	if (ulen)	{
#ifdef MSDOS
    		if (!strcmp (uptr, "con") || !strcmp (uptr, "aux"))	{
    			usprintf (s, "Can't finger '%s'... DOS Reserved Device Name\n", uptr);
			close_s(s);
			log(s,"close Finger");
			return;
		}
#endif
#ifdef CONVERS
    		if (!stricmp (uptr, "conf") || !stricmp (uptr, "stat"))
    			doconf = 1;
#endif
	    	if (!stricmp (uptr, "bbs") || !stricmp (uptr, "stat"))
    			dobbs = 1;
	}
	if(ulen && !strcmp(uptr,"iheard")) {
		outsave = Curproc->output;
		Curproc->output = s;
		doipheard(0,NULL,NULL);
		Curproc->output = outsave;
	} else if (doconf || dobbs)	{
		usprintf (s, "Current Status at %s\n\n", Hostname);
    		if (dobbs)	{
	    		if (!BbsUsers)
				usputs (s, "No users currently on the BBS\n");
			else if (Listusers != NULL)	{
		    		usputs (s, "Bulletin Board ");
				(*Listusers)(s);
			}
#ifdef CONVERS
			if (doconf && dobbs)	{
#else
			if (dobbs)	{
#endif
				if (Sftp == -1)
					usprintf (s, "\nFTP Server not started\n");
				else
					usprintf (s, "\nThere are %d in FTP Sessions\n", FtpUsers);
#ifdef TUTOR
				usprintf (s, "There are %d in Information Server Sessions\n", Tutored);
#endif
				usputs (s, "\n");
			}
			if (dobbs)	{
				outsave = Curproc->output;
				Curproc->output = s;
				dombmailstats(0,NULLCHARP,NULL);
				Curproc->output = outsave;
			}
		}
#ifdef CONVERS
		if (doconf)	{
			if(Sconv == -1)
				usputs(s,"Conference not started\n");
			else	{
				usputs (s, "Conference Bridge Users:\n");
				ShowConfUsers(s);
			}
		}
#endif
    	
	} else {
		if(ulen == 0){
			char buffer[128];
#ifdef MSDOS
			sprintf (buffer, "%s/*.", Fdir);
#else
			sprintf (buffer, "%s/*", Fdir);
#endif
			fp = dir(buffer,-1);
			if(fp == NULLFILE)
				usprintf(s,"No finger information available\n");
			else
				usprintf(s,"Known users on this system:\n");
		} else {
#ifdef SAMCALLB
			cb_lookup (s, uptr, (FILE *) 0);
#endif
#ifdef USERLOG
			outsave = Curproc->output;
			Curproc->output = s;
			newargv[1] = uptr;
			dombuserinfo(0,newargv,NULL);
			Curproc->output = outsave;
#endif
			file = pathname(Fdir,uptr);
			cp = pathname(Fdir,"");
			/* Check for attempted security violation (e.g., somebody
			 * might be trying to finger "../ftpusers"!) */
			if(strncmp(file,cp,strlen(cp)) != 0){
				fp = NULLFILE;
				usprintf(s,"Invalid user name %s\n",uptr);
			} else if((fp = fopen(file,READ_TEXT)) == NULLFILE)	{
				/* Now search the finger database file for this user - WG7J */
				found = 0;
				if((fp = fopen(Fdbase,READ_TEXT)) != NULLFILE) {
					while(fgets(line,FLINE,fp) != NULLCHAR)
						if(!strnicmp(line,uptr,(unsigned)ulen)) {
							usprintf(s,"%s", line);
							while(fgets(line,FLINE,fp) != NULLCHAR)	{
								if (line[1] && *line != ' ' && *line != '\t')
									break;
								else
									usprintf (s, line);
							}
							found = 1;
							break;
						}
					fclose(fp);
					fp = NULLFILE;
				}
				if(!found)
					usprintf(s,"No user info for %s\n",uptr);
			}
			free(cp);
			free(file);
		}
		if(fp != NULLFILE){
			sendfile(fp,s,ASCII_TYPE,0);
			fclose(fp);
		}
	}
	if(!ulen)	{
		usputs (s, "\n*** Additional information available by fingering:\n");
#ifdef CONVERS
		usputs (s, "    stat, conf, bbs, or iheard\n");
#else
		usputs (s, "    stat, bbs, or iheard\n");
#endif
		if(Listusers != NULL)	{
    			usputs (s, "\n");
			(*Listusers)(s);
		}
	}
	close_s(s);
	log(s,"close Finger");
}

int
fin0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return (deleteserver (&Sfinger));
}


