Sunday, June 26, 2016

an open letter to my assignment group


I'm having a very frustrating time this week editing this work. I feel that the content is not quite there in terms of satisfying the assignment requirements, and I'm having a lot of difficulty making sense of a lot of the input you've given me. I've asked for clarifications in many of the comments but the responses, as a rule, haven't been clear. I'm trying to rewrite what I can, fill in the gaps where I can, and preserve y'all's intent of meaning where I can discern it, but it's very difficult to discern in a lot of cases. This makes it next to impossible to provide clarity to those who will be reading, and grading, our paper.

This is mainly meant as fair warning that I doubt our grade will be all that great on this assignment.

I am struggling to pull this paper together even to the level that I was able to do for the last paper (which, frankly, was well below normally-acceptable standards, in my opinion). In order to rewrite this to the level of acceptability that we were able to achieve even in that assignment, I would have to spend another full day on this reading the sources given to square them with the citations and to make sense of everything and pull it all together into a cohesive document that satisfies the assignment criteria.

I'm disinclined to say anything further that could be taken personally, but I do mean to convey that I have not yet seen the quality of writing so far from this group that is normally acceptable at an undergraduate level, let alone in grad school. The main reason I volunteered to edit the papers for the group is that I am a good writer and editor, and a better critic. Perhaps most to the point, however, it truly pains me to turn in mediocre-to-lousy writing.

I realize I have probably burned three bridges at once with this; however, I feel strongly that this is important enough to take that risk: in all sincerity, PLEASE, each of you needs to step up your writing game. I am asking not only for my sake and the sake of my grade, but also for the sake of your own academic and professional careers, and to honor the value of the degree we're all working to achieve.

Friday, May 13, 2016

Asterisk and SELinux – and allowing additional Asterisk CLI users

Most advice on Asterisk that you'll find out in the ether states that to get Asterisk working right, you'll need to disable SELinux. Sometimes you'll even see vendor engineers repeating this over official channels.

IMO this is stupid and wrong. Disabling security is a terrible approach to fixing problems generally, – but particularly so when the real issue is more than likely a config problem.

Enough ranting though – I came to post about the resolution to just such a config problem.

Systemd config

After building a basic install of Asterisk 13.8 Certified on CentOS 7.2, I wasn't satisfied to run the included sysvinit script for startup when the entire balance of the system was initializing through systemd. I found that /var/run/asterisk wouldn't cooperate with my initial attempts at writing a systemd script – after every reboot, it came back owned by root; ownership changes wouldn't stick. I learned from Jari Turkia[1] this is due to /var/run being a tmpfs – nothing there persists across reboot.

Jari used /usr/bin/mkdir, suppressing errors, and /usr/bin/chown, but it's possible to do the same thing elegantly in a single line using /bin/install – a handy trick I picked up from Paul.[2]

With that and other help [3],[4],[5], I was able to dial in a very nicely working systemd script to control my Asterisk installation. The config is after the jump.

Asterisk config

After sorting the directory ownership and permissions, I also learned that I could allow additional users (e.g., my own login account) to use the Asterisk CLI without having to use sudo – there are a couple of config items that have to be changed to let this happen:
  1. In /etc/asterisk/asterisk.conf, uncomment [files] stanza and its entry astctlpermissions[6]
    • This changes the permissions on the /var/run/asterisk/asterisk.ctl socket node – necessary because a CLI user needs write access to the socket
  2. In /etc/asterisk/cli_permissions.conf, add an entry for the user or group you want to give permissions, along with the appropriate permissions.[7]
    • Since I'm my only user, I set group wheel to have all rights, but you may need something more strict.

Wednesday, January 16, 2013

Router Breaks SIP? Work Around It.

Recently I had the misfortune of dealing with a Cisco WRVS4400N router in a medium-sized business environment. It worked fine for almost everything, but as it turns out, an external SIP client (Aastra phone in this case) was not among the working. No matter what I tried, I couldn't get traffic to come to the Asterisk PBX behind the router on UDP 5060 from the internet, neither from that phone, nor other devices on its network, nor from other phones and other networks. Apparently the router simply couldn't properly handle packets coming to UDP 5060.

As it turned out, this router is known for giving trouble with SIP; the older version of the firmware had SIP ALG built in, but it couldn't even be disabled! Apparently the new version has the option to toggle SIP ALG off, but it still doesn't work for whatever reason.

This post isn't about that particular router model, though. Sadly, this is far from the only equipment out there that plays havoc with what one should expect to be a run-of-the-mill remote phone implementation. Fortunately, there's a relatively easy workaround you can use, and I think it's fairly elegant, if a bit hackish.

First, I should cover what I tried and failed at, because it would be easy for anyone without an in-depth understanding of the SIP protocol to make the same mistake.

SIP is notorious for NAT traversal problems, and there are a variety of solutions out there that can be had, from SIP proxies to STUN servers to SIP ALG. I'm not covering those here, but I'm touching on them because the problems are due to a peculiarity of the SIP protocol -- the contents, not the metadata, of SIP messages describe how a connection should be set up. So if something about the connection, be it port or IP address, changes when traversing NAT, then the message itself has to contain information about those changes. The tools I mentioned above take one approach or another to modify how the messages traverse NAT, or they simply rewrite the message contents to align with the differences in the network. I wanted to avoid implementing any new software solutions in this particular situation, though.

I initially tried to set the phone up to use a different UDP port, then forward that port at the router to 5060 on the Asterisk box. This SORT OF worked... the phone was able to register and calls would even go through ... but only for 20 seconds until the connection timed out. This happened because the Asterisk machine was still sending out packets telling the phone to use port 5060 (instead of my substitute port), and when the phone responded on port 5060, the packets couldn't make it to the PBX; it was the same problem I started with. Using 5060 just wasn't an option, and I realized I would need to use some other port altogether.

Ultimately, I set the Asterisk instance to use a randomly-selected, high-numbered UDP port using the bindport directive in sip.conf (In FreePBX, you'll find this setting in the "Asterisk SIP Settings" section under the Tools tab):
(Of course, Asterisk has to be reloaded or restarted after a change like this). Then, on the router, I forwarded incoming traffic on that UDP port directly to the Asterisk server on the same port.

Of course, the already-installed phones on the local network (not traversing the brain-dead router) were still configured to use 5060, and that couldn't work anymore, because Asterisk was no longer listening on 5060. I considered changing the configuration on all those phones, but I realized it was going to be a huge pain to do for 20 or more devices. Since that's the default setting for SIP phones, it's also much easier not to have to change it on any new phones either!

So I didn't. Instead, I set up an IPtables rule on the Asterisk machine to forward incoming traffic on UDP 5060 to the new port, like this:
iptables -A PREROUTING -t nat -i eth0 -p udp --dport 5060 -j REDIRECT --to-port 47320
You'll need to adjust the interface definition (-i eth0) and port number (--to-port 47320) according to your configuration.

This command can be added to an existing IPtables configuration to run automatically on boot (/etc/init.d/iptables, e.g.), or it can be set up as a standalone one-liner by adding it to the /etc/rc.local, /etc/inittab, or some other init script.

So if you have a router giving you fits over SIP traversal, the "correct" solution is probably to replace the router with something that doesn't break standard protocols. But the "right" solution for you might be to take the simple steps I've outlined here.

Let me know if you have any questions!

Wednesday, May 25, 2011

Cock Sparrer - Trouble on the Terraces - lyrics

I couldn't find 'em anywhere with Google, so I transcribed the lyrics from Cock Sparrer's "Trouble on the Terraces"  it's been a favorite of mine for many years.

For those not in the know, it's basically about football violence/soccer hooliganism/fun times - I think there is a documentary by the same name, about the same thing, but I haven't seen it and I don't know if it's related otherwise.

Here's a youtube posting that has the audio if you're interested:

Anyway, without further ado, the lyrics:

You say you want the authorities to take action
But I don't believe you're genuinely concerned
You say you want the terraces to be closed down
But your son is one of us, so when will you learn?

Adrenaline's running high, and most got nothing to fear
It's all part of the game; it adds to the atmosphere
We got trouble on the terraces, on the terraces, on the terraces

Next time you see me running on the pitch
Don't forget I'm just the same as you
It's a split second gut reaction that is happening to me
It ain't 'cause I've got nothing else to do

Adrenaline's running high, and most got nothing to fear
It's all part of the game; it adds to the atmosphere
We got trouble on the terraces, on the terraces, on the terraces

We got trouble, riots, aggro, now

Tuesday, March 29, 2011

Perl script to concatenate PDF files

I hammered this together a few minutes ago because I find I often need something like this. It's a perl script that concatenates PDF files from the command line. It could be adapted pretty easily for web form input or a gui app if you wanted to badly enough.

The only prerequisites I know of are Perl and Ghostscript which should be found on virtually any modern unix-type system and possibly some Windows ones too.

I don't intend to offer support per se but let me know if you have any questions.



Releasing under GPLv3

#!/usr/bin/perl -w
# ^^ change path if necessary

# a script to concatenate PDF files. just give it PDF files as arguments, in the
# order you want them concatenated.
# cobbled together from the 'gs' command line example found at

# NOTE: I have not tested this with any other papersize than letter!
# it does handle portrait/landscape without fuss however.

use strict;

my $cmdstr='gs -q -sPAPERSIZE=letter -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=output.pdf';
my $cmdargs='';

my @infiles = @ARGV;

if (scalar(@infiles)> 0){
  foreach my $file (@infiles) {
    $cmdargs .= " $file";

  exec $cmdstr . $cmdargs;
} else {
  print "Syntax: $0 [input PDF file 1] ... [input PDF file n]\n";

Saturday, August 28, 2010

I wrote a program today to organize photos. I have a great number of photos from over the years; they were mostly organized at some time in the past, but got copied wholesale to new hard drives when it was time to migrate, or got stowed in a tarball somewhere, etc... anyway this program i wrote (in perl) will, given a source directory and a target directory, iterate through the source directory finding files matching a given file type (in this version, jpg and cr2, but that can change), extract the creation date from the file's EXIF data, create a directory tree (as needed) under the target path as year/month/day and either move or copy the file into that directory. I'm going to post the code now, but it's not totally mature and it's not yet commented at all. have a gander if you like. I intend to improve this in the future but no promises are made. also i guarantee it not to bug-free.

I'm releasing this under the GPL, v3 which can be found at

#!/usr/bin/perl -w -- call this version 0.01

use strict;
use File::List;
use File::Copy;
use File::Path;
use Image::ExifTool;
use File::Basename;

my $basedir = "put path to source here";
my $target = "put path to target here";
my $i = 0;

my $search = new File::List("$basedir");
my $fileArrRef = $search->find("JPG\$|jpg\$|cr2\$|CR2\$");

sub pathbuild {
    my $newpath = $_[0];
    if (! -d $newpath) {
        if ( -e $newpath ) {
    return $!;

my $dtOrig;my $date;my $time;my $yr;my $mo;my $day;
foreach my $fullname (@$fileArrRef) {
    my $info = Image::ExifTool::ImageInfo($fullname);
    if ($$info{DateTimeOriginal}) {
        $dtOrig = $$info{DateTimeOriginal};
        ($date,$time) = split( / /, $dtOrig);
        ($yr,$mo,$day) = split(/:/, $date);
    } else {
        $dtOrig = '';
    my ($name,$path,$ext) = File::Basename::fileparse($fullname,qr/jpg|cr2/i);
    my $dest = "$target/undated";
    if ($dtOrig) {
        $dest = "$target/$yr/$mo/$day"

    my $destfile = "$dest/$name$ext";
    $i = 0;
    while (-e $destfile){
        $destfile = "$dest/$name$i.$ext";
    if (link ($fullname,$destfile)){
        unlink ($fullname);
    } else {
        copy ($fullname,$destfile);

Monday, May 24, 2010

Trivial? Not sure, but it's trivia in any case.

Announcing a Trivia Challenge, with a Prize:

There's something very interesting about the subject of the photo in this link. See if you figure out what it is, and why it's like that.

The first ten people to flickr-mail or email me with
[1] the interesting fact about the subject of the photo
[2] the specifics of why that fact is the case
Will receive an 8x10 print (or similar size, exact dimension depends on photo dimension) of any of my work on flickr of your choosing (excluding low-res work and photos of people).

This is open to everyone, and no information sources are off-limits (but do your own research please).



PS - tell your friends to check it out, because the photo's been viewed over 200 times but I've only gotten one right answer!!