Latest Entries »

I decided to pull my old P4 box out of retirement to give FreeBSD 9 a try. For the most part, things are as I remember, however FreeBSD 9′s default Xorg uses HAL to manage all the devices, including the keyboard and mouse. What this means, as far as making X feel like “home”, is that I can no longer make my usual xorg.conf edits to replace Caps Lock (which is useless) with another Ctrl.  I have been using my keyboard with the Caps Lock key as a Ctrl for so long that it causes so much frustration even after a few minutes, so it’s usually one of the first things that changes. When I start using a new desktop.

My main computer is a Mac, and I was an early Lion adopter. At first, I didn’t like the “natural scrolling”, so I disabled it. I hated the idea of having to reset all the defaults every time I used a new Mac though, so I decided to give it another try. Eventually it really grew on me! So much so, that sitting at my FreeBSD desktop I would try to scroll up or down and get frustrated that everything felt backwards. I decided that in addition to my additional Ctrl key, I’d have to get the scrolling to reverse also.  Luckily, both of these changes are trivial, once you know what information to look for and what file to create and/or edit.

I won’t get into the entire story of how I ended up compiling every application on my system from ports – the short version of the story is that I installed vim and basically it installed X along with a million other things (that I knew I was going to use anyway).  If you don’t want that to happen you can avoid it by setting the WITHOUT_X11 variable.  That’s no different from earlier FreeBSD versions though, whereas this hald configuration stuff did throw me for a loop at first.  In any event, once I got Xorg and HAL (and dbus, etc) installed, I had to create an fdi file in /usr/local/etc/hal/fdi/policy/ which holds the configuration details. I don’t think the name of the file matters too much, I honestly stopped researching once I got the configuration working the way I wanted. Here’s my x11-input.fdi:

File Named: /usr/local/etc/hal/fdi/policy/x11-input.fdi
--
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.capabilities" contains="input.keyboard">
      <merge key="input.xkb.Options" type="string">ctrl:nocaps</merge>
    </match>
    <match key="info.product" string="USB Receiver">
      <merge key="input.x11_options.ZAxisMapping" type="string">5 4</merge>
    </match>
  </device>
</deviceinfo>

If you’re like me, you’ll want to just copy and paste this file, save it, and move on with life. Don’t do that (yet!). There are a few things you’ll need to know before you can roll with this as is. First – you’ll notice that my encoding is UTF-8. This is extremely important to take note of. If your system is not using UTF-8, this will not work.  It might seem obvious, but when I first found an fdi file and tried to do the old copypasta in/out in/out I got nothing for my trouble! That’s because the encoding was ISO-8859-1 and on my system it needed to be UTF-8. Get to know your system’s encoding.

Again, in the interest of full disclosure – there is more research to be done with regards to what exactly every piece of info in this file means – I didn’t look it all up because it started working.  I say this now because you’ll see the deviceinfo version atrribute is set to “0.2″ and you might be wondering “why?” Well, I don’t know why. I’ve seen some 0.1 and some 0.2 – 0.2 sounded more recent, and so I am using it, and it works. I’ll look it up later ;)

Moving on in the file, you see one pair of device tags which have 2 children “match” tags.  This confused me at first – I thought I needed a set of device tags for each device.  As it turns out, one set is enough – the match tags inside actually are the most specific you need to get as far as “per device” configuration. The match tags essentially allow you to specify a key and value to search for, such that the merge tags within will apply the actual configuration to the device that’s “matched”. Makes sense right? You can apply the configuration to multiple devices my having a more generic match definition, or apply the config to one device only by matching for a more specific value for a given key.  At this point you’re probably wondering what exactly is being matched. Enter hal-device.

HAL gives you a command line tool named hal-device, which will tell you all sorts of information about the devices on your system. I recommend that when you run it you try piping it into a pager like less, or filtering the output with grep, because it’s going to be a lot of info. The hal-device command spits out the device info in a key/value format. If you run the following, you should see some information about your keyboard:

hal-device |grep -7 keyboard

The -7 gives you 7 lines of context surrounding each instance of the text “keyboard”. On my system the output look like this:

 usb.interface.description = ''  (string)
  usb.freebsd.devname = 'ukbd0'  (string)
  freebsd.driver = 'ukbd'  (string)
  freebsd.unit = 0  (0x0)  (int)
  input.device = ''  (string)
  info.subsystem = 'usb'  (string)
  info.product = 'Logitech USB Keyboard'  (string)
  info.capabilities = { 'input', 'input.keyboard', 'input.keys', 'button' } (string list)
  info.addons.singleton = { 'hald-addon-input' } (string list)
  input.x11_driver = 'kbd'  (string)
  freebsd.device_file = '/dev/ukbd0'  (string)
  info.category = 'input'  (string)
  info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_c315_noserial_if0'  (string)
  input.xkb.Options = 'ctrl:nocaps'  (string)
  info.bus = 'usb'  (string)
--

46: udi = '/org/freedesktop/Hal/devices/atkbd_0'
  freebsd.driver = 'atkbd'  (string)
  freebsd.unit = 0  (0x0)  (int)
  platform.id = 'atkbd.0'  (string)
  freebsd.device_file = '/dev/atkbd0'  (string)
  info.category = 'input'  (string)
  info.capabilities = { 'input', 'input.keyboard', 'input.keys', 'button' } (string list)
  input.device = ''  (string)
  info.addons.singleton = { 'hald-addon-input' } (string list)
  input.x11_driver = 'kbd'  (string)
  input.xkb.Options = 'ctrl:nocaps'  (string)
  info.udi = '/org/freedesktop/Hal/devices/atkbd_0'  (string)
  info.parent = '/org/freedesktop/Hal/devices/atkbdc_0'  (string)
  info.product = 'AT Keyboard'  (string)

Now that you see that, look above at the fdi file again. You’ll see how the XML format lends itself to this rather well – you can read it almost as English:

"match [the] key [named] info.capabilities [if it] contains [the value] input.keyboard".

Got it? Great. The merge tag then becomes a sort of command that says “set the value of the key named input.xkb.Options, which happens to be a type of string, to the value ctrl:nocaps”. Not so complicated right?
It gets a little trickier with the mouse, mostly because you may not realize that the mouse wheel scrolls along the Z axis.  To me, the Z axis represents layers on a web page, not mouse scrolling – but this is the way it’s referred to in X, and therefore in the HAL config files that deal with the X input devices.  You’ll also notice that the key I’m matching on is “info.product” – and I’m looking for “USB Receiver” – this is because for the particular wireless mouse I use (which happens to be USB, as you may have guessed), HAL lists the name as “USB Receiver”. Yours might not, in fact – it probably will not, be the same.  Use a command like:

% hal-device |grep -10 mouse
--
usb.level_number = 1  (0x1)  (int)
  usb.device_subclass = 0  (0x0)  (int)
  usb.device_protocol = 0  (0x0)  (int)
  usb.interface.class = 3  (0x3)  (int)
  usb.interface.subclass = 1  (0x1)  (int)
  usb.interface.protocol = 2  (0x2)  (int)
  usb.interface.description = ''  (string)
  usb.freebsd.devname = 'ums0'  (string)
  freebsd.driver = 'ums'  (string)
  freebsd.unit = 0  (0x0)  (int)
  input.device = '/dev/sysmouse'  (string)
  info.subsystem = 'usb'  (string)
  info.product = 'USB Receiver'  (string)
  info.capabilities = { 'input', 'input.mouse' } (string list)
  info.addons = { 'hald-addon-mouse-sysmouse' } (string list)
  input.x11_driver = 'mouse'  (string)
  freebsd.device_file = '/dev/ums0'  (string)
  info.category = 'input'  (string)
  info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_c51b_noserial_if0'  (string)
  input.x11_options.ZAxisMapping = '5 4'  (string)
  info.bus = 'usb'  (string)
  usb.interface.number = 0  (0x0)  (int)
  usb.is_self_powered = false  (bool)
  usb.can_wake_up = true  (bool)
  usb.max_power = 98  (0x62)  (int)
  info.parent = '/org/freedesktop/Hal/devices/usb_device_46d_c51b_noserial'  (string)

To find the details about your mouse.  As you can see, my configuration has been applied to that the “button” that is triggered when this mouse wheel is scrolled down (5) actually scrolls up, because it comes first, hence 4, the “up scroll button”, scrolls down. Also note – that if I were to plug in some other mouse, the configuration might not apply! This mouse configuration change only applies where info.product = “USB Receiver”. I could just as easily use info.capabilities and look for contains “input.mouse”, similar to how I matched the keyboard, thereby applying this switch to all mice on my system. This is just an example to show you that you can apply configurations my matching different keys.  One benefit of doing it this way is that if my wife were to sit at this workstation, she’d be confused by the mouse – but all she’d need to do is plug her own mouse in and it would have the default scroll directions.

And there you have it! I spent a few hours hunting down this info, hopefully it took you less time to find this blog post! Enjoy! :)

Took me a few hours to figure out that when I got:

“child exited with status 13 /usr/local/lib/python2.6/site-packages/Trac-0.11.5-py2.6.egg/trac/web/fcgi_frontend.py”

The problem was that I needed to chmod a+x /usr/local/lib/python2.6/site-packages/Trac-0.11.5-py2.6.egg/trac/web/fcgi_frontend.py

a+x might be a bit lenient, but it works now. When I rebuilt my ports the permissions changed to 644, which makes sense. Trac is back in working order now, although my fullblog plugin is acting up. Seems like a simple issue though…

DNS Oops

When we moved to a new apartment, I took my FreeBSD DNS server with us. We couldn’t get internet set up until today (about a month! – it was a nightmare) but I was using the DNS to ease our little network’s file and printer sharing. Even though we only have a few computers, it’s better to be able to refer to them by name. It took us about a month to get an internet connection, but I expected that once I configured the wireless router everything else should “just work” as it did before.

Well it almost worked out that way… seems I forgot to change the forwarders in my named.conf to reflect my new ISP’s DNS server. My local DNS server handles internal DNS requests for us and it also acts as a caching server to help speed things up. Without valid forwarders configured, each lookup for a URL that wasn’t already in the cache seemed to take forever! In fact, some lookups failed, and when I checked with nslookup, I would get “no servers can be found”. After looking around the net for a while, I decided to check named.conf one more time… and yeah… still had my old ISP’s DNS server listed in the forwarders section…

Zsh glob qualifiers ftw!

I have a FreeBSD 7.1 server, a couple of macs, a windows machine, and an ubuntu machine. I need to share files between them all. I could try to get NFS for windows working, but it seemed to me that using Samba was a good way for me to allow all of the machines (Even the windows one!) have access to the storage I have on my “server”. I’ve been working with BSD, Linux and Windows for a long time, and I still get emails to thank me for that old Linux From Scratch hint I wrote that describes how to set up printing with samba and cups. I thought this would be a cinch. Was it? Of course not haha. It turns out that even though my user had access to mount the share, I had mounted it in FreeBSD owned by user root, group wheel with permission set to 755. My user is in the wheel group and I would like the wheel group to have write permission, so I remounted it with the following line in /etc/fstab:

/dev/ad8s1  /mnt/sambashare msdosfs rw,large,-m=775,-g=wheel 0 0

the large is there because it’s a 500GB drive.

And now, all is well. I can mount the share and I have read write access! I can create and delete a test folder… so that’s it! Right? Wrong. There’s an old windows directory on there that I need to delete, but OS X says I haven’t got enough permission to do that. Oh no!

Well how am I supposed to go digging through some directory tree and find the files that I don’t have permission to delete? I bet there’s a unix command that can help me… (actually I know there is – it’s called find, and find is great…but… I love zsh and I love finding fun reasons to use its features!)  Since I know ls will list my files… and ls -al will tell me the permissions… why not just say “ls -al everything i dont have write permission to”?

ls -al *(^I)

The stuff that is between the parentheses is called a glob qualifier. Glob qualifiers let you ask zsh to give you back more specific information. In this case, the capital I means group writable files and the ^ is used to negate the qualifier. If you try to translate this command line into english it would say something like, “list the names and permissions of all of the files in the current directory, even the hidden ones, that are not group writable.”

You may be thinking, “Wait… did you say all files in the current directory?” and if you are thinking that – you’re right. The above command only lists the files in the current directory, so it is not very useful right now.  I need to look in my mounted drive, which is on /mnt/sambashare, so how about this command line?

ls -al /mnt/sambashare/*(^I)

That is close… but not quite there. It’s only showing files in that directory, and I need to look into all the directories that might be in there. Since all the files and directories in that directory are group writable, this gives me:

zsh: no match

So how can I tell ls to look into directories too? That’s easy! I can use the recursive globbing operator, **

Now the command line looks like this:

ls -al /mnt/sambashare/**(^I)

But that STILL doesn’t go all the way into directories I need it to. This is getting crazy now isn’t it? It turns out that to look into directories, even directories that are inside other directories, we cannot simply use the recursive globbing operator, we need to append a /* as well, which makes the command line:

ls -al /mnt/sambashare/**/*(^I)

But now… oh no! We’re still not there! This returned a list including some files that ARE group writable! Why don’t I just run chmod -R  and end this agony already? (Is that what you’re thinking? haha well the answer is… I want to know exactly what files I can’t delete before I take further action). It seems that the ls command is going into directories and showing me things I didn’t ask for. I have a hunch that it’s because ls is doing some recursion of its own… (don’t ask me why, it’s just a hunch) so I’m going to add the -d option to the ls command, making the command line….(drum roll please):

ls -ald /mnt/sambashare/**/*(^I)

….and my hunch was correct! So now I have my list of all files in my share that are not group writable. It might seem like a lot of time and effort, but for a seasoned zsh user this is nothing! I did have to consult the zsh man page to find the glob qualifier for “group writable files”, but that didn’t take long. In the next article I’ll continue with this scenario, and tell you if I ever did manage to get those files deleted :) Stay tuned… if you dare!

uninstall inactive!

Oh man I just realized that I never ran “sudo port uninstall inactive” and I have reclaimed… hmm… 5 gigs? It’s as simple as that – if you’re using macports for a while and you’ve been using “sudo port upgrade outdated” to upgrade, make sure you remove the old versions because after a while that space really adds up! I don’t know why I thought that upgrading a port removed the old version? I bet it’s in the documentation somewhere (yes, it’s time for me to RTFM haha)

Wicked Cool Ruby Scripts

Having fun and solving problems can be mutually exclusive. Even for professional programmers and system administrators who chose their career because they enjoy problem solving, there can be times when finding a solution is an exercise in the mundane. Luckily, there are tools designed to ease the pain and frustration faced by programmers and admins. Ruby is a programming language that was designed from the start to not only provide a means of solving problems, but also to be inherently intuitive and fun to use. Wicked Cool Ruby Scripts, by Steve Pugh, is a book aimed to bring to light the fact that you can use Ruby to write concise yet useful scripts that solve difficult problems.

If you’re a fan of the “Wicked Cool” books from No Starch Press, you’ll find the format of this book familiar. It’s not a hefty tome complete with syntax and “hello world” introductory lessons, rather it’s almost a recipe book of sorts, divided into sections of problems and chock full of immediately useful Ruby code. This is the “Wicked Cool” book I’ve been waiting for, because although I write PHP and shell scripts (not so much Java and Perl, other topics covered in the series), I’ve always thought Ruby was the coolest of all. Right from the start, you can tell that Steve Pugh agrees with me. His tone throughout the book is that of a friend who has something fun to share, never browbeating or lecturing. He’s not simply writing to show us that he knows how to write Ruby well, he’s really trying to help us out.

Honestly, some of the examples in Wicked Cool Ruby Scripts might leave you wondering why you’d use such a powerful language like Ruby for such seemingly simple things. What Steve Pugh tries (and succeeds!) to show us is that Ruby isn’t just for writing massive web applications, but it can also handle tasks often relegated to the ubiquitous, but cryptic Awk or shell languages. Perhaps you still wonder why you’d want to? “Just because you can doesn’t mean you should”, right? So why bother? Because Ruby is “Wicked Cool”, that’s why.

So what’s cool? How about a simple file alteration monitor to help you see what’s changed on your system? Not cool enough? How about a web based photo gallery in about 50 lines of code? Still not impressed? How about writing a Metasploit module to attack one Windows machine from another? From general purpose utilities to system security and yes, even some games, Wicked Cool Ruby Scripts has enough in it to pique the interest of just about any programmer or sysadmin. I for one am finding it hard to concentrate on this review because I want to get back to writing Ruby. If you’re a programmer waiting for a good excuse to try Ruby, or a Windows sysadmin wondering what an open source programming language can do for you, you’ll find Wicked Cool Ruby Scripts enlightening, inspiring, and of course… cool.

So as you may know, I’m working on secret PHP project using the Zend Framework. It’s coming along well and I have been taking some notes on the server which is on the local network. I was about to download my notes and print them when I decided that printing directly from the FreeBSD server to the printer in our office should not be a difficult feat.

Of course… it wasn’t difficult, but it was a bit tricky. Here are some things I just learned, in no particular order:

* When installing the port called ghostscript8-no_x11 , you are asked to configure it and set up some options via the usual curses menu interface. One of these options says “include X11 support”. Doesn’t it seem strange that the port is named with the no_x11 suffix, yet including X support is an option? I thought so. I don’t have X on this server and never will. I don’t want X there. I unchecked the option, and then the build failed. Oddly enough you need to leave this option enabled or you will run into bizarre build errors like “ert file not found”.  Don’t worry though, leaving this option checked does not build X! (I don’t think it makes sense but with the port as it is today, this is the case)

* If you didn’t think about installing CUPS early enough to set up the special options in make.conf to tell FreeBSD’s ports system to overwrite the default LPR printing base, you’ll have to move or otherwise disable /usr/bin/lp and /usr/bin/lpr and then either link /usr/local/bin/lpr and lp to /usr/bin or just edit your PATH.  I found that tidbit here: http://home.nyc.rr.com/computertaijutsu/cups.html

* The DELL 5110 printer we use has been added to our windows domain. The drivers for PCL and PS were added to the print server so that when the printer is being added there are choices. If you have the PS driver installed, just use that, trust me. You can add the printer in cups’ web interface and tell it to send the job raw. It’s much easier, in my opinion, than messing with drivers and ppd files. Using the PS driver and the raw queue I was able to print a test page the first try, which is saying something, believe me.

* I wasn’t able to print text files properly via the lpr command. I got strange stair-stepping on my printouts and they were totally unusable. Using the a2ps command to format and send the output directly to the printer worked amazingly. I never saw a printed text file look so good. a2ps is available in the ports tree and it works great even when you’re printing from a FreeBSD server via Cups and the samba/smb backend to some printer on a windows domain.

PHP/Recode fail

I use PHP on FreeBSD servers, compiled from the ports system. It works very well, except that sometimes… well… sometimes… segfaults happen. Yes random, bizarre, “how did this working system suddenly become non-working wtf” errors happen.

Here’s an example of what happened to me today. This is a snip from my lighttpd error log

(mod_fastcgi.c.2722) child signaled: 11
(mod_fastcgi.c.1051) the fastcgi-backend /usr/local/bin/php-cgi failed to start:
(mod_fastcgi.c.1065) terminated by signal: 11
(mod_fastcgi.c.1070) to be exact: it segfaulted, crashed, died, … you get the idea.
(mod_fastcgi.c.1072) If this is PHP, try removing the bytecode caches for now and try again.
(mod_fastcgi.c.2759) ERROR: spawning fcgi failed.

WHAT!?

Well in a nutshell, php-cgi is failing to start. When I attempt to run /usr/local/bin/php-cgi from the command line, it causes a segmentation fault. If you’ve seen this before, you might have thought “oh no… sig11! signal 11 could mean my hardware is fried!” At least I thought so. The truth of the matter, in this case, is that the php-cgi executable is not happy. Why isn’t it happy? I’m glad you asked. We all want our executeables to be happy, right?

This wasn’t easy for me to figure out the first time it happened to me last year. I was going nuts trying to figure out what went wrong, I even put in a request for new hardware (yes a new development server, which I actually got). This didn’t solve my problem either. I began to panic. I’m not sure what made me think of it, but after a while I decided to try minimalizing my PHP installation, by commenting out extensions from my extensions.ini file (on my sys it’s /usr/local/etc/php/extensions.ini)

With everything commented out, php-cgi was happy again, but of course I need at least a few of the extensions (specifically mysqli), and so I started adding extensions back in one at a time to find the problem. It turns out that the problem is with the recode extension.

With the recode extension out of the picture, things went along fine for quite a while and I was able to develop my small web application with Zend Framework (1.5 at the time, I think). PHP was happy, Lighttpd was happy, I was happy. There was a lot of happiness to be found! And then it happened. I updated my PHP port with portmaster. A dark cloud (a cloud named sig11) loomed over the server and the happiness turned to confusion once again. Then I remembered… “didn’t this happen last year?” Yes. Yes it did. Same problem. This time I didn’t panic though, I went straight for the extensions file.

Now I’m not sure what about the recode extension my system doesn’t like, but it doesn’t like it. It didn’t like it last year, and it doesn’t like it now. The PHP port installed a new copy of extensions.ini which includes the recode extension and so that’s why the error reoccured after updating the port. If you are experiencing weird segmentation faults with PHP, I highly recommend you start commenting out your extensions. Also, you may want to check the order of the extensions. If they are in alphabetical order, something is wrong. Some extensions rely on others to be loaded first, so be careful.

That’s it for now… PHP is happy once again, and I’m working on a new dev project, this time with Zend Framework 1.7  :) I’d tell you more about it… but it’s a secret. No, really, it’s a secret.

Does it work? The answer is yes! :)
All you have to do is edit the sshd_config file on the OpenBSD machine and set X11Forwarding to yes, then fire up X (I’m using XQuartz 2.3.2 (xorg-server 1.4.2-apple18)) and in an xterm (or Terminal.app!) enter

ssh -Y user@openbsd_machine program

Voila!
P.S.: Actually, you don’t even have to start X on either end of this connection, it will still work. I just tried :)

Why can’t I just reboot? Why do I have to choose some option from a dropdown? I only wanted to reboot! Now I was tricked into shutting down a server that isn’t even in the same zipcode! What the hell Microsoft? Why couldn’t you make reboot the first choice? Now I’m stuck making calls and e-mailing people to say “sorry I was confused by the crazy windows shutdown options”. Shutting down should be easier. Instead, the first thing you have to do is click START, which makes NO SENSE WHATSOEVER, then you have to choose from some silly dropdown to explain why. I’ll tell you why I was rebooting Microsoft! I’ll tell you why! It’s because you force me to reboot in order to get anything done! that’s why! That’s why I have to reboot the damned server! WTF?! You make my life miserable at every opportunity. Is it because you know I hate you? Is it because you know I’m using a mac and have a FreeBSD machine and OpenBSD machine at home? is that it? Is it because you know about my Ubuntu desktop machine? What is it? Why must you torture me this way?

Wordpress Cloud Hosting