mocp / random / enqueue
After disk failure on our company music server, I lost my enqueue-some-random-music-script. That shan’t happen again. So here, for my own enjoyment: autoenq.sh #!/bin/sh enqueue_app="mocp -a" music_glob="*.mp3" music_path="`dirname "$0"`" list_path="$music_path/.autoenq.list" if [ "$*" = "-c" ]; then # Create list of all files find . -type f -iname "$music_glob" > "$list_path.tmp" 2>/dev/null # no lost+found # Create list of all dirs that have files cat "$list_path.tmp" | sed -e 's/\/[^\/]*$//' | sort | uniq > "$list_path" exit 0 fi args="`echo "$*" | sed -e "s/['\\\\]//g"`" # no backslashes and single quotes please args="`echo "$args" | sed -e 's/[[:blank:]]\+/.
asterisk dialplan peculiarities / regex with eqtilde
In the Asterisk PBX dialplan, expressions can be formed using the $[...] syntax. Addition, subtraction, comparison and so on are defined. As is a regex operator: =~ Unfortunately, the documentation about the details of the implementation is hard to find. Here, a breakdown of my findings: static struct val * op_eqtilde is defined in main/ast_expr2.y It uses the REG_EXTENDED flag when calling regcomp: so extended regular expression syntax is used.
executing remote command / ssh / extra escaping
If you use ssh to run commands remotely, you may have run into the problem that you need an extra layer of escaping. Let’s say you have application myapp that for some reason only runs on host myserver. If you have functional ssh keys to log onto myserver it can be helpful to create a myapp wrapper on your desktop. After all, this: $ myapp myargs … is far more convenient than doing this:
django / query expression / negate
Suppose you have an is_enabled boolean in your Django model. class Rule(models.Model): is_enabled = models.BooleanField(blank=True) # other exciting fields here And now imagine you want to negate the is_enabled values. Something you would easily do in SQL, with: UPDATE myapp_rule SET is_enabled = NOT is_enabled; The Django F-syntax is nice, and looks like it should be up for the task. Let’s sum up a couple of attempts: Rule.objects.update(is_enabled=(not F('is_enabled'))) No! You get this:
mysql issue warnings / cron
I’ve previously written about MySQL pain in the behind issues involving views with SECURITY DEFINER and bad client collation selection. For the former problem, I wrote a script that you could call periodically to warn you of potential problems with your views. Now I’ve extended it to warn you about collation issues as well. Put warn-mysql-issues.sh (view) in your cron tab and run it periodically. It’ll save you from production-time errors that you get when attempting to compare a string of one collation with another.
linux / canon mf8350 / printer driver
Getting printer drivers for the Canon MF8350 to work under Ubuntu is a big pain in the behind. (Installation using custom scripts that abuse both /usr/lib and /usr/local/lib and ultimately fail to compile for obscure reasons.) My colleague found that the easiest way to get it to work, was converting the RPM to DEB using alien(1). For your enjoyment, here are the two debian packages needed for Ubuntu 10.04 (amd64):
diff / memory exhausted / udiff
Sometimes when I’m unsure what a button in a database-driven application does, I simply click it and check the differences in the database before and after the click. If the database dumped is (somewhat) sorted and with one line per row (for MySQL use –skip-extended-insert), this can be an easy method of verifying that your application action does exactly what you expect and nothing more. Create a pre.sql before the click, click the button and watch the action happen.
pcap / capture fragments / udp
When dealing with internet protocols that operate on top of UDP, fragmenting suddenly becomes a lot less uncommon. Normally, you would only encounter fragments on TCP connections when the MTU on the sending host is larger then the MTU in any of the next hops. Hosts usually attempt to avoid fragmentation for obvious reasons. (Inefficiëncy, extra reassembly work.) For connectionless UDP packets this is a different matter. Protocols over UDP expect packets to be single entities.
no sql security definer / please
Have you ever had it happen that you removed a MySQL user and suddently parts of your application stopped working? Not because you removed the user that was connecting, but because you removed the user that defined the particular view or function that you were using. I have, and it was quite stressful ;-) We moved a slave machine to a different IP, I updated the mysql.user host column, and BAM, the application running on the master mysql stopped working.
build error / unixodbc / debian-squeeze
Building unixodbc-2.2.14p2 on debian/squeeze which you just fetched through apt-get source unixodbc. ~/src/unixodbc-2.2.14p2$ ./configure ... works fine ... ~/src/unixodbc-2.2.14p2$ make ... make: Entering directory `/home/walter/src/unixodbc-2.2.14p2/odbcinst' make: *** No rule to make target `libltdl/libltdlc.la', needed by `libodbcinst.la'. Stop. make: Leaving directory `/home/walter/src/unixodbc-2.2.14p2/odbcinst' make: *** [install-recursive] Error 1 The fix: add top_build_prefix to the environment. ~/src/unixodbc-2.2.14p2$ top_build_prefix=`pwd`/ make ... success!
asterisk / nat keepalive / round robin dns
Current Asterisk (telephony software) version 1.6.2.x (and probably 1.4 and 1.8), has an odd quirk with the qualify option. The qualify option enables a function that checks the response times of the SIP peer. By default, it sends an OPTIONS SIP packet every 60 seconds. The quirk here, is that it sends the packet to the first A-record resolved for this peers hostname at startup (or sip reload). This works fine in most cases when the host has only one A-record.
pruning old data / mysql / csv
It is not uncommon to have a database with records that just accumulate and accumulate over time. Think of log files, telephony billing records, traffic data and so forth. The chances that you’ll ever need this data again are very slim. And letting your database grow indefinitely is not particularly smart. Time to prune! Two things you need to worry about while pruning your data: Throwing it all away without a backup doesn’t feel right.
port forwarded ssh / port 22
Sometimes you need to access your source code repository-server from a new server which hasn’t been whitelisted yet. You check out the source over port 22, but you can’t, because traffic from new-server to 22 is rejected. The quick solution, you know this, is ssh port forwarding. Connect to old-server and forward connections to repository-server from there. $ ssh old-server -L1234:repository-server:22 That works. For mercurial, at least. $ hg clone ssh://walter@localhost:1234//srv/hg/myproject myproject walter@localhost's password: requesting all changes .
faxable images / asterisk pbx
Because creating images that the open source PBX Asterisk(tm) will properly fax using the SendFAX() application, was a pain in the ass, I’d like to share my findings. The HOWTO for creating TIFF images that are laid out so the spandsp fax back-end in asterisk, is embedded in the images2fax.sh shell script, below. In short, you need to have images of 1728x2292, in 2 colors, with the correct DPI (204x196) and the right compression.
nat / switch external source port
When reproducing an issue with IP phones speaking SIP, I ran into the question of how to switch source port on my linux NAT router. The problem the clients were having, were a result of a failing (or reset) NAT-gateway. The NAT-gateway would change the external source port mid-dialog (some SIP dialogs can persist for quite a long time). So, how do you go about switching source port on an UDP connection on your Linux NAT router without resetting it (or disturbing anyone else using it)?
sip totag / grandstream / register
SIP Question: The Grandstream GXP2000 18.104.22.168 sends SIP REGISTER requests with a To tag. Is my proxy wrong in refusing the request? REGISTER sip:server SIP/2.0 Via: SIP/2.0/UDP 22.214.171.124:5074;branch=z9hG4bK0b90873d634698eb From: "phone 123" <sip:123@server>;tag=c29eb9104c6a5a86 To: <sip:123@server>;tag=as77984b6 Contact: <sip:firstname.lastname@example.org:5074;transport=udp> Supported: path Authorization: Digest username="123", realm="server", algorithm=MD5, uri="sip:server", nonce="0997652c", response="3b91afb768c11ae0a0405e1bed41bc23" Call-ID: email@example.com CSeq: 56349 REGISTER Expires: 3600 User-Agent: Grandstream GXP2000 126.96.36.199 Max-Forwards: 70 Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE,UPDATE,PRACK,MESSAGE Content-Length: 0 Answer: no, the proxy is right. RFC 3261 says this about it.
nxclient / locale passing
So, I achieved victory on getting the compose key to work in the NX session. On to get a proper English language setting on our Terminal Server. The configuration suffers from two problems: (1) /etc/environment had values set (LANG=nl_NL.UTF-8 and LANGUAGE=nl_NL:nl). (2) nxssh does not pass the LANG/LC_* environment variables. If I were to remove the /etc/environment variables and configure everything like in a previous post of mine, everyone gets the POSIX locale (nxssh doesn’t pass anything).
altgr / nxclient / compose key
Like various reports on the internet suggest, the AltGr compose key doesn’t work properly or not at all from an NXClient connected to an NXServer (FreeNX in my case). Note that this is a different issue from the one where Alt_R (and Super_L, Super_R, Ctrl_R en Menu) remains pressed after which no normal typing is possible. That issue is described in Alt Gr keeps stuck and involves a new int sendKey = 0; in nxagent that should be reverted.
python2.6 features / python2.5
Today I’ll show you some quick and dirty python2.5 compatibility fixes. Of course you’re developing on python2.6 or even python3.x, but your customer still lives in the dark ages. Here are two fixes that might come in handy. ImportError: No module named ssl Falling back to python2.5 socket.SSL if there is no python2.6 ssl through a small wrap_socket replacement: import socket try: from ssl import wrap_socket except ImportError: class wrap_socket: def __init__(self, socket): self.
uninitialized globals / C language
As per the C language spec., uninitialized globals are initialized to zero (0). Nandu310 tells us why on his blog about the memory areas in the C language. Data segment: the data segment is to hold the value of those variables that need to be available throughout the life time of the program. […] There are two parts in this segment. The initialized data segment and uninitialized data segment. When variables are initialized to some value (other than 0 or which is different value), they are allocated in the initialized segment (.
unexpanded tabs / mercurial web / diff
The hgweb mercurial web interface on current Debian/Squeeze (mercurial-common 1.5.1-2) lists tab characters as-is in the diff view. Every line is prefixed not only by a plus or a minus (unified diff), but also by file and line numbers. This can cause a tab (0x9) character to appear as a single space. This does not look nice. The following patch can be applied to expand the tab character so the intentation looks right again.
mysql utf8 collation / conversion
On a clean MySQL install — on a Debian or Ubuntu system at least — the MySQL server gets the latin1_swedish_ci with latin1 character set by default. Every time you set up a new machine, you must remember to either fix the defaults in my.cnf config file or to supply character set and collation options when creating databases. Of course you’ll opt to set this by default in my.cnf first: