FTP sharing tricks

The following shows you how to run a script of your choice whenever a new file is uploaded.

  1. Enable detailed FTP logging. Edit the file /System/Library/LaunchDaemons/ftp.plist, and add another ‘-l‘ option to the FTP daemon (yes, there will be two):

    ...
    <key>ProgramArguments</key>
    <array>
    <string>ftpd</string>
    <string>-l</string>
    <string>-l</string>
    <string>-n</string>
    </array>
    ...

  2. Start FTP sharing. Open ‘System Preferences‘, click on ‘Sharing‘, then select ‘File Sharing‘ from the list. Check the ‘on‘ option, then click the ‘Options…‘ button and check ‘Share files and folders using ftp‘.
  3. At this point you should be able to open a FTP session, upload a file, and have everything logged. Have a look in /var/log/ftp.log and make sure everything is logged. You should see something like:

    ...
    Jan 5 06:27:49 gandalf ftpd[23214]: ANONYMOUS FTP LOGIN FROM ::1, blah (class: guest, type: GUEST)
    Jan 5 06:27:54 gandalf ftpd[23214]: put /test.txt = 6 bytes in 0.007 seconds
    Jan 5 06:27:56 gandalf ftpd[23214]: Data traffic: 6 bytes in 1 file
    Jan 5 06:27:56 gandalf ftpd[23214]: Total traffic: 743 bytes in 1 transfer
    ...

  4. Now, let’s write a little bash script that will read the FTPD log, and will act when a new upload arrives. Save the following as a run_on_upload.sh, and customize with your own code:

    #!/bin/bash
    tail -n 0 -f /var/log/ftp.log |
    grep --line-buffered --only-matching "put /.*=" |
    while read put file delimiter; do
        # do something useful
        echo ${file:1}
    done
  5. Run the script, upload something, and see that it works… 🙂
FTP sharing tricks

Folder Actions, UNIX style

Mac OS X has a nice feature called Folder Actions. Basically, this feature lets you attach an AppleScript script to a folder, and have that script run whenever items are added or removed from the folder. Have a look here for a simple example.

How would you write that script in bash? here’s my simple, general-purpose solution.

There are three parts in this solution:

When you attach the Send Events To Shell Script.scpt script to a folder, it will act as an observer and forward the Opening, Closing, Adding and Removing events to the bash script /usr/local/bin/FolderActionsDispatcher.sh. The event payload includes the type of the event, the data needed to perform its purpose (i.e., for the Adding event, the list of the added items), as well as the name of the folder that was the target of the event. FolderActionsDispatcher.sh will parse the event, and then will try to invoke a callback script named .FolderActions.sh in the target folder. All you have to do is write the .FolderActions.sh bash script and place it in the folder it belongs to.

Here’s an example. Let’s say that we want to copy every file placed in ~/Downloads to /private/tmp, and do it automatically. Here’s what we will do:

  1. One time setup. Download the program, unarchive and copy Send Events To Shell Script.scpt to ~/Library/Scripts/Folder Action Scripts, Copy FolderActionsDispatcher.sh to /usr/local/bin, and make it world executable, like so:$ chmod a+x /usr/local/bin/FolderActionsDispatcher.sh.
  2. Create the file ~/Downloads/.FolderActions.sh. The file FolderActions.template is a good starting point. Make the new file user executable, like so:$ chmod u+x ~/Downloads/.FolderActions.sh.

    Edit ~/Downloads/.FolderActions.sh and add the desired code in the item_added_to_folder() function. This callback function will be called by the /usr/local/bin/FolderActionsDispatcher.sh dispatcher script, every time an item (either a file or a folder) is added to the ~/Downloads directory.

    ...
    function item_added_to_folder() {
    FOLDER=$1
    ITEM=$2
    # this is what we will do
    cp ${FOLDER}/${ITEM} /private/tmp
    }
    ...

  3. Save the modified script.
  4. Enable Folder Actions
 for ~/Downloads. In the Finder application, select the ~/Downloads folder, bring up the context menu, and select ‘Folder Actions Setup…‘ 

From the dialog, select the ‘Send Events To Shell Script.scpt‘ action, and click the ‘Attach‘ button.

That’s it 🙂 To test it, place a file in ~/Downloads and see that it gets copied to /private/tmp.

Download a zip with all the files.

Folder Actions, UNIX style