/* Copyright (C) 1999 Beau Kuiper

   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 2, 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.  */

#include "ftpd.h"
#include "ftpcmd.h"
#include "reply.h"

extern FTPCMD siteftpcmd[];

int ftp_site(FTPSTATE *peer, char *cmd)
{
	int result = FALSE;
	INPUTLINE acmd;
	
	/* if we were invoked without parameters */
	if (cmd == NULL)
		return(ftp_write(peer, FALSE, 500, REPLY_NOPARAM("SITE")));
	
	/* separate the site command from the site command parameters */
	cmd_split(peer, &acmd, cmd, siteftpcmd, FALSE, peer->sitedisableset);
	
	result = ftp_run(peer, &acmd, "SITE");
	
	if (acmd.parameters != NULL)
		freewrapper(acmd.parameters);

	return(result);
}

int ftpsite_dump(FTPSTATE *peer, char *cmd)
{
	NEWFILE *nfile = file_nfopen(peer, cmd);
	if (nfile != NULL) /* Log the transfer */
	{
		char *lfile = file_expand(peer, cmd);
		log_giveentry(MYLOG_FTRANS, peer, safe_snprintf("dump %s", lfile));
		freewrapper(lfile);
	}
	return(ftp_dumper(peer, nfile, 200, "SITE DUMP done!", FALSE, FALSE));
}

int ftpsite_umask(FTPSTATE *peer, char *cmd)
{
	int result = FALSE;
	int newumask = 0;
	
	if (peer->chmodable && cmd)
	{
		int res = sscanf(cmd, "%o", &newumask);

		newumask &= 0777;
		if (res == 0)
			result = ftp_write(peer, FALSE, 501, REPLY_UMASKBAD);
		else
		{
			result = ftp_write(peer, FALSE, 200, REPLY_UMASKNEW(newumask, peer->umask));
			peer->umask = newumask;
		}
	}
	else
	{
		result = ftp_write(peer, FALSE, 200, REPLY_UMASKCUR(peer->umask));
	}
	return(result);
}
	
int ftpsite_help(FTPSTATE *peer, char *cmd)
{
	return(ftp_dohelp(peer, siteftpcmd, cmd, peer->sitedisableset));
}

int ftpsite_idle(FTPSTATE *peer, char *cmd)
{
	int newtimeout;
	
	if (!cmd)
		return(ftp_write(peer, FALSE, 200, REPLY_TIMEOUTCURRENT(peer->timeout)));

	if (peer->maxtimeout < 30)
		return(ftp_write(peer, FALSE, 500, REPLY_TIMEOUTFIXED(peer->maxtimeout)));

	if (sscanf(cmd, "%d", &newtimeout) < 1)
		return(ftp_write(peer, FALSE, 500, REPLY_TIMEOUTNOTINT));
	
	if ((newtimeout >= 30) && (newtimeout <= peer->maxtimeout))
	{
		peer->timeout = newtimeout;
		ftp_write(peer, FALSE, 200, REPLY_TIMEOUTOK(peer->timeout));
	}
	else
		return(ftp_write(peer, FALSE, 500, REPLY_TIMEOUTRANGE(30, peer->maxtimeout)));

	return(3); /* make sure timeout gets updated! */
}

int ftpsite_chmod(FTPSTATE *peer, char *cmd)
{
	int result = FALSE;
	
	if (peer->chmodable)
	{
		int newmode;
		char *mode = NULL;
				
		if (cmd != NULL)
			mode = getkeyword(&cmd);

		if (cmd == NULL)
			result = ftp_write(peer, FALSE, 501, REPLY_CHMODNOPARMS);
		else if (sscanf(mode, "%o", &newmode) == 0)
			result = ftp_write(peer, FALSE, 501, REPLY_CHMODBADMODE);
		else
		{
			newmode &= 0777;
			result = ftp_chmod(peer, cmd, newmode);
		}
				
		freeifnotnull(mode);
	}
	else
		result = ftp_write(peer, FALSE, 500, REPLY_CHMODDENIED);
	
	return(result);
}

int ftpsite_access(FTPSTATE *peer, char *cmd)
{
	int count = 0;
	char aclinfo[12];
	char replystr[5];
	
	if (config->altlongreplies)
		strcpy(replystr, "211-");
	else
		strcpy(replystr, "    ");
		
	ftp_write(peer, TRUE, 0, REPLY_ACCESSFIRST(peer->username));
	ftp_write(peer, TRUE, 0, REPLY_ACCESSSECOND(replystr));
	ftp_write(peer, TRUE, 0, replystr);
	
	/* this accesses the insides of the acllist. I shouldn't, but
	   it is the easiest way of doing it */
	
	while(count < peer->acldata->aclcount)
	{
		acllist_makepermstr(peer->acldata, count, aclinfo);
		if (aclinfo[0] == 0)
			strcpy(aclinfo, "no access");
		ftp_write(peer, TRUE, 0, "%s%-60s %s", replystr, peer->acldata->acls[count].dir, aclinfo);
		count++;
	}

	ftp_write(peer, FALSE, 211, REPLY_ACCESSEND);
	return(FALSE);
}

