Hi everybody,
I liked the function of Asus' original software to automagically copy the contents of a USB-device (SD-card reader for example) to an incremental directory on the harddisk of my WL-HDD.
Of course, Oleg's firmware outweighed Asus' original, but still I kind of wanted this feature.
Through some help of this forum, I managed to come up with a set of scripts that helps me do so.
Advantages:
1. It works also with multi-card-readers or multi-partition devices that are not detected properly by the automounter
2. It copies the contents of the storage device to an incremental directory on the harddisk that is easy to recognize (date-time format)
3. It also creates an jpeg-image which contains the contents of the folder of the harddisk where the files have been backup-ed to and writes it back to the storage device.
Why no. 3?
Imagine you are out in the wild and want to backup your SD-card of your camera because it's full and only brought your WL-HDD because it's so small. You just plug your card-reader in and you see the lights flashing, but how can you be sure that everything went well during the copying process?
The image that is created and written back to the drive contains the directory output and can (or should) be viewable in your camera for example. When you see that all files have proper sizes and are complete, you can safely format your SD-Card and don't have to worry until the end of your trip to see if everything REALLY went fine
Enough talk, here are the scripts, they all assume that your internal hard-drive is mounted to /opt:
Insert the following lines into /tmp/local/sbin/post-boot:
Code:
insmod /lib/modules/2.4.20/kernel/drivers/scsi/scsi_mod.o
insmod /lib/modules/2.4.20/kernel/drivers/scsi/sd_mod.o
insmod /lib/modules/2.4.20/kernel/drivers/usb/storage/usb-storage.o
and
Code:
echo /opt/utils/hotplug > /proc/sys/kernel/hotplug
The first three lines are needed only if you turned off the ftp-server in the web-interface. If your system already automagically mounts your storage device to /tmp/harddisk, you can omit them.
Create the file /opt/utils/hotplug:
Code:
#!/bin/sh
# check for need to mount usb-drive
if [ $ACTION = "add" ]; then
devs=`find /dev -name "part?"`;
# e.g. /dev/scsi/host0/bus0/target0/lun3/part1
for dev in $devs; do
part=`echo $dev | sed -e "s/.*part\(.*\)/\1/"`;
# e.g. 1 if part1
dev=`echo $dev | sed -e "s/.*dev\(.*\)\/part.*/\1/"`;
# e.g. /scsi/host0/bus0/target0/lun3
disc=`ls -l /dev/discs | grep $dev | sed -e 's/.* disc\(.*\) ->.*/\1/`;
# e.g. 4 if $dev maps /dev/discs/disc4
# check if already in mount-tab
result=`mount | grep "/dev/discs/disc$disc/"`;
if [ $? = 1 ]; then
echo "Not mounted: $disc";
mounted=0;
while [ $mounted -lt 1 ]; do
dest="/tmp/harddisk$count";
result=`mount | grep "$dest"`;
# if directory exists, increase counter
if [ $? = 0 ]; then
let count=count+1;
else
mounted=1;
fi
done
mkdir -p "/tmp/harddisk$count";
mount /dev/discs/disc$disc/part$part /tmp/harddisk$count
else
echo "disc$disc already mounted!"
fi
done
fi
# unmount "dead" mountpoints
if [ $ACTION = "remove" ]; then
devs=`mount | grep /part | sed -e "s/\(.*\) on .*/\1/"`;
# e.g. /dev/discs/disc4/part1
for dev in $devs; do
if [ \! -e $dev ]; then
dir=`mount | grep $dev | sed -e "s/.*on \(.*\) type.*/\1/"`;
# e.g. /tmp/harddisk
umount $dir;
fi
done
fi
/sbin/hotplug $*
This file checks for devices in the system and mounts them to /tmp/harddisk (or /tmp/harddisk1[2, 3, 4, ...] if already in use), if this hasn't already happened. Use this if your storage device doesn't come up mounted automagically.
For image-backup, create first /tmp/local/sbin/post-mount:
Code:
#!/bin/sh
dirs=`ls /tmp | grep harddisk`;
for dir in $dirs; do
if [ -e /tmp/$dir/dcim ]; then
folder=`date +%Y%m%d_%H%M%S`;
mkdir -p /opt/backup/$folder;
cp -ar /tmp/$dir/dcim/* /opt/backup/$folder;
# this php script requires ipkg-packages gdlib, php, php-gd and cyrus-sasl
ls -lR /opt/backup/$folder | /opt/utils/reportjpg.php;
# modify here according to your camera
cp /opt/backup/result.jpg /tmp/$dir/dcim/100nikon/dscn0001.jpg
umount /tmp/$dir
fi
done
This checks for a directory called "DCIM" (almost all digital cameras use this), and if so, copy all files to /opt/backup/[timestamp], create a report-image in jpg-format and write it back to the camera as dscn0001.jpg (change this according to your camera model). Then unmount the drive.
Unfortunately, my Nikon camera doesn't display this image, it says "this image contains no data", but in Windows Explorer it can be seen, so I assume my Nikon checks some other file attributes. If someone has a solution, please let me know.
To create the image with the directory output, I had to resort to a php-script because I can't code in C to use libgd and libjpeg from there. Would be much faster and more convenient, but that's up to someone else
You need the following ipkg-packages: gdlib, php, php-gd, cyrus-sasl (because of some stupid dependencies).
Put this code under /opt/utils/reportjpg.php:
Code:
#!/opt/bin/php
<?
while (!feof(STDIN)) {
$input = trim(fgets(STDIN));
$res[] = $input;
}
$im=imagecreate(2048,1536);
imagecolorallocate($im,0,0,0);
$col=imagecolorallocate($im,255,255,255);
$y=0; $x=0;
foreach ($res as &$line) {
imagestring($im,1,$x,$y,$line,$col);
$y=$y+12;
if ($y > 1500) {
$x=$x+400;
$y=0;
}
}
imagejpeg($im,"/opt/backup/result.jpg",100);
imagedestroy($im);
?>
Don't forget to chmod 755 all files and save configuration with
flashfs save; flashfs commit; flashfs enable;
Then reboot to activate hotplug changes.
Hope you enjoy this piece of code and if someone could come up with a more ressourceful way of writing the jpg-report-image, please let me know !
CU!
Frederik.