Example source code for a custom protocol handler for the virtual file system.

In the user manager, make a new VFS item.  Set its protocol to be CUSTOM, and use a URL like this:

CUSTOM_com.myprotocol.VFS_MyProtocol://any_data_you_want_on_the_url/

{{{
package com.myprotocol;

import crushftp.handlers.*;
import java.util.*;
import java.io.*;
import java.text.*;
import crushftp.server.*;

public class VFS_MyProtocol
{
	VFS uVFS = null;
	VRL url = null;
	Properties vItem = null;
	
	public VFS_MyProtocol(VFS uVFS, String urlStr, Properties vItem)
	{
		this.uVFS = uVFS;
		this.url = new VRL(urlStr);
		this.vItem = vItem;
	}

	public Properties get_item(String path) throws Exception
	{
		if (path.endsWith("/")) path = path.substring(0,path.length()-1);
		Properties dir_item = new Properties();
		dir_item.put("url",url+path);
		dir_item.put("local","false");
		dir_item.put("protocol", "ftp");
		dir_item.put("type", "FILE");
		dir_item.put("permissions", "drwxrwxrwx");
		dir_item.put("num_items", "0");
		dir_item.put("owner", "owner");
		dir_item.put("group", "group");
		dir_item.put("size", "0");
		dir_item.put("month", "1");
		dir_item.put("day", "1");
		dir_item.put("time_or_year", "12:00");
		dir_item.put("name", "test");
		dir_item.put("local", "false");
		dir_item.put("dir", path);
		return dir_item;
	}

	public void getListing(Vector list, String path) throws Exception
	{
		if (path.startsWith("/")) path = path.substring(1);
		Common.debug(2,"ls "+url+path);
	}

	public InputStream getInputStream(Long seekPos, Properties item) throws Exception
	{
		Common.debug(2,"get "+item.getProperty("url"));

		InputStream inStream = null;
		long skipped = 0;
		long amt = seekPos - skipped;
		while(skipped < seekPos)
		{
			long l = inStream.skip(amt);
			if (l > 0) skipped += l;
			else break;
			amt = seekPos - skipped;
		}

		return inStream;
	}

	public OutputStream getOutputStream(Long seekPos, final Properties item) throws Exception
	{
		Common.debug(2,"put "+item.getProperty("url"));

		OutputStream outStream = null;
		
		return outStream;
	}

	public String doCommand(String command, Properties item) throws Exception
	{
		Common.debug(2,command +" "+item.getProperty("url"));
		String s = "";
		try
		{
			if (command.toUpperCase().startsWith("DELE"))
			{
				s = "250 OK";
			}
			else if (command.toUpperCase().startsWith("RMD"))
			{
				s = "250 OK";
			}
			else if (command.toUpperCase().startsWith("MKD"))
			{
				s = "257 OK";
			}
			else if (command.toUpperCase().startsWith("MDTM"))
			{
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
				s = "213 " + sdf.format(new Date());
			}
			else if (command.toUpperCase().startsWith("SIZE"))
			{
				s = "213 0";
			}
			else s = "200 Ignoring command.";
		}
		catch(Exception e)
		{
			Common.debug(1, e);
			s = "550 "+e.toString();
		}
		return s;
	}

	public Boolean rename(Properties item1, Properties item2) throws Exception
	{
		Common.debug(2,"rename "+item1.getProperty("url") + "   to   " + item2.getProperty("url"));
		return new Boolean(false);
	}

}
}}}