/*
    Pirate Bulletin Board System
    Copyright (C) 1990, Edward Luke

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 1, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


    Email address:
    lush@Athena.EE.MsState.EDU
*/

#include "bbs.h"
#include "io.h"

struct protocols {
	char *pname ;
	char *sendbin ;
	char *recvbin ;
} ;

struct protocols protos[] =
{
{ "Kermit", "kermit -si", "kermit -ri"},
{ "Xmodem", "sx -b",      "rx"},
{ "Ymodem", "sb -b",      "rb"},
{ "Zmodem", "sz -b",      "rz"}
} ;


#define MAXDIRSIZE 80

#define NUMPROTOS (sizeof(protos)/sizeof(struct protocols))

char *
NameProtocol(id)
{
	if(id < 0 || id >= NUMPROTOS)
	  return "invalid" ;
	return protos[id].pname ;
}

char *
CurrentProtocol()
{
	return NameProtocol(currentuser.protocol);
}

char dirs[MAXDIRSIZE][STRLEN] ;
int numdirs = 0 ;
static char currfile[STRLEN] ;
int fileselect = 0 ;

char *
filemargin()
{
	static char buf[STRLEN] ;
	
	if(fileselect)
	  sprintf(buf,"File Sub-board is '%s'",currfile) ;
	else
	  sprintf(buf,"No File Sub-board Selected") ;
	return buf ;
}

#undef DIR

get_dir()
{
	DIR *dp ;
	struct direct *ent ;
	struct stat status ;

	numdirs = 0 ;
	if((dp = opendir("ftp/files")) == NULL)
	  return -1 ;
	for(ent=readdir(dp);ent!=NULL;ent=readdir(dp)) {
		if(!strcmp(ent->d_name,"."))
		  continue ;
		if(!strcmp(ent->d_name,".."))
		  continue ;
		if(!strcmp(ent->d_name,"upload_area"))
		  continue ;
		sprintf(genbuf,"ftp/files/%s",ent->d_name) ;
		if(lstat(genbuf,&status))
		  continue ;
		if(!(status.st_mode & (S_IFDIR | S_IFLNK)))
		  continue ;
		if(numdirs >= MAXDIRSIZE)
		  continue ;
		strcpy(dirs[numdirs],ent->d_name) ;
		numdirs++ ;
	}
	closedir(dp) ;
	return 0 ;
}


f_list()
{
	DIR *dp ;
	struct direct *ent ;
	struct stat status ;
	int i ;
	int col ;
	char buf[512] ;

	if(!fileselect) {
		move(3,0) ;
		clrtobot() ;
		prints("Use (S)elect to select a sub board first!\n") ;
		pressreturn() ;
		return -1 ;
	}
	move(3,0) ;
	clrtobot() ;
	prints("List of Files on bbs for download\n") ;
	prints("%-32s  Size","FILENAME") ;
	sprintf(buf,"ftp/files/%s",currfile) ;
	if((dp = opendir(buf)) == NULL)
	  return -1 ;
	i = 5 ;
	col = 0 ;
	for(ent=readdir(dp);ent!=NULL;ent=readdir(dp)) {
		if(!strcmp(ent->d_name,"."))
		  continue ;
		if(!strcmp(ent->d_name,".."))
		  continue ;
		sprintf(genbuf,"ftp/files/%s/%s",currfile,ent->d_name) ;
		if(stat(genbuf,&status))
		  continue ;
		if((status.st_mode & S_IFDIR))
		  continue ;
		if(i == 23) {
			col++ ;
			if(col == 2) {
				int ch ;
				move(23,0) ;
				standout() ;
				prints("-- More --") ;
				standend() ;
				while((ch = igetch()) != EOF) {
					if(ch == 'q') {
						closedir(dp) ;
						move(23,0) ;
						clrtoeol() ;
						return 0 ;
					}
					if(ch == '\n' || ch == '\r' || ch == ' ')
					  break ;
					bell() ;
				}
				col = 0 ;
				move(4,0) ;
				clrtobot() ;
			}
			move(4,col*39) ;
			prints("%-32s  Size","FILENAME") ;
			i = 5 ;
		}
		move(i,col*39) ;
		prints("%-32s %4dk",ent->d_name,(status.st_size+1023)>>10) ;
		i++ ;
	}
	closedir(dp) ;
	return 0 ;
}

f_create_namelist()
{
	DIR *dp ;
	struct direct *ent ;
	struct stat status ;

	if(!fileselect) {
		return -1 ;
	}
	CreateNameList() ;
	sprintf(genbuf,"ftp/files/%s",currfile) ;
	if((dp = opendir(genbuf)) == NULL)
	  return -1 ;
	for(ent=readdir(dp);ent!=NULL;ent=readdir(dp)) {
		if(!strcmp(ent->d_name,"."))
		  continue ;
		if(!strcmp(ent->d_name,".."))
		  continue ;
		sprintf(genbuf,"ftp/files/%s/%s",currfile,ent->d_name) ;
		if(stat(genbuf,&status))
		  continue ;
		if((status.st_mode & S_IFDIR))
		  continue ;
		AddNameList(ent->d_name) ;
	}
	closedir(dp) ;
	return 0 ;
}

f_download()
{
	char fname[STRLEN] ;
	char path[512] ;
	struct stat st ;

	if(!fileselect) {
		move(3,0) ;
		clrtobot() ;
		prints("Use (S)elect to select a sub board first!\n") ;
		pressreturn() ;
		return -1 ;
	}
	if (currentuser.protocol < 0 || currentuser.protocol >= NUMPROTOS)
	  return 0;
	f_create_namelist() ;
	move(0,0) ;
	prints("%s Download facility\n",CurrentProtocol()) ;
	prints("Enter Filename: ") ;
	clrtoeol() ;
	namecomplete(NULL,fname) ;
	sprintf(path,"/ftp/files/%s/%s",currfile,fname) ;
	if((*fname == '\0') || (stat(path,&st) == -1)) {
		move(2,0) ;
		prints("Invalid File Name\n") ;
		pressreturn() ;
		move(0,0) ;
		clrtoeol() ;
		move(1,0) ;
		clrtoeol() ;
		move(2,0) ;
		clrtoeol() ;
		return 1 ;
	}
	if((st.st_mode & S_IFDIR)) {
		move(1,0) ;
		prints("Invalid File Name\n") ;
		pressreturn() ;
		move(0,0) ;
		clrtoeol() ;
		move(1,0) ;
		clrtoeol() ;
		move(2,0) ;
		clrtoeol() ;
		return 1 ;
	}
    sprintf(genbuf,"downloading file '%s'",path) ;
    report(genbuf) ;
	move(3,0) ;
	clrtobot() ;
    reset_tty() ;
	printf("Using %s protocol\n",CurrentProtocol()) ;
	sprintf(genbuf,"%s %s",protos[currentuser.protocol].sendbin,path) ;
	do_exec(genbuf,NULL) ;
    restore_tty() ;
	clear() ;
    pressreturn() ;
	return 0 ;
}

f_upload()
{
	char buf[512] ;
	
	if(!fileselect) {
		move(3,0) ;
		clrtobot() ;
		prints("Use (S)elect to select a sub board first!\n") ;
		pressreturn() ;
		return -1 ;
	}
	if(currentuser.protocol < 0 || currentuser.protocol >= NUMPROTOS)
	  return 0;
	move(3,0) ;
	clrtobot() ;
    reset_tty() ;
	printf("Using %s protocol\n",CurrentProtocol()) ;
	sprintf(buf,"/ftp/files/upload_area/%s",currfile) ;
	chdir(buf);
    do_exec(protos[currentuser.protocol].recvbin,buf) ;
	sprintf(buf,"/");
	chdir(buf);
    restore_tty() ;
	clear() ;
	pressreturn() ;
	return 0 ;
}

f_protocol()
{
	int i ;
	char proto[STRLEN] ;

	move(3,0) ;
	clrtobot() ;
	prints("PROTOCOL MENU\n") ;
	for(i = 0 ; i < NUMPROTOS; i++)
	  prints("%d)  %s\n",i,protos[i].pname) ;
	move(2,0) ;
    prints("Enter Protocol id (0-%d): ", NUMPROTOS - 1) ;
	clrtoeol() ;
	getdata(0,0,NULL,proto,3,DOECHO,NULL) ;
	if(proto[0] == '\0')
	  return 0 ;
	i = atoi(proto) ;
	if(i < 0 || i >= NUMPROTOS)
	  return 0 ;
	clear() ;
	currentuser.protocol = i ;
	substitute_record(PASSFILE,&currentuser,sizeof(currentuser),usernum) ;
	return 0 ;
}

f_select()
{
	int i ;
	extern int numdirs ;
	extern char dirs[MAXDIRSIZE][STRLEN] ;
	char buf[STRLEN] ;

	get_dir() ;
	move(3,0) ;
	clrtobot() ;
	prints("FILE BOARDS MENU\n") ;
	clrtoeol();
	for(i=0; i < numdirs; i++) {
	  move(i%20+4,(i/20)*20) ;
	  prints("%2d) %s",i,dirs[i]) ;
	}
	move(2,0) ;
	prints("Enter file board id (0-%d): ", numdirs - 1) ;
	clrtoeol() ;
	getdata(0,0,NULL,buf,3,DOECHO,NULL) ;
	if(buf[0] == '\0')
	  return 0 ;
	i = atoi(buf) ;
	if(i < 0 || i >= numdirs)
	  return 0 ;
	clear() ;
	strcpy(currfile,dirs[i]) ;
	fileselect = 1 ;
	return 0 ;
}

f_text()
{
	char fname[STRLEN] ;
	char path[512] ;
	struct stat st ;

	if(!fileselect) {
		move(3,0) ;
		clrtobot() ;
		prints("Use (S)elect to select a sub board first!\n") ;
		pressreturn() ;
		return -1 ;
	}
	f_create_namelist() ;
	move(0,0) ;
	prints("Text Viewing Facility\n") ;
	prints("Enter Filename: ") ;
	clrtoeol() ;
    namecomplete(NULL,fname) ;
	sprintf(path,"/ftp/files/%s/%s",currfile,fname) ;
	if((*fname == '\0') || (stat(path,&st) == -1)) {
		move(2,0) ;
		prints("Invalid File Name\n") ;
		pressreturn() ;
		move(0,0) ;
		clrtoeol() ;
		move(1,0) ;
		clrtoeol() ;
		move(2,0) ;
		clrtoeol() ;
		return 1 ;
	}
	if((st.st_mode & S_IFDIR)) {
		move(1,0) ;
		prints("Invalid File Name\n") ;
		pressreturn() ;
		move(0,0) ;
		clrtoeol() ;
		move(1,0) ;
		clrtoeol() ;
		move(2,0) ;
		clrtoeol() ;
		return 1 ;
	}
    sprintf(genbuf,"Examining file '%s'",path) ;
    report(genbuf) ;
    more(path,YEA) ;
    clear() ;
	return 0 ;
}
