----
Here is the source code to the HomeDirectory plugin.  Someone may find this useful in developing their own plugins.  Same rules on how to make the package structure. ([Third Party])
----
Start.java
----

%%prettify 
{{{
package HomeDirectory;

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

public class Start implements Serializable
{
	Properties settings = new Properties();
	String version = "4.3.5";
	GUI g = null;
	Common common_code = new Common();

	public Properties getDefaults()
	{
		Properties p = new Properties();
		p.put("enabled","false");
		p.put("debug","false");
		p.put("path","");
		p.put("always_generate","false");
		p.put("uniqueFolder","false");
		p.put("uniqueFolderFormat","_MM.dd.yyyy");
		p.put("templateUser","");
		p.put("permissions","(read)(write)(view)(delete)(resume)(rename)(makedir)(deletedir)");
		p.put("username_filter","*");
		p.put("server_item","All");
		p.put("version",version);
		return p;
	}

	public void setSettings(Properties p) throws Exception
	{
		settings = p;

		if (g != null) g.setSettings(settings);
	}

	public Properties getSettings()
	{
		if (g != null) settings = g.getSettings();
		settings.put("version",version);
		return settings;
	}

	public javax.swing.JPanel getPrefsPanel()
	{
		if (g == null) g = new GUI();
		g.setParent(this);
		g.setSettings(settings);
		return g;
	}

	public Object run(Properties info)
	{
		if (!settings.getProperty("enabled").equalsIgnoreCase("true")) return null;

		Properties server_item = (Properties)info.get("server_item");
		if (info.getProperty("action","").equals("afterLogin") && (get("server_item").trim().equalsIgnoreCase("All") || get("server_item").trim().length() == 0 || (server_item.getProperty("ip","")+"_"+server_item.getProperty("port","")).equals(get("server_item").trim())))
		{
			generateHomeDir(info);
		}
		return null;
	}

	public void generateHomeDir(Properties info)
	{
		boolean found_user = false;
		Properties user = (Properties)info.get("user");
		String username = info.getProperty("username");
		if (username.equalsIgnoreCase("") || username.equalsIgnoreCase("anonymous") || username.equalsIgnoreCase("webstatistics") || username.equalsIgnoreCase("crush4admincontroller")) return;
		if (!Common.do_search(get("username_filter"),username,false,0)) return;
		try
		{
			VFS uVFS = (VFS)info.get("uVFSObject");
			Vector listing = new Vector();
			uVFS.getListing(listing,"/");
			String path = settings.getProperty("path","");
			if (!path.endsWith("/")) path += "/";
			String uniqueAddon = "";
			try{if (settings.getProperty("uniqueFolder","").equals("true")) uniqueAddon = new SimpleDateFormat(settings.getProperty("uniqueFolderFormat")).format(new java.util.Date());}catch(Exception e){msg(e);}

			msg("listing : " + listing.toString());
			if (get("always_generate").equals("true") || listing.size() == 0 || (!uniqueAddon.equals("") && new File(path+username+uniqueAddon).exists()))//empty dir, or this user was one we created previously
			{
				new File(path+username+uniqueAddon).mkdirs();

				Vector VFSItems = new Vector();
				Properties permissions = new Properties();
				//we also generate a cache of what the permissions are for the file system instead of loading from a file
				String uVFS_home = uVFS.getHome();
				String localPath = path+username+uniqueAddon;
				if (new File(uVFS_home+"/../VFS.XML").exists() && get("always_generate").equals("true"))
				{
					permissions = (Properties)Common.readXMLObject(uVFS_home+"/../VFS.XML");
				}

				if (permissions == null) permissions = new Properties();

				String buildPrivs = settings.getProperty("permissions","");
				permissions.put("/"+new File(localPath).getName().toUpperCase()+"/",buildPrivs);
				Properties dir_item = new Properties();
				dir_item.put("url",new File(localPath).toURI().toURL().toExternalForm());
				dir_item.put("type","dir");
				Vector v = new Vector();
				v.addElement(dir_item);
				Properties p = new Properties();
				p.put("dir","/");
				p.put("name",new File(localPath).getName());
				p.put("data",v);
				VFSItems.addElement(p);

				if (!get("always_generate").equals("true"))
				{
					Common.recurseDelete(uVFS_home+"/VFS/",false);
				}
				for (int x=0; x<VFSItems.size(); x++)
				{
					Properties pp = (Properties)VFSItems.elementAt(x);
					new File(uVFS_home+pp.getProperty("dir")).mkdirs();
					common_code.writeXMLObject(uVFS_home+pp.getProperty("dir")+pp.getProperty("name"),pp.get("data"),"VFS");
				}
				common_code.writeXMLObject(uVFS_home+"/../VFS.XML",permissions,"VFS");
				msg("setting home directory and permissions : " + buildPrivs);
				uVFS.reset();
				uVFS.setHome(uVFS_home);
				found_user = true;
			}
		}
		catch(Exception e)
		{
			msg(e);
		}


		if (found_user)
		{
			info.put("action","success");
		}
		else
		{
			info.put("action","failed");
		}
	}

	public void testSettings()
	{
		String error = "OK";
		try
		{
		}
		catch(Exception e)
		{
			error = e.toString();
		}
		JOptionPane.showMessageDialog(null, error, "Alert",JOptionPane.ERROR_MESSAGE);
	}

	public String get(String key)
	{
		return settings.getProperty(key,"");
	}

	public void msg(String s)
	{
		if (settings.getProperty("debug").equals("true")) crushftp.handlers.Common.debug(0,"HomeDirectory:"+s);
	}

	public void msg(Exception e)
	{
		if (settings.getProperty("debug").equals("true")) crushftp.handlers.Common.debug(0,e);
	}

}

}}}
/%

----
GUI.java
----

%%prettify 
{{{
package HomeDirectory;

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;
import java.util.*;
import java.lang.reflect.*;
import java.io.*;

public class GUI extends JPanel
{
	private JLabel jLabel1 = new JLabel();
	private JTextField path_field = new JTextField();

	public GUI()
	{
		try
		{
			jbInit();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	Object parent = null;
	private JPanel jPanel1 = new JPanel();
	private JCheckBox enabled_cb = new JCheckBox();
	private JCheckBox debug_cb = new JCheckBox();
    private JLabel jLabel10 = new JLabel();
	private JComboBox server_item_combo = new JComboBox();
    private JButton browse_button = new JButton();
    private JScrollPane jScrollPane1 = new JScrollPane();
    private JTextField permissions_field = new JTextField();
    private JLabel jLabel7 = new JLabel();
    private JCheckBox uniqueFolder_cb = new JCheckBox();
    private JTextField uniqueFolderFormat_field = new JTextField();
    private JCheckBox always_generate_cb = new JCheckBox();
    private JLabel jLabel8 = new JLabel();
    private JTextField username_filter = new JTextField();
    private JLabel jLabel2 = new JLabel();
	public void setParent(Object parent)
	{
		this.parent = parent;
	}

	void jbInit() throws Exception
	{
		jLabel1.setFont(new java.awt.Font("Arial", 0, 12));
		jLabel1.setText("Path:");
		jLabel1.setBounds(new Rectangle(15, 16, 37, 29));
		this.setLayout(null);
		path_field.setBounds(new Rectangle(76, 18, 382, 22));
		jPanel1.setBorder(BorderFactory.createEtchedBorder());
		jPanel1.setBounds(new Rectangle(3, 38, 583, 334));
		jPanel1.setLayout(null);
		enabled_cb.setFont(new java.awt.Font("Arial", 0, 12));
        enabled_cb.setText("Enabled");
		enabled_cb.setBounds(new Rectangle(6, 6, 100, 22));
		debug_cb.setBounds(new Rectangle(122, 6, 100, 22));
	debug_cb.setFont(new java.awt.Font("Arial", 0, 12));
        debug_cb.setText("Debug");
        jLabel10.setFont(new java.awt.Font("Arial", 0, 12));
        jLabel10.setText("<html> <b>HomeDirectory Plugin Help</b><br> Simple plugin that just " +
    "generates the users home directory when they first login.<br> This " +
    "way you could use say the SQL plugin and setup a user.  When they " +
    "actually<br> login, a new folder could be created for them to upload " +
    "into.<br> <br> <b>How to use:</b><br> Set a location where users home " +
    "folders will be created at.  Use the browse button to pick<br> the " +
    "location.<br> <br> Specify the permission they will have in that " +
    "folder.  In general you will give them full<br> permissions here " +
    "as this folder is probably empty.  This way they can then login, " +
    "and upload<br> files to it.  If the folder doesn\'t exist, it will " +
    "be created for them.<br> <br> To test, create a new user via the " +
    "user manager.  Don\'t setup any directory<br> items in the \"user\'s " +
    "stuff (VFS)\" pane.  Then login with that user and look for<br> the " +
    "new folder that just got created.<br>"+
	"For the time/date format on a unique folder, search google for 'SimpleDateFormat'.<br>" +
	"<br> Questions?  Email me: " +
    "ben@crushftp.com<br> <br> --Ben Spink<br> </html> ");
        browse_button.setBounds(new Rectangle(462, 10, 107, 31));
        browse_button.setText("Browse...");
        browse_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                browse_button_actionPerformed(e);
            }
        });
        jScrollPane1.setBounds(new Rectangle(15, 173, 557, 142));
		server_item_combo.setToolTipText("Allows you to specify the individual server that can use this plugin " +
	    "instance.");
	        server_item_combo.setBounds(new Rectangle(390, 133, 183, 27));
        permissions_field.setText("(read)(write)(view)(delete)(resume)(rename)(makedir)(deletedir)");
        permissions_field.setBounds(new Rectangle(147, 55, 412, 22));
        jLabel7.setFont(new java.awt.Font("Arial", 0, 12));
        jLabel7.setText("Directory permissions:");
        jLabel7.setBounds(new Rectangle(16, 51, 131, 29));
		uniqueFolder_cb.setText("Use Unique Time Stamped Folder? (ex. johndoe_01.01.2007)");
        uniqueFolder_cb.setFont(new java.awt.Font("Arial", 0, 12));
        uniqueFolder_cb.setOpaque(false);
        uniqueFolder_cb.setBounds(new Rectangle(17, 84, 379, 22));
        uniqueFolderFormat_field.setBounds(new Rectangle(402, 84, 140, 22));
        uniqueFolderFormat_field.setToolTipText("Java SimpleDateFormat - search google for the format.");
        uniqueFolderFormat_field.setText("MM.dd.yyyy");
        always_generate_cb.setBounds(new Rectangle(17, 135, 213, 22));
        always_generate_cb.setFont(new java.awt.Font("Arial", 0, 12));
        always_generate_cb.setText("Always Generate Home Folder");
        jLabel8.setBounds(new Rectangle(325, 132, 67, 29));
        jLabel8.setText("Server:");
        jLabel8.setFont(new java.awt.Font("Arial", 0, 12));
        username_filter.setBounds(new Rectangle(157, 109, 120, 22));
        jLabel2.setBounds(new Rectangle(17, 106, 142, 29));
        jLabel2.setText("Username matching :");
        jLabel2.setFont(new java.awt.Font("Arial", 0, 12));
        this.add(jPanel1, null);
        jPanel1.add(jLabel1, null);
        jPanel1.add(path_field, null);
        jPanel1.add(browse_button, null);
		this.add(enabled_cb, null);
		this.add(debug_cb, null);
        jPanel1.add(jScrollPane1, null);
        jPanel1.add(permissions_field, null);
        jPanel1.add(jLabel7, null);
        jPanel1.add(uniqueFolder_cb, null);
        jPanel1.add(always_generate_cb, null);
        jPanel1.add(server_item_combo, null);
        jPanel1.add(jLabel8, null);
        jPanel1.add(uniqueFolderFormat_field, null);
        jPanel1.add(jLabel2, null);
        jPanel1.add(username_filter, null);
        jScrollPane1.getViewport().add(jLabel10, null);
		buildServerList();
	}

	public Properties getSettings()
	{
		Properties p = new Properties();
		p.put("enabled",enabled_cb.isSelected()+"");
		p.put("debug",debug_cb.isSelected()+"");
		p.put("path",path_field.getText());
		p.put("permissions",permissions_field.getText());
		p.put("username_filter",username_filter.getText());
		p.put("always_generate",always_generate_cb.isSelected()+"");
		p.put("uniqueFolder",uniqueFolder_cb.isSelected()+"");
		p.put("uniqueFolderFormat",uniqueFolderFormat_field.getText());
		p.put("server_item",server_item_combo.getSelectedItem());
		return p;
	}

	public void setSettings(Properties p)
	{
		  enabled_cb.setSelected(p.getProperty("enabled").equalsIgnoreCase("true"));
		  debug_cb.setSelected(p.getProperty("debug").equalsIgnoreCase("true"));
		  path_field.setText(p.getProperty("path"));
		  permissions_field.setText(p.getProperty("permissions"));
		  username_filter.setText(p.getProperty("username_filter"));
		  always_generate_cb.setSelected(p.getProperty("always_generate").equalsIgnoreCase("true"));
		  uniqueFolder_cb.setSelected(p.getProperty("uniqueFolder").equalsIgnoreCase("true"));
		  uniqueFolderFormat_field.setText(p.getProperty("uniqueFolderFormat"));
		  server_item_combo.setSelectedItem(p.getProperty("server_item"));
	}

	public void buildServerList()
	{
		server_item_combo.removeAllItems();
		server_item_combo.addItem("All");
		try
		{
			Vector the_server_list = (Vector)crushftp.server.ServerStatus.server_settings.get("server_list");
			for (int x=0; x<the_server_list.size(); x++)
			{
				Properties server_item = (Properties)((Properties)the_server_list.elementAt(x)).clone();
				server_item_combo.addItem(server_item.getProperty("ip","lookup")+"_"+server_item.getProperty("port","21"));
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	void test_btn_actionPerformed(ActionEvent e)
	{
		Properties p = getSettings();
		try
		{
			Method setSettings = parent.getClass().getMethod("setSettings",new Class[] { new Properties().getClass() });
			setSettings.invoke(parent,new Object[]{p});
			Method testSettings = parent.getClass().getMethod("testSettings",null);
			testSettings.invoke(parent,null);
		}
		catch(Exception ee)
		{
		}
	}

    void browse_button_actionPerformed(ActionEvent e)
	{
		JFileChooser d = new JFileChooser();
		d.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		d.setCurrentDirectory(new File("/"));
		d.setApproveButtonText("Pick");
		d.setFileFilter(null);
		int res = d.showOpenDialog(this);
		String the_dir = "";
		if(res == JFileChooser.APPROVE_OPTION)
		{
			File f = d.getSelectedFile();
			the_dir = f.toString().replace('\\','/')+"/";
		}
		else return;
		path_field.setText(the_dir);
    }

}
}}}
/%