I’ve wrote this shell script that uses an SMS to post to Twitter. It is ment to be used as an Eventhander for SMS Server Tools, but it’s simple enough for stand alone usage with simple text files.
If used as an Eventhandler the arguments are “RECEIVED” and the path to the SMS file, add “eventhandler=/path/to/sms2twitter.sh” to your smsd.conf. Without SMS Server Tools you can also use a simple file for posting to twitter:
Create a file starting like this:
-
Phone: 0634567890
-
-
Your tweet in max. 140 characters
Then call this script with the path to your file:
-
sms2twitter.sh /path/to/file.txt
You will need to create a sqlite3 DB with this schema:
-
sqlite3 sms2twitter.db \
-
"CREATE TABLE account (phone, username, password, PRIMARY KEY(phone))"
For every Phone that you allow to post Tweets thru SMS you need to run:
-
sqlite3 sms2twitter.db \
-
"INSERT INTO account VALUES (‘phonenumber’, ‘username’, ‘password’)"
Lees meer…
For Postmasters: easy way to read a mailbox from your XMail spool. If you have a CDB file (see this post), it is also capable of looking up aliases.
-
-
readmail real.user@domain.org
-
#or:
-
readmail an.alias@domain.org
-
#or if your RootDomain is domain.org:
-
readmail an.alias
-
-
#!/bin/bash
-
XMAILROOT="/var/lib/xmail"
-
CDB="/var/lib/qpsmtpd/rcptto/validrcptto.cdb"
-
-
RootDomain=$(grep RootDomain $XMAILROOT/server.tab | awk ‘{print $2}’|sed ‘s/"//g’)
-
aliaslookup=1
-
[ -f "$CDB" ] || {
-
echo "warning: CDB file not found, alias lookup disabled"
-
aliaslookup=0
-
}
-
spool="$XMAILROOT/domains/"
-
if [ -z "$1" ]; then echo usage: $0 user@domain; exit; fi
-
user=$(echo $1|cut -d@ -f1);
-
domain=$(echo $1|cut -d@ -f2)
-
[ "$domain" == "$user" ] && domain=$RootDomain
-
-
if [ ! -d "$spool/$domain" ]; then
-
echo "$domain: no such domain in $spool"
-
exit 8
-
fi
-
-
if [ ! -d "$spool/$domain/$user" ]; then
-
if [ $aliaslookup -eq 1 ]; then
-
echo -n "$user@$domain not found, looking for alias: "
-
real=$(cdb -qm $CDB $user@$domain)
-
if [ $real == "" ];then
-
echo "not found"
-
exit 8
-
else
-
echo "using $real"
-
user=$(echo $real|cut -d@ -f1)
-
fi
-
else
-
echo "$user: no such user in domain $domain"
-
exit 9
-
fi
-
fi
-
-
mutt -f $spool/$domain/$user/Maildir
This scripts creates a Constant DataBase file. We use this to interact with the qpsmtpd plugin check_validrcptto_cdb
.
-
-
#!/bin/bash
-
-
#this script creates a cdb file from xmail users and their aliases
-
-
OUTPUTFILE=/var/lib/qpsmtpd/rcptto/validrcptto.cdb
-
XMAILROOT=/etc/xmail
-
-
#no more settings beyond this point
-
-
TMPFILE=$(mktemp /tmp/email2cdb.XXXXXXXXXX)
-
-
[ -d "$(dirname $OUTPUTFILE)" ] || {
-
echo "directory for OUTPUTFILE $OUTPUTFILE does not exists"
-
exit 3
-
}
-
-
[ -f "$TMPFILE" ] && rm $TMPFILE
-
touch $TMPFILE || {
-
echo "can not create $TMPFILE"
-
exit 9
-
}
-
-
#paranoia strikes again:
-
#chmod og-r $TMPFILE
-
-
#list all email boxes:
-
cat $XMAILROOT/mailusers.tab \
-
| sed ‘s/"//g’ \
-
| awk ‘{print $2 "@" $1 "\t" $2 "@" $1}’ \
-
| sed ‘s/^*//’ \
-
| sed ‘s/*//’ >> $TMPFILE
-
-
#list aliases
-
cat $XMAILROOT/aliases.tab \
-
| sed ‘s/"//g’ \
-
| awk ‘{print $2 "@" $1 "\t" $3 "@" $1}’ \
-
| sed ‘s/^*//’ \
-
| sed ‘s/*//’ >> $TMPFILE
-
-
#create cdb file
-
cdb -cm $CDBOPTIONS $OUTPUTFILE $TMPFILE || {
-
echo "can not create cdb file $OUTPUTFILE FROM $TMPFILE"
-
echo "WARNING: I did not remove $TMPFILE for debug purposes"
-
exit 9
-
}
-
-
#cleanup:
-
rm $TMPFILE
-
exit 0
Here is a bash script that uses kdialog to present a password prompt and tries to mount a crypt device. It interacts with the (k)ubuntu “cryptsetup” package.
-
-
#!/bin/bash
-
if [ -r /lib/cryptsetup/cryptdisks.functions ]; then
-
. /lib/cryptsetup/cryptdisks.functions
-
else
-
kdialog –title $(basename $0) –error "/lib/cryptsetup/cryptdisks.functions not found"
-
exit 1
-
fi
-
-
crypt_create (){
-
DLG_TITLE="Cryptsetup Dialog"
-
mountpoint=$(grep $MAPPER/$1 /etc/fstab | awk ‘{FS=" "}{print $2}’)
-
sudo cryptsetup status $1 > /dev/null
-
if [ $? -ne 0 ]; then
-
pwd=$(kdialog –title "$DLG_TITLE" –password "mapping $1 to device <$2>
-
-
Enter passphrase:")
-
if [ $? -ne 0 ]; then return 3; fi
-
if [ "$pwd" == "" ]; then
-
kdialog –title "$DLG_TITLE" –warningyesno "empty password, try again?" && {
-
crypt_create $1 $2
-
return 2
-
}
-
fi
-
echo "$pwd" | sudo cryptsetup create $1 $2
-
mount $mountpoint 2&>/dev/null|| {
-
sudo cryptsetup remove $1
-
kdialog –title "$DLG_TITLE" –warningyesno "cryptsetup create <$1> <$2> failed, try again?" && {
-
crypt_create $1 $2
-
return 2
-
}
-
return 0
-
}
-
else
-
if [ -z $3 ]; then
-
kdialog –yesno "$MAPPER/$CRYPT_NAME is active, do you want to deactivate?" && {
-
umount $mountpoint
-
sudo cryptsetup remove $1
-
}
-
fi
-
fi
-
return 1 #cryptdevice already setup
-
}
-
-
if [ -r $TABFILE ]; then
-
grep -Ev "^#" $TABFILE | while read line; do
-
cryptname=$(echo $line | awk ‘{print $1}’)
-
cryptdevice=$(echo $line | awk ‘{print $2}’)
-
crypt_create $cryptname $cryptdevice $1
-
done
-
exit 0
-
else
-
kdialog –title $(basename $0) –error "$TABFILE not readable"
-
exit 2
-
fi
-
quick walk-through for compiling PostgreSQL with tsearch2 full text extension and Dutch Snowball stemmer on Debian Etch:
-
sudo su -
-
cd /usr/src
-
apt-get build-deps postgresql-8.1
-
wget ftp://ftp4.nl.postgresql.org/postgresql.zeelandnet.nl/latest/postgresql-8.2.4.tar.bz2
-
tar jxvf postgresql-8.2.4.tar.bz2
-
cd postgresql-8.2.4
-
wget http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/tsearch_snowball_82-20070504.gz
-
gunzip tsearch_snowball_82-20070504.gz
-
patch -b -p0 < tsearch_snowball_82-20070504
-
./config
-
make
-
make install
-
cd contrib
-
make
-
make install
-
cd tsearch2/gendict
-
wget http://snowball.tartarus.org/algorithms/dutch/stem.c
-
wget http://snowball.tartarus.org/algorithms/dutch/stem.h
-
./config.sh -n nl -s -p dutch_ISO_8859_1 -v -C‘Dutch Stemmer. Snowball’
-
cd ../../dict_nl
-
make
-
make install
-
wget http://snowball.tartarus.org/algorithms/dutch/stop.txt -O /usr/local/pgsql/share/contrib/dutch.stop
-
adduser postgres
-
mkdir /usr/local/pgsql/data
-
chown postgres /usr/local/pgsql/data
-
su – postgres
-
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
-
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >/tmp/logfile 2>&1 &
-
/usr/local/pgsql/bin/createdb tsearch2
-
/usr/local/pgsql/bin/psql tsearch2 < /usr/local/pgsql/share/contrib/tsearch2.sql
-
/usr/local/pgsql/bin/psql tsearch2 < /usr/local/pgsql/share/contrib/dict_nl.sql
-
/usr/local/pgsql/bin/psql tsearch2
If everything went well you are now in a PostgreSQL prompt.
We will now update ans insert some stuff:
-
UPDATE pg_ts_dict SET dict_initoption=‘contrib/dutch.stop’ WHERE dict_name=‘nl’;
-
INSERT INTO pg_ts_cfg (ts_name, prs_name, locale) VALUES (‘dutch’, ‘default’, ‘nl_NL’);
-
INSERT INTO pg_ts_cfgmap (SELECT ‘dutch’, tok_alias, dict_name FROM pg_ts_cfgmap WHERE ts_name=‘default’);
-
UPDATE pg_ts_cfgmap SET dict_name=‘{nl}’ WHERE ts_name=‘dutch’ AND dict_name=‘{en_stem}’;
select to_tsvector('dutch', 'ik ga naar school'); to_tsvector
------------------
'ga':2 'schol':4
(1 row)
I’ve created php5 and mysql5 documentation packages for Quanta. They include an installer and come in several languages. I’m working on PHP:PEAR Documentation. Download here …
Today I had this problem with a MySQL/php application:
Illegal mix of collations (latin1_bin,IMPLICIT) and (latin1_swedish_ci,IMPLICIT)
I’ve created this loop to solve the problem, because the server contains several database with lots of tables:
-
passwd="yeah right!"
-
mysql="mysql -u root -p"$passwd" -ss -B -e"
-
$mysql "show databases"|while read db; do
-
$mysql "SHOW TABLES FROM $db"|while read table; do
-
if [ "$($mysql "show create table $db.$table"|grep -c latin1_bin)" != "0" ]; then
-
$mysql "ALTER TABLE $db.$table CONVERT TO CHARACTER SET latin1"
-
fi
-
done
-
done
Often I want to copy/paste my WAN IP address, here is a shellscript for it (warning: kde only, requires wget and sed, no error detecting whatsoever!)
-
#!/bin/bash
-
ip=$(wget -q -O – http://checkip.dyndns.org/ | sed ‘s/.+ (([[:digit:]]{1,3}.){3}[[:digit:]]{1,3}).+/1/’)
-
dcop klipper klipper setClipboardContents $ip
-
echo $ip
We use Spamassassin as anti spam tool with Bayes learning. If I want to feed spam massages to the sa-learn tool, I have to get individual messages from my Thunderbird Mailfolder which stores all mails together in a text file.
First I move alle spam massages to the Thunderbird Junk mail. Thunderbird has a build in learning tool to fight spam, so most spam messages are moved to the junk folder automagically. Make sure there are no messages in this folder that are already marked as spam by Spamassassin!
Split a Thundebird mailfolder into individual Mails:
-
targetfolder=/tmp/spam
-
if [ ! -d "$targetfolder" ]; then
-
echo "targetfolder $targetfolder does not exists";
-
exit 1;
-
fi
-
m=0
-
find ~/.mozilla-thunderbird -type f -name Junk|while read junkfile; do
-
i=0
-
for line in `grep -n "From – " "$junkfile" | cut -d: -f1`; do
-
if [ $i -gt 0 ]; then
-
head "$junkfile" -n $(echo $line-1|bc) | tail -n $(echo $line-$cl|bc) > $targetfolder/msg$(printf "%09d" $m).eml
-
fi
-
let i=$i+1
-
let m=$m+1
-
cl=$line
-
done
-
done
Sometimes you have to write lots of CD’s/DVD’s of even more files. This scripts loops through files in a target directory and creates new “virtual disks” and places symbolic links in it to the found file. If a “virtual disk” is full it will create another one. You can define your own pattern for the disknames.
#!/bin/bash
# sizes in Megabytes
CDSIZE=750
DVDSIZE=4380
if [ "$(basename $0)" == "make-dvd" ]; then
let "DISKSIZE=$DVDSIZE*1024*1024"
else
let "DISKSIZE=$CDSIZE*1024*1024"
fi
VERBOSE=1
usage ()
{
echo "usage: $0 [OPTIONS] source target, where options can be:"
echo " -s START number of 1st disk"
echo " -v print usefull messages"
echo " -V print usefull and less usefull messages"
echo " -d BYTES disksize of the writable media (default $DISKSIZE)"
echo " -r puts all symlinks in corresponding directory"
echo " without this option all symbolic links are placed directly under disk"
echo " -p pattern to use for diskname (default DISK_%03d), see man printf"
echo " example pattern: \"MY_CD_%03d\" for MY_CD_001, MY_CD_002, etc ..."
if [ "$1" != "" ]; then
echo "ERROR: $1"
exit 9
fi
exit 8
}
myprint ()
{
if [ "$VERBOSE" == "$1" ]; then
echo $2;
fi
}
integertest ()
{
stringTest=$(echo $1 | sed 's/[0-9]+//g');
if [ ${#stringTest} -gt 0 ]; then
usage "argument for $2 must be an integer"
fi
}
if [ $# -lt 2 ]; then usage; fi
START=1
VERBOSE=0
INTREE=0
PATTERN="DISK_%03d"
while getopts ":s:t:p:rvVd:" Option; do
OPTARG=$(echo $OPTARG | sed 's/^W+//')
case $Option in
s ) START=$OPTARG;;
v ) VERBOSE=1;;
V ) VERBOSE=2;;
r ) INTREE=1;;
d ) DISKSIZE=$OPTARG;;
p ) PATTERN=$OPTARG;;
* ) usage "unkown option";;
esac
done
shift $(($OPTIND - 1))
SOURCE=$(cd "$1" && pwd)
TARGET=$(cd "$2" && pwd)
integertest $START "-s"
integertest $DISKSIZE "-d"
DISKNAME=$(printf $PATTERN $START)
if [ $? -gt 0 ]; then usage "wrong argument for pattern"; fi
if [ ! -d "$SOURCE" ]; then usage "source \"$SOURCE\" is not a directory"; fi
if [ ! -d "$TARGET" ]; then usage "target \"$TARGET\" is not a directory"; fi
if [ ! -w "$TARGET" ]; then usage "target directory \"$TARGET\" is not writable"; fi
OLDIFS=$IFS
IFS=:
CURRENTSIZE=0
FIRSTRUN=1
echo -n "fetching filelist from $SOURCE ... "
for file in $(find -L $SOURCE -type f -printf "%P$IFS"); do
if [ "$FIRSTRUN" == "1" ]; then
echo "done"
myprint 1 "making 1st disk $DISKNAME"
if [ -d "$TARGET/$DISKNAME" ]; then usage "can not make disk $TARGET/$DISKNAME"; fi
mkdir -p $TARGET/$DISKNAME
FIRSTRUN=0
fi
filesize=$(du -b "$SOURCE/$file" 2> /dev/null | sed 's/W+.*//')
myprint 2 $(printf "%s [%10d - %10d] %s" $DISKNAME $CURRENTSIZE $filesize $file 2>/dev/null)
if [ "$filesize" == "" ]; then echo "can not get filesize of file $SOURCE/$file, skipping it"; continue; fi
let "newsize=$CURRENTSIZE+$filesize"
if [ $newsize -gt $DISKSIZE ]; then
let "START=START+1"
DISKNAME=$(printf $PATTERN $START)
myprint 1 "disk full, making new one: $DISKNAME"
CURRENTSIZE=$filesize
if [ -d "$TARGET/$DISKNAME" ]; then usage "can not make disk $TARGET/$DISKNAME"; fi
mkdir -p $TARGET/$DISKNAME
else
let "CURRENTSIZE=$CURRENTSIZE+$filesize"
fi
DIRNAME=$(dirname "$file")
FILENAME=$(basename "$file")
if [ "$INTREE" == "1" ]; then
if [ ! -d "$TARGET/$DISKNAME/$DIRNAME" ]; then mkdir -p "$TARGET/$DISKNAME/$DIRNAME"; fi
LINKTARGET="$TARGET/$DISKNAME/$DIRNAME/$FILENAME"
else
LINKTARGET="$TARGET/$DISKNAME/$FILENAME"
fi
ln -s "$SOURCE/$file" "$LINKTARGET"
if [ $? -gt 0 ]; then
let "CURRENTSIZE=$CURRENTSIZE-$filesize"
fi
done
IFS=$OLDIFS