Well, everybody seems to be asking why the iPad can’t print files, yet.

If you are looking for iPad printing solutions, you might have come across funny approaches like this one, but this article is about a serious solution.

Credits: to use Mac OS X Server’s mail services to provide printing features for the iPad was Armin Briegel’s idea. You can follow him on Twitter. I was just the guy to write the few lines of code.

The idea is very easy: iPad’s iWork applications as well as other iPad apps can export PDF files, which you can send to an email address of choice.

If now you use a Mac OS X Server machine (can be a Mac mini server, e.g.) which runs mail services to print all PDF files sent to a specific address, you have an easy solution to the iPad printing “challenge”.

I guess you know how to set up Mac OS X Server 10.6 to run basic mail services, if not, read my wonderful O’Reilly book on it :-D The book comes in german only, so see it as a chance to improve your german :-D , or get in touch with O’Reilly, that you want it translated into english.

So this is how it works:

1. List available printers and test them

First open the Terminal on your Mac OS X Server 10.6 and type the following line to see which printers are available for our mail printer.
mothership:iPadPrint root# lpstat -a
EPSON_Perfection_2480_2580 accepting requests since Mon Aug 31 18:33:07 2009
Fax accepting requests since Tue May 11 21:25:40 2010
hp_deskjet_5550 accepting requests since Tue May 11 21:55:46 2010

In this example you see that there are three printers available on my machine, where the EPSON device actually is a scanner, and there is a Fax available, too, but imagine that there are multiple printers you might want to use.

Now try if you can print PDF files to one of your printers:
lp -d "hp_deskjet_5550" 1.pdf
In the line above replace “hp_deskjet_5550″ with the name of your printer. Replace “1.pdf” with the absolute file path of a pdf file.
If this works fine, go to the next step.

2. Set up printing mail accounts on Mac OS X Server

I assume that your Mac OS X Server runs as an Open Directory Master. Now open the Workgroup Manager and create a new mail account for your printer. In my case the user will be called “hp_deskjet_5550″, the domain is “andre-aulich.de”, so the complete email address will be “hp_deskjet_5550@andre-aulich.de”.

Note: If you don’t want some Internet folks printing thousands of pages on your machines, make sure that this machine can not be reached from the internet. If this is not possible, create a dedicated internal domain which can not be reached from outside.

This is how the new account looks like in Workgroup Manager:


Save theses settings, send an email without any attachements, and a second one with a PDF file as attachment to this account, and then open the Terminal and change into your dovecot’s mail directory:
mothership:mail root# cd /var/spool/imap/dovecot/mail
mothership:mail root# ls -al
total 0
drwxrwxr-x 10 _dovecot mail 340 Mar 25 09:56 .
drwxr-xr-x 4 root wheel 136 Aug 31 2009 ..
drwx------ 15 valerie mail 510 Nov 10 2009 14167B4C-211D-4AA9-A2B4-4641AD5C508B
drwx------ 25 andre mail 850 May 12 11:38 22D9FA73-A1CA-4981-AD37-3E06D7E4F457
drwx------ 13 public mail 442 Nov 10 2009 2AF362D6-E665-48D7-98AF-E347B055135A
drwx------ 11 ab mail 374 Mar 12 10:48 2EF9F9D2-69FD-4670-B1FE-2C8FC55D3675
drwx------ 16 ical mail 544 Jan 15 16:32 A1BB97FC-5E6D-491C-AAED-F8B9212FE3D3
drwx------ 10 hp_deskjet_5550 mail 340 Mar 25 09:56 B806EEC7-9C41-49B7-8D7C-DF507DFE21DF
drwx------ 16 sadmin mail 544 Nov 18 12:15 E8043686-DCCC-432F-BD96-85C400288357
drwxrwxrwx 7 andre mail 238 Nov 10 2009 Public
mothership:mail root# cd B806EEC7-9C41-49B7-8D7C-DF507DFE21DF/
mothership:B806EEC7-9C41-49B7-8D7C-DF507DFE21DF root# ls -al
total 32
drwx------ 10 hp_deskjet_5550 mail 340 Mar 25 09:56 .
drwxrwxr-x 10 _dovecot mail 340 Mar 25 09:56 ..
drwx------ 2 hp_deskjet_5550 mail 68 Mar 25 09:56 cur
-rw------- 1 hp_deskjet_5550 mail 84 Mar 25 09:56 dovecot-uidlist
-rw------- 1 hp_deskjet_5550 mail 8 Mar 25 09:56 dovecot-uidvalidity
-rw------- 1 hp_deskjet_5550 mail 0 Mar 25 09:56 dovecot-uidvalidity.4bab2555
-rw------- 1 hp_deskjet_5550 mail 220 Mar 25 09:56 dovecot.index.log
-rw------- 1 hp_deskjet_5550 mail 11 Mar 25 09:56 maildirsize
drwx------ 3 hp_deskjet_5550 mail 102 Mar 25 09:56 new
drwx------ 2 hp_deskjet_5550 mail 68 Mar 25 09:56 tmp
mothership:B806EEC7-9C41-49B7-8D7C-DF507DFE21DF root# cd new
mothership:cur root# ls -al
total 0
drwx------ 2 hp_deskjet_5550 mail 68 Mar 25 09:56 .
drwx------ 10 hp_deskjet_5550 mail 340 Mar 25 09:56 ..
-rw------- 1 hp_deskjet_5550 mail 1.3K May 12 12:02 1273658576.M795669P68535.mothership.intern,S=1327,W=1364:2,
-rw------- 1 hp_deskjet_5550 mail 1.3K May 12 12:03 1273658602.M6558P68554.mothership.intern,S=1325,W=1362:2,
-rw------- 1 hp_deskjet_5550 mail 77K May 12 12:05 1273658717.M385494P68662.mothership.intern,S=78367,W=79416:2,
-rw------- 1 hp_deskjet_5550 mail 77K May 12 12:05 1273658742.M267533P68676.mothership.intern,S=78365,W=79414:2,

What have we done here? Dovecot stores emails in /var/spool/imap/dovecot/mail. We list the content of the folder and see that each user has its own folder, named like the UUID of the user. If you don’t know how to look up the UUID of a user, or if you just don’t want to spend the time doing it, just look for the folder which is owned by our new printer user.
If you need to look up the UUID of our newly created user, you can also type
dscl /LDAPv3/127.0.0.1 -read /Users/hp_deskjet_5550 | grep apple-generateduid
in Terminal to get an output like this:
dsAttrTypeNative:apple-generateduid: C784550D-B2A6-4881-8DAF-0FC96D4BE8ED
Now you can search for the mail folder of our freshly created mail user.
In the code above we see that the folder B806EEC7-9C41-49B7-8D7C-DF507DFE21DF is owned by hp_deskjet_5550, so we change into this directory and list its contents. New mails will always be copied into the “new” folder, so we change into this directory and list its content, which already holds 4 emails in my case.

3. Extract attachments from emails and print them

First, make sure you have MacPorts installed, then install ripmime:
bash-3.2# port install ripmime
---> Computing dependencies for ripmime
---> Fetching ripmime
---> Attempting to fetch ripmime-1.4.0.6.tar.gz from http://lil.fr.distfiles.macports.org/ripmime
---> Verifying checksum(s) for ripmime
---> Extracting ripmime
---> Configuring ripmime
---> Building ripmime
---> Staging ripmime into destroot
---> Installing ripmime @1.4.0.6_0
---> Activating ripmime @1.4.0.6_0
---> Cleaning ripmime

Now, create a new directory and a bash script which we are going to use for further automation:
mkdir -p /usr/local/iPadPrint/
cd /usr/local/iPadPrint/
touch printpdfs
chmod +x printpdfs

Open the script using nano and insert the following code:
#!/bin/bash
TMPDIR="/usr/local/iPadPrint/tmp/"
mkdir -p /usr/local/iPadPrint/tmp/
for i in /var/spool/imap/dovecot/mail/C784550D-B2A6-4881-8DAF-0FC96D4BE8ED/new/*; do
if [[ "$(grep "Content-Type: application/pdf;" "$i")" == "" ]]; then
echo "Deleting file $i as it holds no pdf files."
rm "$i"
else
echo "Printing pdf attachment(s) of file $i"
/opt/local/bin/ripmime -i "$i" -d "$TMPDIR"
rm "$i"
fi
done
for i in "$TMPDIR"*; do
if [[ "$i" != *.pdf ]]; then
echo "$i deleted. No pdf file"
rm -r "$i"
else
echo "$i will be printed."
lp -d "hp_deskjet_5550" "$i"
rm "$i"
fi
done

You can also download the script from here. Just extract it, copy it into /usr/local/iPadPrint and make it executable.
Change /var/spool/imap/dovecot/mail/C784550D-B2A6-4881-8DAF-0FC96D4BE8ED/new/* to match your environment.
Now invoke the script.

It will extract all attachments out of your emails. If an email doesn’t contain a pdf file, it will be deleted without printing.
The tool will print all contained pdf files and delete everything after printing.

4. Automate it

To run this whenever a new email arrives in the account of our printer mail account, download this file, copy it into /Library/LaunchDaeomons, and make sure, its permissions look like this:
-rw-r--r-- 1 root wheel 458 May 12 13:38 de.andre-aulich.ipadprinter.plist
Change the line /var/spool/imap/dovecot/mail/C784550D-B2A6-4881-8DAF-0FC96D4BE8ED/new/ to match your environment.
Then load the job:
launchctl load -w /Library/LaunchDaemons/de.andre-aulich.ipadprinter.plist

Now Mac OS X Server 10.6 automatically discovers new print jobs you send via email and prints all included pdf files to the selected printer.

You can use this solution to work with multiple printers by simply creating more scripts and launchd jobs.

Hope this helps!

P.S.: Most cli commands need to be invoked as root user or with sudo.

Posted on by André Aulich. This entry was posted in Mac OS X Server, Mail.

Comments are closed.