/* macros for reply strings */

/* this is used to go tell a client to go to hell if it tries to send more
   than one command at a time! */
   
#define REPLY_ONECMDONLY 	"Only one command at a time."

/* this is used to tell a user the server is shutting down and they are being
   forcibly logged out! */

#define REPLY_SERVERSHUTDOWN 	"Goodbye, server shutting down, logging out."

/* this is used to tell a user that regular timeout has occurred. Parameter is
   how many seconds timeout is*/

#define REPLY_TIMEOUT(tv) 	"Goodbye, timeout occured (%d sec), logging out.", tv

/* this is the default message used to greet a user as they connect */

#define REPLY_GREET		PROGNAME" ("VERSTR") server ready. Enter Username."

/* this is used when deleting a file. Parameter is the filename. */

#define REPLY_DELETE(filename)	"Deleting file '%s'", filename

/* this is used when chmoding a file. Parameter 1 is the filename, 2 is the
   new mode */
   
#define REPLY_CHMOD(filename, modenum) "Changing mode on file %s to %03o.", filename, modenum

/* this is used when the client specifies the name of the source file to
   rename */
   
#define REPLY_RENAMESOURCE	"Source ready, waiting for destination."

/* this is used when the user did not specify a file to rename from using RNFR */

#define REPLY_RENAMENOSOURCE	"Specify the source to rename first."

/* this is used when the use successfully renames a file. First paramter is
   source file, second is the destination. */

#define REPLY_RENAME(file1, file2) "Renaming '%s' to '%s'", file1, file2

/* this is used when a new directory is created. Parameter is the new directory
   name. RFC requires that this reply is formatted with new directory name
   in quotes at beginning of reply! */

#define REPLY_MKDIR(newdir)	"\x22%s\x22 was created", newdir

/* this is used when a directory is removed. Parameter is the directory that
   was removed. */

#define REPLY_RMDIR(dirname)	"Directory '%s' removed", dirname

/* this is used when directories are changed OR when the user asks for the
   current directory. Parameter is the new directory. It is a RFC requirement 
   that the current directory be at the begining of the reply, enclosed in 
   double quotes */

#define REPLY_PWD(dirname)	"\x22%s\x22 is the current directory.", dirname

/* this is used when the command a client enters is not recognised. parameter
   is the command that isn't understood */

#define REPLY_CMDNOTKNOWN(cmd)	"%s: command not recognised.", cmd

/* this is used when a command a client enters requires parameters that were
   not given by the client. Parameter is the command that the user entered. */

#define REPLY_NOPARAM(cmd)	"%s: parameters needed.", cmd

/* this is used when the user enters a command that requires login status
   but the user isn't logged in. Typically, you should never see this message
   since new code hides invalid commands from use. It may be removed in the
   future. */

#define REPLY_NOLOGIN		"Please login first."

/* this is used when the user issues a command that is not valid while a 
   data connection is established. The parameter is the command the user
   issued */

#define REPLY_DATACONNINVALID(cmd) "%s: command not valid during data connection.", cmd

/* this is used when the user quits. */

#define REPLY_QUIT		"Goodbye, logging out."

/* this is used when the user tries to login as another user when jailing is
   enabled */

#define REPLY_JAILUSER		"You cannot log on as another user."

/* this is used when the user has had too many failed login attempts! */

#define REPLY_NOCREDITS		"You have run out of login credits."

/* this is used when the user executes the USER command. Parameter is the 
   username they entered */

#define REPLY_USER(user)	"Welcome '%s', enter password to login.", user

/* this is used when the user executes the PASS command, but is already logged
   in. */

#define REPLY_ALREADYLOGGEDIN	"Already logged in!"

/* this is used when the user executes the PASS command, but has not executed
   a user command first */
   
#define REPLY_USEUSERFIRST	"Supply a username first."

/* this is used when PASS results in successful login. Parameter is the 
   username */

#define REPLY_PASSOK(username)	"User '%s' login successful.", username

/* this is used when login fails due to too many users logged in */

#define REPLY_TOOMANYUSERS	"Too many users. Cannot login."

/* this is used when login fails to bad password or similar error. First
   parameter is the username and the second is the reason login failed, in
   english. */

#define REPLY_LOGINFAIL(username, reason) "Login for user '%s' failed (%s).", username, reason

/* this is used for the REST command, when the resume value is invalid */

#define REPLY_INVALIDREST	"Resume value is not valid."

/* this is used for the REST command, when resume value is set, First parameter
   is new value resume is set to */

#define REPLY_RESTOK(posval)	"Starting at position %s", offt_tostr(posval)

/* this is used when the PORT command is used but a client told muddleftpd to
   connect to it on a privlidged port. */
   
#define REPLY_PORTBADPORT	"PORT must specify port between 1024 and 65535."

/* this is used when the PORT command is used but the client told muddleftpd to
   connect to a different server than the control port came from, but allowfxp
   was not set */

#define REPLY_PORTBADFXP	"PORT must specify IP same as control IP."

/* this is used when the PORT command succeeds. The 4 parameters are integer
   parts of the IP address. 5th is the remote port to connect to */
   
#define REPLY_PORTOK(ipa,ipb,ipc,ipd,portnum)	"PORT command successful. Data port is %d.%d.%d.%d port %d.", ipa, ipb, ipc, ipd, portnum

/* this is used for bad Port parameters */

#define REPLY_PORTBADPARM	"Invalid parameters for PORT command."

/* this is for setting the type to ASCII */

#define REPLY_TYPEASCII		"TYPE is now ASCII."

/* this is for setting type to BINARY */

#define REPLY_TYPEBINARY	"TYPE is now BINARY."

/* this is for unimplemented types */

#define REPLY_TYPEUNIMP		"Unimplemented TYPE."

/* this for aborting connections */

#define REPLY_ABORT		"ABOR Successful."

/* this is for passive connections. The RFC states that the end of the
   reply, the ip and then upper 16 and lower 16 bits of the port, separated
   by commas must be enclosed in brackets */

#define REPLY_PASV(p1,p2,p3,p4,p5,p6)	"Entering Passive Mode (%d,%d,%d,%d,%d,%d)", p1, p2, p3, p4, p5, p6

/* this is for the no operation reply */

#define REPLY_NOOP		"No operation was successful."

/* this is used for help when the command the client wants help for is
   not known (or disabled). Parameter is the unknown command */

#define REPLY_HELPUNKNOWN(cmd)	"Command '%s' not known.", cmd

/* this is the first line of the multi-line reply for help. It must begin with
   214- */

#define REPLY_HELPSTART		"214-Recognized commands:"

/* this is the last line of the multi-lined reply to help. parameter is 
   the email specified in the config file */

#define REPLY_HELPEND(emailaddr) "End of help. Send comments to %s", emailaddr

/* this is the reply when the client does an ALLO (allocate space) */

#define REPLY_ALLO		"Space allocation unnessecary."

/* this is the reply when the client does an ACCT (account) */

#define REPLY_ACCT		"Account unnessecary."

/* this is the reply when the client asks for file structure with 
   the command STRU */

#define REPLY_STRUFILE		"STRU File OK."

/* this is the reply when the client asks for any other structure to file */

#define REPLY_STRUUNKNOWN	"Unknown STRU type."

/* this is the reply for when a transfer is done. The number of bytes is the
   parameter */
   
#define REPLY_TRANSDONE(count)	"Transfer done. %s bytes transferred.", offt_tostr(count)

/* this is the reply for when a transfer is aborted. The number of bytes 
   transferred is the parameter */

#define REPLY_TRANSABORT(count)	"Transfer aborted. %s bytes transferred.", offt_tostr(count)

/* this is the reply for when byte credits are exhausted. It is the a multi-line
   reply line */

#define REPLY_BYTELIMIT		"426-Byte download credits exhausted."

/* this is the reply for when file credits are exhausted. */

#define REPLY_FILELIMIT		"File download credits exhausted."

/* this is the reply when a client tries to resume an ascii upload (cannot
   be done) */

#define REPLY_RESUMEASCIIUP	"Cannot resume ASCII upload. Use APPE."

/* this is the reply when stou cannot determine a unique filename to use */

#define REPLY_STOUNOUNIQUE	"Could not determine an unique filename."

/* this is the reply when a passive connection is stolen by a computer
   without the same IP as the client. */

#define REPLY_PASSIVEBADHOST	"Passive connection not from your host, disconnecting."

/* this is the reply when a transfer for a directory listing is being
   announced */

#define REPLY_TRANSLISTSTART	"Starting ASCII transfer for file listing."

/* this is the string used when a transfer is being started. First parametsr
   is the mode the file is being transferred in, second is the size of the
   file, which must go at the end of the string */

#define REPLY_TRANSSTART(type,size)	"Starting %s transfer.%s", type, size

/* this is the string used when a transfer is being resumed. First parameter
   is the file transfer mode, second is the starting offset, third is the
   size of the file, which must go at the end of the string */

#define REPLY_TRANSRESUME(type,offsetpos,size)	"Starting %s transfer at offset %s.%s", type, offt_tostr(offsetpos), size

/* this is used when a file transfer is aborted after a transfer command
   starts but before the data connection is established. */

#define REPLY_TRANSSTILLBORN	"Data connection in progress cancelled."

/* This is used when the new umask given to the server is not parsable */

#define REPLY_UMASKBAD		"UMASK must be octal value."

/* this is used when a new umask is set. First parameter is the new umask,
   second is the old */

#define REPLY_UMASKNEW(nu,ou)	"New UMASK is %03o (old was %03o)", nu, ou

/* this is used when the current umask is returned. First parameter is the umask */

#define REPLY_UMASKCUR(cmask)	"Current UMASK is %03o", cmask

/* this is used when the timeout is returned. Paramter is the current
   timeout value */

#define REPLY_TIMEOUTCURRENT(val) "Timeout is set to %d seconds.", val

/* this is used when the timeout in the config file is less than 30 seconds,
   and cannot be adjusted by the client. Parameter is the current timeout
   value */

#define REPLY_TIMEOUTFIXED(val)	"Timout too small to be adjusted. (%d sec)", val

/* this is used when the client doesn't send a integer timeout to the timeout
   command */
   
#define REPLY_TIMEOUTNOTINT	"Timeout must be an integer value."

/* this is used when the timeout command is successful in setting a new
   timeout. First parameter is the new timeout value */
   
#define REPLY_TIMEOUTOK(tout)	"Timeout set to %d seconds.", tout

/* this is used when the timeout value specified is out of range. First	
   parameter is the minimun, second is the maximun timeouts */

#define REPLY_TIMEOUTRANGE(t1, t2) "Timeout must be between %d and %d seconds.", t1, t2

/* this is used when chmod is called with no parameters. */

#define REPLY_CHMODNOPARMS	"SITE CHMOD expects mode and filename parameters."

/* this is used when chmod is called with a non octal value mode */

#define REPLY_CHMODBADMODE	"SITE CHMOD requires octal mode number."

/* this is used when access to site chmod is denied by administrator. */

#define REPLY_CHMODDENIED	"SITE CHMOD access denied."

/* this is used when the access list is requested by the user. It is the
   first line of a multi-line reply. The parameter is the username the 
   access list is being displayed for */

#define REPLY_ACCESSFIRST(uname)	"211-Access lists for user %s:", uname

/* this is the second line of the access list reply. It requires %s at
   the beginning of the line and the first parameter to map to it */

#define REPLY_ACCESSSECOND(format)	"%s***Path/Filename***                                          ***Access***", format

/* this is the final line of the access list reply. */

#define REPLY_ACCESSEND		"End of access list."

/* this is the STAT reply. The parameters should be self explanitary. Well 
   maybe not, but it makes it flexible. */

#define REPLY_STAT1(pus)	"211-Running "PROGNAME" ("VERSTR") on host '%s'", pus->vserver->vhostname
#define REPLY_STAT2(pus)	"%sUser currently logged in as '%s'", replystr, pus->username
#define REPLY_STAT3(pus)	"%sCurrent Directory: %s", replystr, pus
#define REPLY_STAT4(pus)	"%sFile transfer mode: %s", replystr, (pus->binary)?"IMAGE":"ASCII"
#define REPLY_STAT5(pus)	"%sRestart position: %s", replystr, offt_tostr(pus->restartpos)
#define REPLY_STAT6(pus)	"%sUmask of new files and dirs: %04o", replystr, pus->umask
#define REPLY_STAT7(pus)	"%sTimeout: %d seconds", replystr, pus->timeout
#define REPLY_STAT8(pus)	"%sYour host: %s", replystr, pus->hostname

/* this is the STAT replies if a file is being downloaded. */

#define REPLY_STAT9		"%sData Connection in progress: ", replystr

/* this is displayed if a data connection is waiting on completion */

#define REPLY_STAT10		"%s Connection is not yet completed.", replystr

/* this is displayed if the data port is transmitting data, but the total
   amount to be transfered is unknown */
   
#define REPLY_STAT11(pus)	"%s Data Transferred: %s", replystr, offt_tostr(pus->dport->transbytes)

/* this is displayed if the data port is transmitting data, and the total
   amount is known */
   
#define REPLY_STAT12(pus)	"%s Data Transferred: %s of %s", replystr, offt_tostr(pus->dport->transbytes), offt_tostr(pus->dport->tsize)

/* this is displayed at the beginning of a file listing style stat. The
   parameter is the directory asked for. It is part of a multi-line reply */

#define REPLY_STATLIST(cmd)	"211-Status of %s:", cmd

/* this is displayed when STAT finishes for both regular and file listing 
   STAT's */

#define REPLY_STATEND		"End of status."

/* this is displayed for ratios in the STAT command. First parameter must 
   stay at the front for each of these, and must be first in the parameter
   list. */
   
#define REPLY_RATIOBYTECREDITS(format, creds)		"%sDownload credits: %lld bytes", format, creds
#define REPLY_RATIOBYTERATIO(format, upp, downn)	"%sUpload %d bytes to receive %d bytes of download credits", format, upp, downn
#define REPLY_RATIOFILECREDITS(format, creds)		"%sFile credits: %d files", format, creds
#define REPLY_RATIOFILERATIO(format, upp, downn)	"%sUpload %d files to receive %d files of download credits", format, upp, downn

/* This is displayed with "EPSV ALL" is received, and a different port
   command is sent. This stops NAT breaking */
  
#define REPLY_EPSVSET		"Only EPSV connections can be established."

/* This is displayed when the user does EPSV ALL */

#define REPLY_EPSVON		"Set for EPSV connections only."

/* This is displayed if the user asks for an unsupported protocol */

#define REPLY_BADPROTO		"Unsupported protocol, Must use IPV4. (1)"

/* This is displayed if the user sends a bad epsv command */

#define REPLY_EPSVERR		"EPSV parameter incorrect."

/* This returns the EPSV result */

#define REPLY_EPSV(p1)		"Extended passive mode on (|||%d|)", p1

/* this is used for bad Port parameters */

#define REPLY_EPRTBADPARM	"Invalid parameters for EPRT command."

/* this is used when the EPRT command is used but a client told muddleftpd to
   connect to it on a privlidged port. */
   
#define REPLY_EPRTBADPORT	"EPRT must specify port more than 1024."

#define REPLY_EPRTBADFXP	"EPRT must specify IP same as control IP."

/* this is used when the EPRT command succeeds. The 4 parameters are integer
   parts of the IP address. 5th is the remote port to connect to */
   
#define REPLY_EPRTOK(ipa,ipb,ipc,ipd,portnum)	"EPRT command successful. Data port is %d.%d.%d.%d port %d.", ipa, ipb, ipc, ipd, portnum

/* this is used when the server cannot add any more users */

#define REPLY_SERVERBUSY	"421 Server too busy, logging out.\r\n"

/* this is used when virutal servers on a single IP are not being used */

#define REPLY_NOHOSTS		"HOST not implemented."

/* this is used if a user trys to select a new host */

#define REPLY_HOSTSELECTED	"Virtual host already selected."

/* this is used if a virtual host is not found */

#define REPLY_HOSTNOTFOUND(name)	"Virtual host '%s' not found.", name

/* this is used if a virtual host is misconfigured, does not exist */

#define REPLY_HOSTMISCONF(name)		"Virtual host '%s' misconfigured.", name

/* this is used if a virtual host is too busy */

#define REPLY_HOSTTOOBUSY(name)		"Virtual host '%s' too busy.", name

/* this is used when the virtual server is selected */

#define REPLY_HOSTSEL(name)		"\x22%s\x22 is the selected server.", name
