#ifndef FTPACCESS_H
#define FTPACCESS_H

#ifndef __DECCXX
#include <stream.h>
#endif
#include <iostream.h>
#include <qstrlist.h>
#include <qstringlist.h>
#include <stdlib.h>

#include <qtextstream.h>

class ftpaccess;
class ftpclass;
class ftplimit;
class ftpmessage;
class ftpupload;
class ftpvirtual;

#define	ANONYMOUS	1
#define	GUEST		2
#define REAL		4
#define ANONYMOUS_OUT	8
#define	GUEST_OUT	16
#define REAL_OUT	32

// Passwd-Check
#define NONE		0x0000
#define TRIVIAL		0x0001
#define RFC822		0x0002

#define WARN		0x0000
#define ENFORCE		0x0010

class ftpaccess {
	friend ostream &operator <<(ostream &os, ftpaccess &f);
public:
			ftpaccess(const QString & filename= QString::null);
			~ftpaccess();	

	bool		read(const QString & filename="/etc/ftpaccess");
	bool		write(const QString & filename="/etc/ftpaccess");
	void		addClass(const QString & cmd);
	void		addClass(ftpclass *c);
	void		removeClass(const QString & name);
	ftpclass *	getNextClass(ftpclass *previous=0);
	ftpclass *	seekClass(const QString & name);
	QStringList *	getNoRetrieves() { return noretrieves; };
	void		setLoginFails(unsigned int n) { loginfails=n; };
	unsigned int	getLoginFails() const { return loginfails; };
	void		setPrivate(bool p) { priv=p; };
	bool		getPrivate() const { return priv; };
	void		setBanner(QString const b) { banner=b; };
	QString const		getBanner() const { return banner; };
	void		setHostname(QString const h) { hostname=h; };
	QString const	getHostname() { return hostname; };
	void		setAdminMail(QString const m) { adminmail=m; };
	QString const	getAdminMail() const { return adminmail; };
	int		getNumMessages() const { return numMessages; };
	int		getNumReadmes() const { return numReadmes; };
	bool		getMsgShowEverytime() const { return msgShowEverytime; };
	void		setMsgShowEverytime(bool s) { msgShowEverytime=s; };
	bool		getRdmShowEverytime() const { return rdmShowEverytime; };
	void		setRdmShowEverytime(bool s) { rdmShowEverytime=s; };
	ftpmessage *	getFirstMessage() const;
	ftpmessage *	getNextMessage(ftpmessage *m) const;
	ftpmessage *	getMessage(unsigned int const num) const;
	void		addMessage(ftpmessage *m);
	ftpmessage *	getFirstReadme() const;
	ftpmessage *	getNextReadme(ftpmessage *r) const;
	ftpmessage *	getReadme(unsigned int const num) const;
	void		addReadme(ftpmessage *r);
	void		deleteMessage(ftpmessage *m);
	void		deleteMessage(int num);
	void		deleteReadme(ftpmessage *r);
	void		deleteReadme(int num);
	unsigned short	getChmod() const { return chmd; };
	unsigned short	getDelete() const { return delet; };
	unsigned short	getOverwrite() const { return overwrite; };
	unsigned short	getRename() const { return rename; };
	unsigned short	getUmask() const { return umsk; };
	unsigned short	getPwCheck() const { return passwd_check; };
	void		setChmod(unsigned short c) { chmd=c; };
	void		setDelete(unsigned short d) { delet=d; };
	void		setOverwrite(unsigned short o) { overwrite=o; };
	void		setRename(unsigned short r) { rename=r; };
	void		setUmask(unsigned short u) { umsk=u; };
	void		setPwCheck(unsigned short p) { passwd_check=p; };
	unsigned short	getLogCommands() { return logCommands; };
	unsigned short	getLogTransfers() { return logTransfers; };
	unsigned short	getLogSecurity() { return logSecurity; };
	bool		getLogSyslog() { return logSyslog; };
	void		setLogCommands(unsigned short l) { logCommands=l; };
	void		setLogTransfers(unsigned short l) { logTransfers=l; };
	void		setLogSecurity(unsigned short l) { logSecurity=l; };
	void		setLogSyslog(bool l) { logSyslog=l; };
	QString const	getAnonRoot() { return anonRoot; };
	QString const	getGuestRoot() { return guestRoot; };
	QString const	getPasswd() { return passwd; };
	QString const	getShadow() { return shadow; };
	void		setAnonRoot(QString const a);
	void		setGuestRoot(QString const g);
	void		setPasswd(QString const p);
	void		setShadow(QString const s);
	unsigned short	getUlDlRatio() const { return ulDlRatio; };
	unsigned short	getUlDlRatioWho() const { return ulDlRatioWho; };
	long		getLimitTime() const { return limitTime; };
	unsigned short	getLimitTimeWho() const { return limitTimeWho; };
	long		getLimitUpload() const { return limitUpload; };
	unsigned short	getLimitUploadWho() const { return limitUploadWho; };
	long		getLimitDownload() const { return limitDownload; };
	unsigned short	getLimitDownloadWho() const { return limitDownloadWho; };
	void		setUlDlRatio(unsigned short u) { ulDlRatio=u; };
	void		setUlDlRatioWho(unsigned short u) { ulDlRatioWho=u; };
	void		setLimitTime(long t) { limitTime=t; };
	void		setLimitTimeWho(unsigned short t) { limitTimeWho=t; };
	void		setLimitUpload(long l) { limitUpload=l; };
	void		setLimitUploadWho(unsigned short l) { limitUploadWho=l; };
	void		setLimitDownload(long l) { limitDownload=l; };
	void		setLimitDownloadWho(unsigned short l) { limitDownloadWho=l; };	
	QStringList *	getDlFree() const { return dlFree; };
	QStringList *	getDlFreeDir() const { return dlFreeDir; };
	bool		getMailAdmin() const { return mailAdmin; };
	QString const	getMailFrom() const { return mailFrom; };
	QString const	getMailServer() const { return mailServer; };
	QStringList *	getMailRecipients() const { return mailRecipients; };
	void		setMailAdmin(bool s) { mailAdmin=s; };
	void		setMailFrom(QString const s) { mailFrom=s; };
	void		setMailServer(QString const s) { mailServer=s; };
	ftpupload *	getFirstUpload() const;
	ftpupload *	getNextUpload(ftpupload *last) const;
	ftpupload *	getUploadNo(int num) const;
	int		getNumUploads() const;
	void		deleteUpload(int num);
	void		deleteUpload(ftpupload *u);
	void		addUpload(ftpupload *u);
	int		getNumVirtual() const { return numvirtual; };
	ftpvirtual **	getVirtual() const { return vhosts; };
	ftpvirtual *	getVirtual(int i) const { return vhosts[i]; };
	void		deleteVirtual(int n) { for(int i=n; i<numvirtual-1; i++) vhosts[i]=vhosts[i+1]; numvirtual--; };
	void		addVirtual(ftpvirtual *v);
private:
	void		cleanup();
// Directories
	QString		anonRoot;
	QString		guestRoot;
	QString		passwd;
	QString		shadow;
// Classes
	unsigned int	numclasses;
	ftpclass **	classes;
// Security
	QStringList *	noretrieves;
	unsigned int	loginfails;
	bool		priv;
	unsigned short	chmd;
	unsigned short	delet;
	unsigned short	overwrite;
	unsigned short	rename;
	unsigned short	umsk;
	unsigned short	passwd_check;
	QStringList *	deny_email;
// Messages
	QString		banner;
	QString		hostname;
	QString		adminmail;
	ftpmessage **	messages;
	ftpmessage **	readmes;
	unsigned int	numMessages;
	unsigned int	numReadmes;
	bool		msgShowEverytime;
	bool		rdmShowEverytime;
// Logging
	unsigned short	logCommands;
	unsigned short	logTransfers;
	unsigned short	logSecurity;
	bool		logSyslog;
	bool		mailAdmin;
	QString		mailFrom;
	QString		mailServer;
	QStringList *	mailRecipients;
// Ratios
	unsigned short	ulDlRatio;
	unsigned short	ulDlRatioWho;
	long		limitTime;
	unsigned short	limitTimeWho;
	long		limitUpload;
	unsigned short	limitUploadWho;
	long		limitDownload;
	unsigned short	limitDownloadWho;
	QStringList *	dlFree;
	QStringList *	dlFreeDir;
// Uploads
	int		numUploads;
	ftpupload **	uploads;
// Virtual
	int		numvirtual;
	ftpvirtual **	vhosts;
};
ostream &operator <<(ostream &os, ftpaccess &f);

class ftpclass {
	friend ostream &operator <<(ostream &os, ftpclass &f);
public:
			ftpclass(const QString & cmd=QString::null);
			~ftpclass();
	void		setAnon(bool anon);
	void		setGuest(bool guest);
	void		setReal(bool real);
	void		setName(QString const &newname);
	void		setAddrs(QString const &newaddrs);
	void		setAutogroup(QString const &group);
	void		addLimit(QString const &l);
	void		addLimit(ftplimit *l);
	void		deleteLimit(ftplimit const * const l);
	ftplimit *	getNextLimit(ftplimit const * const prev) const;
	bool const	isAnon() const;
	bool const	isGuest() const;
	bool const	isReal() const;
	QString const &	getName() const;
	QString const &	getAddrs() const;
	QString	const &	getAutogroup() const;
private:
	QString		name;
	int		users;
	QString		addrs;
	QString		auto_group;
	ftplimit *	first;
};
ostream &operator <<(ostream &os, ftpclass &f);

#define ANY	1
#define MO	2
#define TU	4
#define WE	8
#define TH	16
#define FR	32
#define SA	64
#define SU	128
class ftplimit {
	friend class ftpclass;
	friend ostream &operator <<(ostream &os, ftplimit &f);
public:
	ftplimit(QString const &limit=QString::null);
	ftplimit(int const num, QString const &t, QString const &msg);
	~ftplimit();
	void	setAny(bool any);
	void	setMo(bool mo);
	void	setTu(bool tu);
	void	setWe(bool we);
	void	setTh(bool th);
	void	setFr(bool fr);
	void	setSa(bool sa);
	void	setSu(bool su);
	void	setHours(QString const &h);
	void	setMsgfile(QString const &f);
	void	setNum(int const num)	{ numUsers=num; }
	void	addLimit(ftplimit *n);
	QString const getId() const;
	bool	isAny() const		{ return (weekdays&ANY)!=0; };
	bool	isMo() const		{ return (weekdays&MO)!=0; };
	bool	isTu() const		{ return (weekdays&TU)!=0; };
	bool	isWe() const		{ return (weekdays&WE)!=0; };
	bool	isTh() const		{ return (weekdays&TH)!=0; };
	bool	isFr() const		{ return (weekdays&FR)!=0; };
	bool	isSa() const		{ return (weekdays&SA)!=0; };
	bool	isSu() const		{ return (weekdays&SU)!=0; };
	QString	getHours() const	{ return hours; };
	QString	getMsgfile() const	{ return msgfile; };
	int	getNum() const		{ return numUsers; };
	ftplimit *	getNext() const { return next; };
private:
	void		setNextLimit(ftplimit *);
	unsigned short	weekdays;
	int		numUsers;
	QString 	msgfile;
	QString 	hours;
	ftplimit *	next;
};

class ftpmessage {
	friend ostream &operator <<(ostream &os, ftpmessage &f);
public:
	ftpmessage(bool Readme=false,bool Login=true,QString const &p=QString::null,QString const &d=QString::null,QString const &c=QString::null);
	~ftpmessage();
	void	setPath(QString const &p) { path=p.copy(); };
	QString const	&getPath() const { return path; };
	QString	const	getId() const;
	void	setReadme(bool r) { isReadme=r; };
private:
	bool		isReadme;
	bool		atLogin;
	QString		path;
	QString		dir;
	QString		cls;
};
ostream &operator <<(ostream &os, ftplimit &f);

class ftpupload {
	friend ostream &operator <<(ostream &os, ftpupload &f);
public:
		ftpupload();
		~ftpupload();
	void	setRootDir(QString const &r) { rootDir=r; };
	void	setDirGlob(QString const &g) { dirGlob=g; };
	void	setAllow(bool const a) { allow=a; };
	void	setOwner(QString const &o) { owner=o; };
	void	setGroup(QString const &g) { group=g; };
	void	setMode(unsigned short const m) { mode=m; };
	void	setPermitDirs(bool const p) { permitDirs=p; };
	void	setDMode(unsigned short const m) { dMode=m; };
	QString	const &getRootDir() const { return rootDir; };
	QString	const &getDirGlob() const { return dirGlob; };
	bool	getAllow() const { return allow; };
	QString	const &getOwner() const { return owner; };
	QString const &getGroup() const { return group; };
	unsigned short	getMode() const { return mode; };
	bool	getPermitDirs() const { return permitDirs; };
	unsigned short	getDMode() const { return dMode; };
	QString	const getId() const;
private:
	QString		rootDir;
	QString		dirGlob;
	bool		allow;
	QString		owner;
	QString		group;
	unsigned short	mode;
	bool		permitDirs;
	unsigned short	dMode;
};
ostream &operator <<(ostream &os, ftpupload &f);

class ftpvirtual {
	friend ostream &operator <<(ostream &os, ftpvirtual &f);
public:
	ftpvirtual();
	enum realusers { none, all, allowSpecified, denySpecified };
	QString const &	getIP() const { return IP; };
	QString const &	getRoot() const { return root; };
	QString const &	getBanner() const { return banner; };
	QString const &	getLogfile() const { return logfile; };
	QString const &	getHostname() const { return hostname; };
	QString const &	getEmail() const { return email; };
	QString const & getPasswd() const { return passwd; };
	QString const & getShadow() const { return shadow; };
	bool const	getAnon() const { return allowAnon; };
	enum realusers	getReal() const { return allowReal; };
	QStringList	getUserList() const { return users; };
	void		setIP(QString const &I) { IP=I; };
	void		setRoot(QString const &R) { root=R; };
	void		setBanner(QString const &B) { banner=B; };
	void		setLogfile(QString const &L) { logfile=L; };
	void		setHostname(QString const &H) { hostname=H; };
	void		setEmail(QString const &E) { email=E; };
	void		setPasswd(QString const &P) { passwd=P; };
	void		setShadow(QString const &S) { shadow=S; };
	void		setAnon(bool const A) { allowAnon=A; };
	void		setReal(enum realusers const &R) { allowReal=R; };
	void		clearUsers() { users.clear(); };
	void		addUser(QString const &U) { users.append(U); };
private:
	QString		IP;
	QString		root;
	QString		banner;
	QString		logfile;
	QString		hostname;
	QString		email;
	QString		passwd;
	QString		shadow;
	bool		allowAnon;
	enum realusers	allowReal;
	QStringList	users;
};
ostream &operator <<(ostream &os, ftpvirtual &f);

#endif
