poker.png

Don't you want to know what kind of TV it was? How about what floor it was on? This is important information to track!

Periodically while studying some aspect or other of linguistics, I come across factoids regarding the etymology of a word or phrase. While they're not usually of any great significance, I think they're fascinating.

The word 'cattle' comes from the Old French chattels referring to all things a person owns.

'Spree' comes from a Scottish word meaning "cattle raid".

'Eulogy' originated in Ancient Greek. The original meaning was 'good word'.

The Gaelic word for 'war cry' was 'slogan'.

During a British military operation in India, the city of Sind was under siege. A message was sent from headquarters to the general leading the attack asking how the battle was going. His response was a single Latin word; Peccavi. The translation is "I have sinned".

If you've got any you'd like to share, be all means do so.

It's well and widely known that languages evolve over time. Sometimes they change if words fall into disuse ('haberdasher' in English), a word takes on a new meaning (historically, the Arabic word for 'house' meant 'tent'), proximity to another culture (the British Isles being repeatedly overrun helped produce English as we know it today) or sometimes for no clear reason at all (the so-called Great Vowel Shift responsible for the English 'burning' versus the German 'brennend').

Periodically though, pronunciations will change simply because they're easier to say. Euphonic assimilation is responsible for 'goodog' as opposed to 'good dog' in English, but sometimes the change will actually alter a letter. Eventually it may be accepted as the common spelling. Typically though it seems to be confined to 'classes' of letters. A 't' may evolve into a 'd' for example, as they are both 'dental' letters, produced through a similar process involving the speech organs.

While listening to the song 'Vergissmeinnicht' by Eisbrecher recently, it dawned on me that 'vergissmeinnicht' meant 'forget-me-not' ('eisbrecher' incidentally, means 'ice breaker'). It's a fairly obvious conclusion even if one (such as myself) doesn't speak German.

F and V are both labiodental fricative (I've also seen them referred to as 'plosive') letters. The difference between the two of them being that V is voiced and F is not. It's easy to see how over time one letter could gradually be replaced by the other. The major limiting factor as I see it in English is that there are English words that already are 'place holders', prohibiting some changes from taking place. 'Very' would have a hard time becoming 'fery' as 'fairy' and 'ferry' already exist. Not that it's impossible, but it would seem to me to be easier to transition if there were no sound collection already existing.

Language is a very time-sensitive subject. Some researchers think that spoken language evolved out of a need to warn others in the pack about impending dangers. Clearly there's an advantage to being able to warn others quickly. As such, it makes sense that spoken language would, like electrons in an atom, seek a 'low-energy' state where the least amount of energy was exerted to communicate the message.

This implies perhaps that some transliterations are more likely to happen than others. A Z is more likely to evolve into an S than vice versa as an S is easier to say. Hence the name 'euphonic'.

Anyway, it seems that an F is a more 'natural' letter than a V as a voiced letter should always require more effort than it's unvoiced alternative. Since the English equivalent of vergissmeinnicht starts with an F, it seems to suggest that perhaps the original shared root started with an F which was the sounds maintained by English. The questions then arises as to why a language would intentionally adopt a sound that requires more effort? The alternative is that the original root contained a V sound and while English has settled on an F German maintains the original sound.

The second syllable consonant, G, is shared by both languages.

The puzzle for me is the third syllable. English uses a palatal T sound whereas German has an unvoiced sibilant (or palatoalveolar fricative). The sister letter of T is D and that of S, Z. Were German to use a D here or English a Z the resemblance would be clear but I'm at a loss to explain why we're left with the two sounds we have. It's possible I suppose that S evolved out of a now lost palatal sound similar to an open 'sh' sound.

Looking at the two sounds we have to work with, the S seems to me to be the winner in terms of ease of pronunciation. Could it be that in the ages before Germanic split into upper and lower Germanic the root was *FGS (for those of you playing along at home, the * indicates a supposition or uncertainty)? I'd love to know. If an email was sent out detailing this at some point, I didn't get it so please forward it to me.

As for the rest of the word, 'mein' is a fairly commonly known German word, as is 'nicht'. Being the semi-agglutinative language German is, they all get slammed together. I guess we English speakers prefer hyphens.

Since I spent so much time on it, here's a chunk of the song that spawned this whole diatribe:

Verzeih mir - bleib bei mir
und ich sagte noch Vergissmeinnicht
Ich schenk dir zum Abschied
ein letztes Licht
Vergissmeinnicht

Translation:
Forgive me - stay with me
and I still said forget-me-not
I'll give you as a goodbye
one last light
Forget-me-not

Cisco Alert

| | Comments (2)

For those of you playing along at home who also have to have an ASA running 8.0 or 8.1 code, pay attention. The rest of you, go about your business. Move along, nothing to see here...

Cisco recently announced that a flaw exists in ASA 8.0 and 8.1 code that can force the device to reload itself if a specially-formed HTTP packet passes through it if SSL VPN is being used. There are a couple of other conditions, but from what I've read they're all pretty non-standard configurations.

The moral of the story - keep your code up to date.

There's also a paper being released at Black Hat Europe next week that will supposedly reveal a fundamental flaw in BGP and MPLS of a comparable seriousness to Kaminsky's DNS exploit of several months ago. So all those of you who run BGP (yeah yeah I know, no one who runs BGP is going to be reading the blog of little old me), heads up.

While digging through some old files, I found these two functions I had written during my fiddlings with the Nginx web server.  At the time at least, there weren't Nginx equivalents of the a2ensite and a2dissite commands used to enable and disable sites in Apache. 

Since I can't remember if I posted them already (and I'm a bit to busy to check right now) I thought I'd post them again just to be sure.  Usage of these functions blah blah I take no responsibility blah at your own risk blah blah created in a factory that processes tree nuts.

# Enables a site used by nginx
function nginable
(
  if [ $# -lt 4 ]; then
    echo "Usage: nginable -s|--source source_config_file -n|--name site_name [-r|--restart]"
    echo "-s|--source The config file defining the site"
    echo "-n|--name The name to appear in the sites-enabled directory"
    echo "-r|--restart Include to restart nginx after the site has been enabled"
   return 0
  fi

  if [ $1 = "--help" ]; then
    echo "Enables a site used by nginx"  
    echo 'Usage: nginable -s|--source source_config_file -n|--name site_name [-r|--restart]'
    echo 'Ex: nginable --source ./site_config --name nginx_tutorial --restart'
    echo "  If no pathing information is given, the config file"
    echo "  is assumed to exist in /etc/nginx/sites-available."
    return 0
  fi

  args=`getopt :s:n:r $*`

  for i
    do
      case "$i" in
        -s|--source) shift;SOURCE=$1;shift;;
        -n|--name) shift;NAME=$1;shift;;
        -r|--restart) RESTART=1;;
      esac
    done

  SITESENABLED=/etc/nginx/sites-enabled
  SITESAVAIL=/etc/nginx/sites-available

  # See if nginx is running
  PROC=`pgrep -c nginx`
 
  if [ $PROC -gt 1 ]; then
    NGINXON=1
  else
    echo 'Nginx does not appear to be running...'
  fi
 
  # Check for target directory
  if [ ! -d $SITESENABLED ]; then
    echo "[ERROR] Can't find sites-enabled directory"
    return 1
  fi

  # Check for config file
  if [ -f $SITESAVAIL/$SOURCE ]; then
    SOURCE=$SITESAVAIL/$SOURCE
    echo "Site detected - $SOURCE"
  elif [ ! -f $SOURCE ]; then
    echo "[ERROR] Can't find config file $SOURCE"
    return 2
  fi

  # See if a site by that name already exists
  if [ -f $SITESENABLED/$NAME ]; then
    echo "A site called $NAME already exists in $SITESENABLED"
    return 3
  fi

  # Enable site
  ln --target-directory=$SITESENABLED --symbolic $SOURCE

  # See if restart was called for and check syntax
  if [ $RESTART ]; then
    if [ $NGINXON ]; then
      /etc/init.d/nginx stop
    fi

    /etc/nginx -t
    
    if [ ! $? -eq 0 ]; then
        echo "[ERROR] Errors found in config files"
        echo "        Disabling new site..."
        rm $SITESENABLED/$NAME

        if [ ${NGINXON} ]; then
          /etc/init.d/nginx start
          echo "Restarting nginx..."
        fi

        return 4
    fi
    
    if [ ${NGINXON} ]; then
      /etc/init.d/nginx start
      return 0
    fi

    echo "Site $NAME enabled"
    return 0
  fi
)

# Disables a site used by nginx
function nginoff
(
  if [ $1 = '--help' || $1 = '-h' || $# -lt 2 ]; then
    echo "Disables a site used by nginx"
    echo "Usage: nginoff -n|--name site_name [-r|--restart]"
    echo "Ex: nginoff --name nginx_tutorial --restart"
    return 0
  fi
 
  SITESENABLED=/etc/nginx/sites-enabled

  # See if nginx is running
  PROC=`pgrep -c nginx`
 
  if [ $PROC -gt 1 ]; then
    NGINXON=1
  else
    echo 'Nginx does not appear to be running...'
  fi

  args=`getopt :n:r $*`

  for i
    do
      case "$i" in
        -n|--name)shift;NAME=$1;shift;;
        -r|--restart)shift;RESTART=1;;
      esac
    done

  if [ ${NGINXON} && ! ${RESTART} ]; then
    echo "[WARNING] If nginx is not restarted, site errors may occur"
  fi
 
  if [ ! -f $SITESENABLED/$NAME ]; then
    echo "[ERROR] Can't find an enabled site called $NAME"
    return 1
  fi

  rm $SITESENABLED/$NAME

  echo "Site $NAME disabled"

  if [ ${RESTART} ]; then
    if [ ${NGINXON} ]; then
      /etc/init.d/nginx stop
      /etc/init.d/nginx start
    fi
  fi

  return 0
)

A break from the norm

| | Comments (4)

While this isn't a post directly related to my latest random technological fiddlings, I still feel it's important to raise here.

A bill is making it's way through the United States Senate spear-headed by West Virginia Democratic Sen. John Rockefeller, the head of the Senate Committee on Commerce, Science, and Transportation, and Sen. Olympia Snowe, a Republican. This piece of legislation would, in effect, give the president the authority to shut down any network in the U.S. they so chose. The bill dresses all this in a nice suit of "Oh wait, only for national security reasons".

What's scary is that what exactly constitutes a national security concern has always been somewhat ill-defined. During the 1960s, any organization that spoke against the government could be monitored under exactly that same justification. During the McCarthy era, countless individuals, organizations, and businesses were monitored and sometime hauled in front of congress to answer questions about their political beliefs, often at the expense of common sense and decency.

The idea that these individuals might have communist leanings was all the justification that was needed to declare them a potential threat to national security and all by kill them.

As more and more bits of information (well, there's Rush Limbaugh, too) are being placed at the fingertips of the world, this becomes a more sweeping proposal with each passing second. The internet has grown and evolved in a way no one could possibly have predicted and simply switching it off would be chopping off the national arm.

The bill doesn't simply stop at essentially switching off the U.S. edge devices though. It would give the president the ability to also power down private networks and dictate how those systems are configured. As is well and widely known, the open source movement is a critical part of the internet, from a security standpoint as well as from one of it's overall development. I for one, am none too keen on the idea of a body of officials (one of whom famously once described the internet as 'a series of tubes') dictating to me how I can and can't configure the router sitting on the floor of my room.

One of the bill's provisions is to create a licensing requirement for people who want to work in computer security. There are driver's licenses, and I still got rear-ended by someone who didn't know (by her own admission) that she didn't know that wet surfaces increased breaking distance. Creating a certification could be a beneficial bullet on anyone's resume, but having a mandatory license will have the same effect that teaching anything else seems to; directing people to one way of thinking and academically punishing you for not learning something precisely the way it's taught.

The danger also lies in that a license is bound to make people think they know what they're talking about. We all know that there are plenty of idiots out there with college degrees, and I seriously doubt that the Senators have a four-year study program in mind; best-case scenario, it turns out exactly the same type of people.

Imagine the security products vendors could sell with "U.S. Government Approved!" stickers on the box. Creating a mandatory license will only serve to give credence to the voice of people just studious enough to pass it and in the eyes of those who recognize that, diminish the value of the license of the people who are competent.

One of the most effective ways to learn something is to be burned by NOT knowing it at a key moment, and that's how a lot of people know a lot of things. As some of you may know, I spent about eight years in the United States Marine Corps (and no, I don't feel that makes me inherently a bad-ass); there's a apropos expression: "No combat-ready unit has ever passed inspection and no inspection-ready unit has ever passed combat". There is no way that training can compensate for experience.

After graduating from an intensive Arabic language program, I rapidly found out that what I knew was perfect for a laboratory situation, but completely unsuited for something as simple as a coffee shop.

The first thing to learn is how to learn what you need to forget.

The Rockefeller/Snowe bill, quite simply, must not be allowed to pass.

links.gif

...and for security reasons, I won't write a blog entry about it.

In other news, I'm now working in our office in Austin so I've moved there as well. As part of setting up my internet connection, I decided to force myself to learn how to configure the wireless functionality on my Cisco 1801. It turns out it's actually pretty easy:

interface Dot11Radio0
description 192.168.100.0/24_Wireless
ip address 192.168.100.2 255.255.255.0
!
ssid fieryweasel <-- also my Twitter account
!
speed basic-54.0
station-role root
no routing dynamic
!
dot11 ssid fieryweasel
authentication open
guest-mode
infrastructure-ssid

Looking at the wireless traffic with a protocol analyzer, I kept seeing the 'hello' packets used by the Cisco discovery protocol - I had forgotten to enter "no cdp enable", but after that it cleaned up nicely. There's currently no authentication in place, but since the only thing the router is presently connected to is my ASA, I'm in no rush. Perhaps I'll get more in-depth about the configuration options in a later entry. If there's anything else Cisco-related that anyone's curious about, let me know. Chances are I don't know it but it would be a good way to learn.

I've been reading a number of books recently dealing with how various languages were discovered, analyzed, and translated in the past. If the language itself is unknown, the key has almost always been what's referred to as a 'bilingual', some text of sufficient length written in at least one known language as well as the unknown.

The most famous example of this is of course the 1,700-lb Rosetta stone, with the same text in Greek, demotic, and Egyptian hieroglyphs. The Rosetta stone allowed Champollion (arguably) to finish deciphering the hieroglyphic language by means of comparing proper names in the Greek and attempting to find the equivalent hieroglyphs.

I started thinking about how various languages might be deciphered in a distant future when humans were long gone. It occurred to me that about the only real stone inscriptions in any quantity are those that appear on grave stones, and the length of each inscription consists almost entirely of names and numbers if not exclusively. Granted, there are also some monument inscriptions and thing of that nature.

As more and more things become electronic and internet-bound, it may appear to some future civilization that at some point we just stopped writing. But what about plastics? An increasing number of things are plastic, and it's well-known that plastics last a ridiculously long time before finally decomposing. Something as simple as Coke bottles discovered in the landfills of various nations may someday allow many human languages to be unraveled. It's an odd thought that our garbage may be the only real clue to our civilizations.

Tkinter

| | Comments (0)
As part of my continuing effort to hate Python less, I decided to do some fiddling with the Python Tkinter library.  For those of you playing along at home, it's a series of libraries (or whatever Python calls them) for performing Tk/Tcl tasks.  

I've never done GUI coding before.  Up to this point, all my code's execution space was limited to browsers and the occasional CLI tool.  Like one would expect from an object-oriented language, the GUI behaves in much the same fashion, with 'widgets' as they are called (a button, a menu, text field, etc.) descend from a root frame.

from Tkinter import *  # Get the library

class App:

    # Draw GUI and init
    def __init__(self, master):

        # Parent frame
        frame = Frame(master)

        # The pack() method returns an object of type None so Frame(master).pack() will only work if you don't want to reference 'frame' again.
        frame.pack()
   
        # Labels are simply output areas
        self.display_text = Label(frame,text="")
   
        # side=TOP - Sets the widget's placement
        # TOP, BOTTOM, LEFT, and RIGHT are constants set by Tk
        self.display_text.pack(side=TOP)

        # Create a button
        # Args:
        #  frame - Set 'frame' as the parent of the button
        #  text - an attribute setting the text on the button
        #  command - the callback which will fire when the button is clicked.
        self.button = Button(frame, text="This is a button", command=self.a_method)
        self.button.pack(side=LEFT)

    # A callback method
    def a_method(self):
   
        # the config() (or configure() ) method is used to modify widget options
        self.display_text.config(text="Button pressed")

#Yet another thing I hate about Python - if the next four lines are at the top of the file, this doesn't work.
root = Tk() #Instantiate the root widget
root.title('Test App')  # ...and give the window a title
app = App(root)  #Instantiate the App class, which contains all the logic
root.mainloop() # Start the event handling loop

Much like in CSS, object placement seems to get exponentially more troublesome as the number of objects grow. 

While so far the only thing I've done with this is write a utility for work (and thereby getting some more practice with Python's xmlrpclib methods) I think I'll definitely have to keep messing around with this.

Play around with it a bit and let me know what you end up creating!

Python *sigh*

| | Comments (0)

After years of dislike, I may have to admit that I'm not entirely filled with hatred for Python. This did not come voluntarily, mind you. My love of laziness naturally breeds a lot of small projects; why repeat a task over and over when I can code something once and not have to think about it again?

My love of laziness was thrilled when I introduced it to web services some years ago. Now there was a place for my apathetic side as well - why bother learning what over people have coded, when all I have to do it point my code to a web service (ReST was a natural choice *rimshot*)?

A situation arose where there only real way to get something done without reinventing the wheel (avoiding a joke about things being chowned and chgrped to 'wheel') was to consume a web service. Finding a chunk of code where the consumption was already written was easy, but it happened to be in Python. I swallowed hard and decided to use it anyway, creating a Frankensteinian script wherein PHP passed arguments to a Python script which made the web service call and passed the results to a Ruby script (I never managed to work in Erlang).

As the benefit of that particular script became apparent, I made use of the Python section again and again. I finally realized that it was impossible to do any sort of sane version control since there were at least three script files to be updated per 'script'.

On one particularly slow day I decided to try to rewrite one of the aging scripts in pure Python. It worked and was a lot cleaner. I've written some subsequent scripts in pure Python as well, and a lot of my dislikes remain:

  • I hate converting every single number to a string before concatenating it to another string
  • Python, your implementation of lists is hideous
  • I don't want to have to track eleventy billion import statements
  • The whitespace is just annoying. I know how to write clean-looking code. Sometimes I just don't want to.
  • Get a damn case command. Virtually every other language in common use has one.
  • As I've said before: Twisted Python (which admittedly is not part of the Python core) tries way too hard to behave like Erlang. Just learn Erlang and be done with it.
  • String manipulation is the most counter-intuitive crap I've ever seen. x86 assembly makes more sense

That being said, it's just possible that perhaps Python isn't quite as evil as I once thought. Python, at least you're not Java.