Archive
Password generating with python
Direct Link
http://rc3.fileave.com/mkpass.py.txt
To see the script in action, please visit my first Google App: http://genpswd.appspot.com/
Example Usage:
Simple bash reminder
Need to have a reminder while working on the computer? I have developed this simple but very useful script to remind me things that I would forget without a reminder.
#!/bin/bash
# Simple reminder shell script
usage() {
echo -e "usage: `basename $0` [-t minutes] [-m message] [-b beeps]"
echo -e "-t M\t\ttime scheduled to go off in minutes, default 1"
echo -e "-m message\t\tMessage to show when alarm goes off, \
default to 'Something needs your attention'"
echo -e "-b beeps\t\tNumber of beeps, default 5"
}
alarm() {
sleep ${1}m
echo -n ${2}
bps=$3
seq_beeps=$((bps*2))
for i in `seq $seq_beeps`; do
[ `expr $i % 2` == 0 ] && sleep 1 || echo -n -e \\a
done
}
minutes=1
beeps=5
msg='Something needs your attention'
[ ! `whoami` == "root" ] && echo \
"must be root to run this script" && exit 0
while getopts "t:m:b:h" flag
do
case $flag in
t)
case $OPTARG in
[0-9] | [0-9][0-9] | [0-9][0-9][0-9] )
minutes=$OPTARG;;
*)
echo "usage: minutes value must be in range 0 to 999"
;;
esac
;;
m)
msg=$OPTARG;;
b)
case $OPTARG in
[0-9] | [0-9][0-9])
beeps=$OPTARG
;;
*)
echo 'usage: beeps value must be in range 0 to 99'
;;
esac
;;
h|*)
usage
exit 0
;;
esac
done
alarm $minutes "$msg" $beeps &
Example Usage:
alarm -t 5 -m "Check your coffee" -b 10
NOTE: You have to use sudo or become root to use this script.
Use Aleratec Roboracer LS Duplex under Linux to automate daily dvd backups
[UPDATED 3/12/2012]
Just created a new project on github for this script for better viewing: https://github.com/midnightcodr/roboracer_ls_script
This is a successor to my another post published a few days ago: http://ricochen.wordpress.com/2009/07/14/use-aleratec-roboracer-cddvd-duplicator-under-linux/

#!/bin/bash
# script to control RoboRacer LS Duplex under linux
ADMIN=change_to@admin.email.address
DEBUG=1
DEV=`dmesg|awk '/pl2303.*ttyUSB/{print $NF;exit}'|tr -d ' '`
if [ -n "$DEV" ]; then
DEV=/dev/$DEV
if [ ! -c $DEV ]; then
info="pl2303 port does not exist, make sure \
RoboRacer LS Duplex is connected. If\
so please reboot it and try again."
rpr "Problem" "$info"
exit 1
fi
fi
# change the following device names if needed, if there
# are no other drives other than the Duplex's then most likely
# the names will be /dev/sr0 and /dev/sr1
TOPDRIVE=/dev/sr1
BOTTOMDRIVE=/dev/sr2
SCRIPT=${0##*/}
rpr() {
if [ -n "$ADMIN" ]; then
echo -e "$2" | mail -s "`hostname -f` \
RoboRacer: $1" $ADMIN
fi
}
usage() {
echo ">>Examples:"
echo "$SCRIPT demo"
echo "$SCRIPT load_topdrive"
echo "$SCRIPT load_bottomdrive"
echo "$SCRIPT eject_topdrive"
echo "$SCRIPT retrieve_topdrive"
echo "$SCRIPT eject_bottomdrive"
echo "$SCRIPT retrieve_bottomdrive"
echo "$SCRIPT remove_disc_topdrive"
echo "$SCRIPT remove_disc_bottomdrive"
echo "$SCRIPT top_hand_small"
echo "$SCRIPT top_hand_big"
echo "$SCRIPT top_hand_back"
echo "$SCRIPT bottom_hand_small"
echo "$SCRIPT bottom_hand_big"
echo "$SCRIPT bottom_hand_back"
echo "$SCRIPT top_tray_load_disc"
}
w() {
echo -e "$1" >$DEV
}
ww() {
case $1 in
top_hand_small) w !BNKRG95;; #top handle turns a small angle
top_hand_big) w !BNKRB90;; #top handle turns a big angle
top_hand_back) w !BNKRH96;; #top handle turns back to origin
bottom_hand_small)w !BNKPG93;; #bottom handle turns small angle
bottom_hand_big) w !BNKPB8E;; #bottom handle turns a big angle
bottom_hand_back) w !BNKPH94;; #bottom handle turns back to origin
top_tray_load_disc) w !BNKDP90;; #release one disc from the top disc loader
1) w !BNKLF8E;;
2) w !BNKFG89;;
10) w !BNKLG8F;;
13) w !BNKSTA3;;
*)
echo "unsupported parameter" && exit 0
;;
esac
sleep 2
}
eject_topdrive() {
[ -b $TOPDRIVE ] && /bin/eject $TOPDRIVE || echo "$TOPDRIVE does not exist"
}
retrieve_topdrive() {
[ -b $TOPDRIVE ] && /bin/eject -t $TOPDRIVE || echo "$TOPDRIVE does not exist"
}
eject_bottomdrive() {
[ -b $BOTTOMDRIVE ] && /bin/eject $BOTTOMDRIVE || echo "$BOTTOMDRIVE does not exist"
}
retrieve_bottomdrive() {
[ -b $BOTTOMDRIVE ] && /bin/eject -t $BOTTOMDRIVE || echo "$BOTTOMDRIVE does not exist"
}
load_topdrive() {
eject_topdrive
ww top_hand_small
ww top_hand_back
ww top_tray_load_disc
retrieve_topdrive
[ $DEBUG -eq 1 ] && echo "Top drive $TOPDRIVE is loaded"
}
load_bottomdrive() {
eject_bottomdrive && sleep 2
ww bottom_hand_small
ww bottom_hand_back
ww top_hand_big
eject_topdrive && sleep 2
retrieve_bottomdrive
ww top_hand_back
retrieve_topdrive && sleep 2
[ $DEBUG -eq 1 ] && echo "Bottom drive $BOTTOMDRIVE is loaded"
}
remove_disc_topdrive() {
ww top_hand_back
eject_topdrive && sleep 2
ww top_hand_small
ww top_hand_back
retrieve_topdrive
[ $DEBUG -eq 1 ] && echo "Disc removed from top drive $TOPDRIVE."
}
remove_disc_bottomdrive() {
ww bottom_hand_back
eject_bottomdrive && sleep 2
ww bottom_hand_small
ww bottom_hand_back
retrieve_bottomdrive
[ $DEBUG -eq 1 ] && echo "Disc removed from bottom drive $BOTTOMDRIVE."
}
demo() {
echo "executing $0 load_topdrive"
load_topdrive
echo "Simulating writing data to disc in top drive"
sleep 5
echo "executing $0 load_bottomdrive"
echo "Loading disc from top drive to bottom drive"
load_bottomdrive
echo "Simulating labeling disc in bottom drive"
sleep 5
echo "executing $0 remove_disc_bottomdrive"
echo "Removing disc from bottom drive"
remove_disc_bottomdrive
echo "Done."
}
if [ -c $DEV -a -b $TOPDRIVE -a -b $BOTTOMDRIVE ]; then
case $1 in
demo)
demo;;
load_topdrive)
load_topdrive;;
load_bottomdrive)
load_bottomdrive;;
eject_topdrive)
eject_topdrive;;
retrieve_topdrive)
retrieve_topdrive;;
eject_bottomdrive)
eject_bottomdrive;;
retrieve_bottomdrive)
retrieve_bottomdrive;;
remove_disc_bottomdrive)
remove_disc_bottomdrive;;
remove_disc_topdrive)
remove_disc_topdrive;;
top*|bottom*|1|2|10|13)
ww $1;;
*)
usage;;
esac
else
[ $DEBUG -ne 1 ] && rpr "Problem" "Check dud burner's connection"
fi
The above script is the major part of a dvd email archiving application that I have developed recently. With the help of USB Sniffer (current version 1.8) I am able to get those magic control strings. What amazed me is that under Linux, this duplicator doubles as a true robotic dvd archiver — all processes, from generating iso files to light-scribing labels, run ompletely without user interference. The only thing needs to be done is to load empty discs (capacity: 100 discs) and collect them once a while. Basically I use the above script in this way:
1) Generate daily (encrypted) email archive
2) Generate weekly iso’s
3) When iso is ready, burn the iso file on the first tray on the Duplex
4) Use python Image Library to generate a .bmp file with the date-range of the archives as the label for the following step
5) Light-scribe the disc on the second tray with data side faced-up.
6) Disc removed from the second tray into the dvd holder.
Use Aleratec Roboracer CD/DVD duplicator under Linux
This is the bash script that I wrote a while ago to control the Aleratec Roboracer CD/DVD Duplicator under Linux, which is not a supported platform by the manufacturer (standard features such as ejecting burning disks are supported, but not the loading part). Those control strings were obtained using USB sniffer [ http://benoit.papillault.free.fr/usbsnoop/doc.php.en ]. This script became an important part of an email backup application which archives daily emails and burns to the robotic duplicator without user interference.
#!/bin/bash
DEV=/dev/ttyUSB0
SR=`dmesg |awk -F ':' '/scsi3-mmc drive: 48x\/48x writer dvd-ram/{print $1}'`
DRIVE=/dev/$SR
w() {
echo -e "$1" > $DEV
}
usage() {
echo "`basename $0` -e : eject the disc"
echo "`basename $0` -l : load the disc"
}
[ -c $DEV ] || echo "$DEV does not exist, please make sure\
the duplicator is connected" && exit 1
case $# in
1)
case "$1" in
"-e")
eject $DRIVE
sleep 1
#turn handle a small angle
w !BNKPG93
sleep 1
#turn handle back to origin
w !BNKPH94
sleep 1
eject -t $DRIVE
echo "disc ejected"
;;
"-l")
eject $DRIVE
#turn handle a large angle
w !BNKPB8E
sleep 1
#load disc
w !BNKPH94
sleep 2
#turn handle back to origin
w !BNKDP90
sleep 2
eject -t $DRIVE
echo "disc loaded"
;;
*)
usage ;;
esac
;;
*)
usage ;;
esac
Direct link to the script: http://rc3.fileave.com/robo.sh.

Installation of nginx on Gentoo/Sheevaplug
step 1.
mkdir /etc/portage
echo "www-servers/nginx **" >>/etc/portage/packages.keywords
step 2.
emerge nginx
step 3.
mkdir -p /var/www/localhost/htdocs
echo "<h1>Hey it works</h1>" >>/var/www/localhost/htdocs/index.html
index.html is created for testing.
step 3.
vi /etc/nginx/nginx.conf
comment out the first line in server block (or change 127.0.0.1 to the ip you want httpd listens on), without this step nginx will only listens on 127.0.0.1
server {
#listen 127.0.0.1;
server_name localhost;
access_log /var/log/nginx/localhost.access_log main;
error_log /var/log/nginx/localhost.error_log info;
root /var/www/localhost/htdocs;
}
step 5.
mkdir /usr/logs
touch logs/nginx.lock.accept
[ without this step nginx will fail to start ]
step 7.
/etc/init.d/nginx start
step 8.
To verify nginx is running
pgrep nginx
It should report 2 pid numbers; run
netstat -na|grep :80
to test if the port binding is correct, you should see something similar to
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
Gentoo on sheevaplug: Unknown HZ value! problem
I was following the instruction from http://www.gentoo.org/doc/en/handbook/handbook-arm.xml?part=1&chap=7 trying to put Gentoo onto my sheevaplug. Everything seems to be functioning except I couldn’t get the login prompt to appear through the usb-serial port, but I was able to ssh to the box though. The complete booting message reads
Press I to enter interactive boot mode * Mounting proc at /proc ... [ ok ] * Mounting sysfs at /sys ... [ ok ] * Mounting /dev ... [ ok ] * Starting udevd ... [ ok ] * Populating /dev with existing devices through uevents ... [ ok ] * Waiting for uevents to be processed ... [ ok ] * Mounting devpts at /dev/pts ... [ ok ] * Remounting root filesystem read-only ... [ ok ] * Checking root filesystem .../dev/sda1: clean, 194291/1197168 files, 504877/4s [ ok ] * Remounting root filesystem read/write ... [ ok ] * Checking all filesystems ... [ ok ] * Mounting local filesystems ... [ ok ] * Mounting USB device filesystem (usbfs) ... [ ok ] * Activating (possible) swap ... [ ok ] * Your TIMEZONE in /etc/conf.d/clock is still set to Factory! * Setting system clock using the hardware clock [UTC] ... [ ok ] * Configuring kernel parameters ...Unknown HZ value! (80) Assume 100. [ ok ] * Updating environment ... [ ok ] * Cleaning /var/lock, /var/run ...Unknown HZ value! (79) Assume 100. [ ok ] * Wiping /tmp directory ... [ ok ] * Device initiated services: udev-postmount * Setting hostname to sheevaplug ... [ ok ] * Loading key mappings ... [ ok ] * Setting terminal encoding to UTF-8 ... [ ok ] * Setting user font ... [ ok ] * Starting lo * Bringing up lo * 127.0.0.1/8 [ ok ] * Adding routes * 127.0.0.0/8 ... [ ok ] * Starting eth0 * Bringing up eth0 * 192.168.1.59/24 [ ok ] * Adding routes * default via 192.168.1.1 ... [ ok ] * Initializing random number generator ... [ ok ] Unknown HZ value! (85) Assume 100. INIT: Entering runlevel: 3 * Starting syslog-ng ... [ ok ] * Mounting network filesystems ... [ ok ] * Starting sshd ... [ ok ] * Starting vixie-cron ... [ ok ] * Starting local ... [ ok ] Unknown HZ value! (86) Assume 100.[ System is ready at this point, but the login prompt just can't show up; I am able to ssh to the box though. ]
I haven’t found any solution (tried re-installing procps as suggested by some posts but it didn’t help) yet to this problem. I also tried the vinilla-sources-2.6.30.1 kernel, but the problem remains the same. Maybe it’s time to file a bug report with Gentoo.
Edit [ July 6th, 2009 ]:
Today I solved half of the problem, the reason why I couldn’t get a login prompt through the serial port is line #39 in /etc/inittab
s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100
After change that line to
s0:12345:respawn:/sbin/agetty 115200 ttyS0 vt100
I finally had the login prompt appear as it should.
Host file for free with fileave
Just discovered http://www.fileave.com/ and started using it. With the free account I signed up I get up to 50MB of free storage with 300MB of daily data transfer limit (downloads) by external linking. It’s not bad at all considering the price – $0.
As a quick test, I am going to display an image of my favorite webcam:
A few notes:
1. make sure your file has a valid extension. I found that .sh, .txt, .jpg, etc are supported, but .py is not, therefore for (text) files extensions that are not supported, append .txt to the file name before uploading.
2. if you have named your script as myprogram, change it to myprogram.sh before uploading. Fileave lets you upload any types of files, but if the file does not have an extension that it supports, attempting to access the file will give out “File Not Found” error.
grep in real time
By combining tail and grep you can achieve something pretty cool. First let’s write this simple bash script:
#!/bin/bash
[ $# -lt 2 ] && echo "$0 file \"pattern\"" && exit 0
tail -f $1|while read line; do echo $line|egrep --color "$2"; done
Save it as flowgrep, make it executable:
chmod +x flowgrep
The syntax is very easy, just ./flowgrep <log_file> <pattern>. Let’s monitor a growing log file for numbers:
./flowgrep event.log [0-9]+
This will output lines containing at least one 1-digit number and the number(s) will be in red. To terminate the script simply press Ctrl + C
Sample output:
123 is a good number
July 4th is a few days away.
I feel it’s 82 degrees right now.
^C
Note: if pattern contains space(s), use double quotations (“) to enclose it. for example:
./flowgrep /var/log/messages "Too many login failures"
Beautify your code with pygments
Ever wonder how I colour-coded my code blocks with colours? CSS? That’s almost right. WordPress does not support css customisation for standard accounts, but you can get around with this limitation by using inline css. Here’s a good post talking about this technique: http://www.scratch99.com/2007/06/wordpress-simple-css-text-boxes-in-posts/
Inspired by that post, here’s how I do to make my snippets colourful:
1. Download Pygments from http://pypi.python.org/pypi/Pygments [ the .tar.gz file. The pygments site seems to be down at this moment ]
2. Untar it and install it as root
tar xzf Pygments-1.0.tar.gz
cd Pygments-1.0
sudo python setup.py install
3. After the installation you are ready to style your code. Some examples:
pygmentize -f html -O noclasses myscript.sh
outputs css-lized html to the screen
pygmentize -f html -O noclasses -l bash myscript
outputs css-lized html to the screen, option -l bash is used to specify which lexer to use
pygmentize -f html -O noclasses -o myprog.html pyprog.py
outputs css-lized html to file myprog.html
4. Copy and paste the html code from above step into the code block in your post. Preview it if needed. Then publish.
Stop ftp brute force attacks using simple bash script
In one of the servers I am managing I’ve noticed a lot of ftp login attempts recently (server is running ncftp). The pattern of login failures is pretty straightforward hence I’m using tail -f combined with grep to monitor /var/log/messages real-time and add the bad ips to /etc/hosts.deny as soon as attacks are detected. It’s also a good idea to lower the maximum number of failure thread-hold in Ncftpd. This script has been tested on OpenSuSE but it should run with none or little modification on other Linux systems. Here’s the code, don’t forget to change the admin’s email address.
#!/bin/bash
DEBUG=0
LOG=/var/log/messages
ACTION() {
DENY=/etc/hosts.deny
ADMIN=change_to_admin@email.address
while read line; do
grep -q $line $DENY
if [ $? -ne 0 ]; then
if [ $DEBUG == 1 ]; then
echo "will append $line to $DENY"
else
echo "ALL:$line">>$DENY
[ -n "$ADMIN" ] && echo $line | \
mail -s "ftp attacks `hostname -f`:action taken" $ADMIN
fi
fi
done
#change ALL to NcFTPd to block FTP access
}
tail -f $LOG|while read line; do echo $line |grep "Too many login failures from"|\
awk 'BEGIN{FS="[ ;]+"} {print $11}'|ACTION; done &
