Mass-generating random file names

After setting up Bluetooth on my phone and laptop, I was faced with another problem: the phone saves images using filenames of the form ImageXXX.jpg — which is OK the first time, but tends to conflict with older files later on as the "XXX" counter restarts from 0. One may think that "mktemp" is a solution, but unfortunately that command won't let us choose the extenion of the created file. Instead, on Ubuntu and Debian, use "tempfile":

cd /mnt/Memory\ card/Images/
for f in *; do mv $f `tempfile -d $DEST_DIR --suffix=.jpg`; done

tempfile will create unique file names in the destination directory and avoid race conditions at the same time (not really an issue in this case, but good to know.)

Update: here's a different method that will generate more meaningful (though not random) names

t=`date -u '+%F_%H-%M'`
for f in *; do cp $f $DEST_DIR/${t}_$f; done

The files will be prefixed with a timestamp, which is probably more useful.

Bluetooth in Ubuntu, the CLI way

Note: updated for Hardy (2008-06-09)

Note: for the impatient, just use the script at the end of this post.

I recently received a Nokia 6300 as a birthday present. After playing with the cool 2-megapixel camera I wanted to save some of the pictures and clips to my laptop. The most convenient (and cheapest) way to network the phone and laptop is via Bluetooth.

Not knowing a thing about Bluetooth, I set out on a quest to learn more about this protocol — more specifically, how to use it in Ubuntu. This is where my problems started: nowadays everybody assumes that you run either Gnome or KDE, and most tutorials I found on the topic have a Window-esque technical level (run this from the menu, click that in the dialog). Only I don't use a desktop manager at all: I run fluxbox, and to compound that "crime", I turn off most "standard" services (dbus, hal, NetworkManager and whatnot).

Well, it turns out that to get Bluetooth, you need to start hcid, and this in turn absolutely, positively requires dbus:

service dbus start
hcid -s

At this point you can check your Bluetooth interface and scan for other devices:

laptop:~# hcitool dev
	hci0	00:1C:26:F4:AF:C4
laptop:~# hcitool scan
Scanning ...
	00:1D:98:54:A2:CB	Dan Nokia 6300
laptop:~# sdptool browse 00:1D:98:54:A2:CB

After some failed experiments, I learned that I need to configure a PIN agent. Bluetooth uses a PIN code as a crude form of authentication. When either party attempts a connection, the phone prompts for a PIN. hcid on the laptop also needs a PIN, but since we're outside GNOME land, the default agent (which pops a dialog to ask for a PIN) doesn't work. A PIN agent is actually any program that outputs a string PIN: plus the actual PIN code. The simplest agent is something like

exec /bin/echo PIN:0000

Save this to /usr/local/bin/pin-agent, then simply type passkey-agent --default pin-agent &, which will inform hcid of the agent. Now we're ready to connect to the phone, after apt-get install-ing the very cool obexfs package:

laptop:~# obexfs -b 00:1D:98:54:A2:CB -B 10 /mnt
laptop:~# ls /mnt
Graphics  Memory card  Received files  Themes  Video clips
Images    Music files  Recordings      Tones

where the address is the one reported by hcitool scan earlier. Presto, the phone's clips and images are under /mnt! I was a little bummed that the contacts were NOT there, but I'll figure that out some other time.

To save time, here's a script you can use to automate the process:

# Don't forget to set up pin-agent
/etc/init.d/dbus start
hcid -s
# if you have no passkey-agent, see below
passkey-agent --default pin-agent &
# replace with your own address below
obexfs -b 00:1D:98:54:A2:CB -B 10 /mnt

Update: on Hardy (and possibly even earlier), passkey-agent is no longer installed by default. A simple hack (which, alas, may stop working later on) is to cd to /var/lib/bluetooth, mkdir -p a directory with the same name as your computer's Bluetooth address (hcitool dev shows it), and in that directory create a file called pincodes. The pincodes file must contain one or more lines in the format

00:1D:98:54:A2:CB 0000

The first field must be the phone's Bluetooth address (not the computer's address). This is not the same as the directory name!