At line 1 changed 195 lines |
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 FILE. Save your changes, and close the user manager. Now go find the users folder, your server group, then your user, then the VFS folder, and finally the name of the VFS item you just saved. Edit it with a text editor, and set the URL to be: |
|
CUSTOM_com.myprotocol.MyProtocol://any_data_you_want_on_the_url:port/ |
|
Now you are ready to login. This class must be on the class path for CrushFTP for it to work. |
|
(Example: java -classpath plugins/lib CrushFTP) |
|
Any Exceptions must be returned and not thrown. If they are thrown, the info is lost since its a reflection call to the function in this class. |
|
{{{ |
package com.myprotocol; |
|
import crushftp.handlers.*; |
import java.util.*; |
import java.io.*; |
import java.text.*; |
import crushftp.server.*; |
|
public class MyProtocol |
{ |
VFS uVFS = null; |
VRL url = null; |
Properties vItem = null; |
|
public MyProtocol(VFS uVFS, String urlStr, Properties vItem) |
{ |
this.uVFS = uVFS; |
this.url = new VRL(urlStr); |
this.vItem = vItem; |
} |
|
public Object get_item(String path) |
{ |
try |
{ |
if (path.endsWith("/")) path = path.substring(0,path.length()-1); |
File f = new File(url.getPath()+path); |
if (!f.exists()) return null; |
Properties dir_item = new Properties(); |
dir_item.put("url",url+path+(f.isDirectory()?"/":"")); |
dir_item.put("local","false"); |
dir_item.put("protocol", "file"); |
dir_item.put("type", f.isFile()?"FILE":"DIR"); |
dir_item.put("permissions", (f.isFile()?"-":"d")+"rwxrwxrwx"); |
dir_item.put("num_items", "0"); |
dir_item.put("owner", "owner"); |
dir_item.put("group", "group"); |
dir_item.put("size", f.length()+""); |
dir_item.put("month", "1"); |
dir_item.put("day", "1"); |
dir_item.put("time_or_year", "12:00"); |
dir_item.put("name", f.getName()); |
dir_item.put("local", "true"); |
dir_item.put("root_dir", path); |
return dir_item; |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
public Object getListing(Vector list, String path) |
{ |
try |
{ |
if (path.startsWith("/")) path = path.substring(1); |
Common.debug(0,"ls "+url+path); |
File fs[] = new File(url.getPath()+path).listFiles(); |
if (fs != null) |
{ |
for (int x=0; x<fs.length; x++) |
{ |
File f = fs[x]; |
Properties p = get_item(path+"/"+f.getName()); |
list.addElement(p); |
} |
} |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
public Object getInputStream(Long seekPos, Properties item) |
{ |
try |
{ |
Common.debug(0,"get "+item.getProperty("url")); |
VRL u = new VRL(item.getProperty("url")); |
if (!new File(u.getPath()).exists()) return new Exception("Does not exist"); |
InputStream inStream = new FileInputStream(u.getPath()); |
inStream.skip(seekPos.longValue()); |
return inStream; |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
public Object getOutputStream(Long seekPos, final Properties item) |
{ |
try |
{ |
Common.debug(0,"put "+item.getProperty("url")); |
VRL u = new VRL(item.getProperty("url")); |
RandomAccessFile raf = new RandomAccessFile(u.getPath(),"rw"); |
if (raf.length() > seekPos.longValue()) raf.setLength(seekPos.longValue()); |
raf.close(); |
OutputStream outStream = new FileOutputStream(u.getPath(),true); |
return outStream; |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
public Object doCommand(String command, Properties item) |
{ |
try |
{ |
Common.debug(0,command +" "+item.getProperty("url")); |
VRL u = new VRL(item.getProperty("url")); |
String s = ""; |
try |
{ |
if (command.toUpperCase().startsWith("DELE")) |
{ |
new File(u.getPath()).delete(); |
s = "250 OK"; |
} |
else if (command.toUpperCase().startsWith("RMD")) |
{ |
new File(u.getPath()).delete(); |
s = "250 OK"; |
} |
else if (command.toUpperCase().startsWith("MKD")) |
{ |
new File(u.getPath()).mkdirs(); |
s = "257 OK"; |
} |
else if (command.toUpperCase().startsWith("MDTM")) |
{ |
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); |
if (new File(u.getPath()).exists()) s = "213 " + sdf.format(new Date(new File(u.getPath()).lastModified())); |
else throw new Exception("File does not exist."); |
} |
else if (command.toUpperCase().startsWith("SIZE")) |
{ |
if (new File(u.getPath()).exists()) |
{ |
if (new File(u.getPath()).isDirectory() && new File(u.getPath()).listFiles() != null) s = "213 "+new File(u.getPath()).listFiles().length; |
else s = "213 "+new File(u.getPath()).length(); |
} |
else return new Exception("File does not exist."); |
} |
else s = "200 Ignoring command."; |
} |
catch(Exception e) |
{ |
Common.debug(1, e); |
s = "550 "+e.toString(); |
} |
return s; |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
public Object rename(Properties item1, Properties item2) |
{ |
try |
{ |
Common.debug(0,"rename "+item1.getProperty("url") + " to " + item2.getProperty("url")); |
VRL u1 = new VRL(item1.getProperty("url")); |
VRL u2 = new VRL(item2.getProperty("url")); |
return new Boolean(new File(u1.getPath()).renameTo(new File(u2.getPath()))); |
} |
catch(Exception e) |
{ |
return e; |
} |
} |
|
} |
|
}}} |
A custom VFS can be created too. Contact me for details if you're a java programmer wanting to implement your own VFS. This might be a VFS based on database records, or other things. |