/*******************************************************************************
        ftp_server.c
        Z-World, 2000

        Demonstration of a simple FTP server, using the ftp library.
        The user "anonymous" may download the file "rabbitA.gif", but
        not "rabbitF.gif".  The user "foo" (with password "bar") may
        download "rabbitF.gif", and also "rabbitA.gif", since files owned
        by the anonymous user are world-readable.

        Each user may execute the "dir" or "ls" command to see a listing of
        the available files.  The listing shows only the files that the
        logged-in user can access.
*******************************************************************************/

/***********************************
 * Configuration                   *
 * -------------                   *
 * All fields in this section must *
 * be altered to match your local  *
 * network settings.               *
 ***********************************/
/*
 * You must change the following values to whatever
 * your local IP address, netmask, and gateway
 * are. Contact your network administrator
 * for these numbers.
 */
#define MY_IP_ADDRESS   "10.10.6.100"
#define MY_NETMASK      "255.255.255.0"
#define MY_GATEWAY		"10.10.6.1"

/*
 * FTP configuration
 *
 * See the sspec_* and sauth_* functions below to see how to set up
 * files and users for the FTP server.
 */

/********************************
 * End of configuration section *
 ********************************/

#memmap xmem
#use "dcrtcp.lib"
#use "ftp_server.lib"

#ximport "samples/tcpip/http/pages/rabbit1.gif" rabbit1_gif

xstring xtext { "Welcome to the Rabbit FTP server.  Download a file.\n" };

/* -------------------------------------------------------------------- */

/**
 * 	Compute the string length of a string in memory.  Examines the string
 * 	in small chunks.
 * 	RETURN: 	count of characters in string.
 */
int
xmem_strlen( faraddr_t xstr )
{
	auto char 	buff[63+1];
	auto int 	result;   		// Length of string.
	auto int 	s1;

	buff[sizeof(buff)-1] = '\0';
	result = 0;
	do {
		xmem2root( buff, xstr, sizeof(buff)-1 );
		s1 = strlen( buff );
		result += s1;
		xstr += sizeof(buff)-1;
	} while( s1 == sizeof(buff)-1 );

	return( result );
}   /* end xmem_strlen() */

void main()
{
	int file;
	int user;
	faraddr_t  xdest;
	faraddr_t  xsrc;
	long   len;   		// Used for storing 4 byte size into XMEM.

	// Set up the first file and user
	file = sspec_addxmemfile("rabbitA.gif", rabbit1_gif, SERVER_FTP);
	user = sauth_adduser("anonymous", "", SERVER_FTP);
	ftp_set_anonymous(user);
	sspec_setuser(file, user);
	sspec_setuser(sspec_addxmemfile("test1", rabbit1_gif, SERVER_FTP), user);
	sspec_setuser(sspec_addxmemfile("test2", rabbit1_gif, SERVER_FTP), user);

	/*
	 *  Copy the string from one place in XMEMORY to another.  The "xstring"
	 *  directive does NOT store the size.  To use sspec_addxmemfile(), this
	 *  is required.  Thus the copy which prepends a four-byte size value
	 *  (not including NUL char).  The final xmem2mem() copies the string
	 *  just after the size.
	 */
	xmem2root( & xsrc, xtext+0, 4 );
	len = xmem_strlen( xsrc );
	xdest = xalloc( len+4 );
	root2xmem( xdest, & len, 4 );
	xmem2xmem( xdest+4, xsrc, (int)len );	

	sspec_setuser( sspec_addxmemfile( "README", xdest, SERVER_FTP ), user );

	// Set up the second file and user
	file = sspec_addxmemfile("rabbitF.gif", rabbit1_gif, SERVER_FTP);
	user = sauth_adduser("foo", "bar", SERVER_FTP);
	sspec_setuser(file, user);
	sspec_setuser(sspec_addxmemfile("test3", rabbit1_gif, SERVER_FTP), user);
	sspec_setuser(sspec_addxmemfile("test4", rabbit1_gif, SERVER_FTP), user);
	
	sock_init();
	ftp_init(NULL); /* use default handlers */

	tcp_reserveport(FTP_CMDPORT);	// Port 21
	
	while(1) {
		ftp_tick();
	}
}
