Don’t Send iCal Replies

I came across a great hint in Mac OS X Hints today. It seems that there’s an easy way to interrupt the process of sending an email reply when accepting iCal invites. As I tend to play around with iCal invites a lot (adding and deleting the same event ad nauseum) — I love this.
I wrote up a modified script like in the example and bundled it with a shell script, to install and uninstall the modification. You have to run this shell script using sudo from the CLI (Command Line Interface aka
The zip file contains the shell script, the modified Mail.scpt AppleScript, and the original Mail.scpt AppleScript.
To install run sudo /path/to/ install
To uninstall run sudo /path/to/ revert
To check usage and status, run /path/to/
If you don’t like messing with the CLI then there’s a great little shareware app, iCal Reply Checker that does it all, and more.
It seems that neither method interferes with the code signing of iCal as the script in question is not code signed.
It appears that if you’re using an Exchange account in that this script is being bypassed and this hint won’t work for you. 🙁

Fail2ban on Leopard Server

So here I am running my own server — for almost 2 years now. It’s been a real learning experience and I’ve tried to share. My latest add-on has been fail2ban. I got tired of looking into my logs and seeing where script kiddies or bots were trying to take control of my server. Fortunately, none have.
After a bit of googling, I found fail2ban. It’s a collection of python scripts.

Fail2ban scans log files like /var/log/pwdfail or /var/log/apache/error_log and bans IP that makes too many password failures. It updates firewall rules to reject the IP address.

There are a few tricks I’ve discovered along the way to make it work on my installation and likely on Mac OS X Server in general.
First is that fail2ban creates a PID and socket file in a directory that it fails to create. Yeah, that’s a bug. Since I didn’t want to mess around with the actual scripts in the program, I created a plist that issues the mkdir /var/run/fail2ban command. I placed this in /System/Library/LaunchDaemons and set it to Run at Load. Lingon is your friend, but’s now inactive. 🙁
After creating the file you have to use the command line to move it to the /System/Library/LaunchDaemons directory. I also created another launchd plist to reload fail2ban every day. I did this because I run multiple virtual websites and the error logs for those sites get rotated and the names have some time code or something tacked on the end of the filename.
OK, problem 1 solved. Next I discovered that since fail2ban is really running on a multitude of linux boxes all the different methods of IP tracking, sorting etc. were really useless on my OS X Server. I run ipfw firewall and fortunately there’s a module for that in fail2ban. Unfortunately it’s not quite set up correctly, at least it wasn’t for me. I had to tweak it a bit.
What this means is that your action is always going to be ipfw. I tweaked the ipfw.conf file a bit. Now it does the following.

  1. Logs it’s action to ipfw.log
  2. Adds a rulenum to the ipfw command. I did this because some other rule in my setup was allowing the IP before my deny could take effect. By lowering the rulenum my deny now fires off first.
  3. Abstracted the protocol (tcp, udp) to pass as a variable. Just in case something you want to block isn’t tcp.

I also created another filter as I found many times some machine would excessively hit my Apache server looking for nonexistent files. Since it sounds like something a bot would do I decided to ban it. This was the simple creation of a new filter.
I created a jail.local file to hold all my prefs and through trial and error discovered that the examples of how to call for a jail weren’t working for me. Perhaps I just didn’t understand the examples. I soon discovered that parameters for the jail action needed to be passed inside of square brackets in the prefs.
I’m sure, if you’ve gotten this far that you’re either very confused by this whole post or that you’ve had an epiphany. To further the epiphany along I’ve uploaded my file changes.
You should be able to figure out what file goes where from the folder structure of the upload.
A couple of things in summary to remember. First, turn on your server’s firewall. Then make sure you change your server’s local IP address in the files to match your own. That’s the setting for localhost.
Good luck. If you have any questions leave a comment.

VoodooPad Pro Blogging

Please note that VoodooPad Pro has been renamed to VoodooPad.
It’s time to package up all my VoodooPad blogging scripts and assorted web export plugins so that I can

  1. Remember what the heck I was thinking.
  2. Remember what all these pieces were supposed to accomplish as a whole.
  3. Provide some sort of reference to others interested in this stuff.

Concept: To use VoodooPad as a CMS for a web site, allowing for static sites and inclusion of blog-style concatenated page. The blog-style page was originally intended as a News page of a static business site. SEO optimization necessitating the addition of a page with re-newing content. Google likes it more.
Disclaimer: I like Markdown and built these scripts around the fact that the VP document is essentially always formatted in plain text. Images need to be added using links.
I will include a sample package that contains a VP document, a web export plugin and several script plugins. The site the sample is based upon is at.
VoodooPad is a requirement as the meta data and triggers are necessary in the creation of the files. My workflow is as follows.

  1. Create new page/post.
  2. Run script plugin Blog > Meta Markup - HomepageMeta on new page.
  3. Run script plugin Blog > Make Homepage and Feed
  4. Run web export.
  5. FTP files up to site. I use Transmit. It’s also a great app.

The script will move all the created files into a folder structure so that the file structure on the computer will match the web site structure.
VoodooPad document
Item meta data is contained in the HomepageMeta page of the document. This is where most of the personalized info on the site is contained.
In the VP document, tags are used to create a pseudo-folder structure. This means that a page may only have one tag. Some pages are not exported but are used as reference, ie. links in the sidebar or the HomepageMeta page. Pages that are to be rendered at the root level of the site are tagged main.
Triggers can be used to include certain information into specific pages or info on every page. I use this for things like Google Analytics which needs to be on every page or the analytics confirmation that is only on the index.html page.
The Web Export Plugin
Some customization of these files will be necessary for your specific site.

Images are kept in the web export plugin. Files like robots.txt that need to be at the root level are kept in a root folder inside the web export plugin.

  • – creates the actual folder hierarchy, the folders are created in the script. The script also copies files like images to the export folder.

  • – can be used to rename pages that may be PHP based from .html to .php

  • – deletes the extra pages that VoodooPad creates during a web export. No changes to this file are needed.

  • – fixes the relative URLs that occur inside of nested pages. No changes to this file are needed.

  • parseMetaXml.rb – Parses the meta.xml file that VoodooPad creates and uses that infomation to move files into their correct folder structure on the disk and to create a valid sitemap.xml file for use with Google Sitemaps. It also creates and parses the vpDocMeta.xml file for variables.

  • Info.plist – This file was edited to call these scripts during the web export process.

  • vpDocMeta.xml – This file resides inside the root folder of the Web Export Plugin. It is created by the parseMetaXml.rb script. It contains the following data points.

  • root – default value is main. This is the name of the tag of rendered pages that belong at the root level of the folder structure.
  • baseUrl – This is the base URL for the site for creation of the sitemap.xml file.
  • isHomeIndex – default value is false. This is only used if the the page name in VP for the index page of the site is home. This is true if the main page is a blog-style homepage.
  • noIndex – default value is private. This is the name of a directory whose files you don’t want included in sitemap.xml.

Script Plugins
These are placed in the ~/Library/Application Support/VoodooPad/Script PlugIns/ folder. No changes should be required in these scripts. They will be viewable from the Plugin > Blog menu in VoodooPad.

  • meta_markup_HomepageMeta.lua – Takes the data from the page HomepageMeta in the VP doc and adds specific item meta data to the frontmost page.
  • meta_markup_update.lua – Propagates changes made to the HomepageMeta page to all the item meta data of all pages that require them. This is only just the pages used for the blog-style page.
  • blog_home_atom.lua – Creates the blog-style page now called home in the VP document and also creates a valid atom.xml feed in the output directory.

Comments and questions are welcome. If some enterprising person wants to wrap this all up in the new plugin architecture that would be cool. I’m happy to help if I can.

iCal – Exchange Time Zone Fix – Chapter 3

I’ve updated the iCal-Invite-Fix script again. This time to allow for adding multiple Exchange servers to the script so that you should only need a single script. The set-up is slightly more complex.
As the image above shows there are now only 2 properties, both of which are lists. These lists work together as an array; which means the order of the list items is crucial.

  • exchange_fragment contains unique fragments of the TZID that the Exchange server sends.
  • ical_tzid contains the tzid info that iCal expects to see.

If you have any problems setting it up let me know. This post has all the info for the script.
Download the iCal-Invite-Fix script.

Importing Mail Message Attachments Into Aperture

So I’ve just gotten my new Unibody MacBook and Aperture. Immediately I find myself wanting for a Quick Look > Add to Aperture just like there is for iPhoto. Unfortunately it’s nowhere to be found. Fortunately Aperture is scriptable.
Version 1.0 of SaveAttachments2Aperture is now available. It’s currently very simple with little error checking. It works multiple attachments per message and imports all attachments of a selected message into a new Aperture project.
It could be used in a Mail rule though I prefer to select it manually from the Script menu. I have it saved in ~/Library/Scripts/Applications/Mail/.
A thanks goes out to Automating Aperture where I got some of the Aperture scripting.
Comments welcome.
Now at version 1.1. I added some simple logic to only import certain file types. You might need to add to this list. If I’m missing some let me know, especially with Raw images.
v1.2 – add a bunch of the usual camera raw file types