Programmer

New SyxLoader Version 1.5 available

Sunday, August 12th, 2007

SyxLoader

SyxLoader Version 1.5 now offers a new preferences dialog to control the event splitting behaviour. This hopefully will be useful for users of USB class-compliant interfaces who experience data loss or corruption on sysex transmissions.

Read more »


Debian Sarge and QLA2340

Friday, June 2nd, 2006

The following is a brief example of how to compile a kernel module from the qla2x00-source package to get a QLogic QLA2340 fibre channel HBA working under Debian Sarge. This works well for me using kernel image 2.4.27-3 SMP. Many thanks to the kind package maintainers.

Edit your sources.list and add non-free branch to get qla2x00-source package via apt-get.

$ vi /etc/apt/sources.list
[...]
deb ftp://[...]/debian/ stable main non-free
deb-src ftp://[...]/debian/ stable main non-free
[...]
deb http://security.debian.org/ stable/updates main non-free
$ apt-get install bzip2

$ cd /usr/src

$ apt-get install qla2x00-source

$ bzip2 -cd qla2x00.tar.bz2 | tar xf -

$ apt-get install kernel-source-2.4.27

$ bzip2 -cd kernel-source-2.4.27.tar.bz2 | tar xf -

$ ln -s kernel-source-2.4.27 linux

$ cd linux

$ cp /boot/config-2.4.27-3-686-smp .config

$ apt-get install kernel-package

$ make oldconfig

$ make-kpkg --append-to-version=-3-686-smp \
--added-modules=qla2x00 modules_image

$ cd ..

$ dpkg -i qla2x00-modules-2.4.27-3-686-smp_[...]Custom_i386.deb

$ insmod qla2300

Check which device is available (see /var/log/messages) and where to mount preferably, then edit fstab.

$ vi /etc/fstab
# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults        0       0
[...]
/dev/sdb1       /san            ext3    defaults        0       0
[...]
$ mkdir /san

$ /sbin/mkfs.ext3 /dev/sdb1

$ mount /dev/sdb1
$ df -ak
Filesystem           1K-blocks      Used Available Use% Mounted on
[...]
proc                         0         0         0   -  /proc
[...]
/dev/sdb1             51606124     32828  48951860   1% /san

Maybe clean up a little bit.

$ apt-get remove --purge kernel-source-2.4.27

$ apt-get remove --purge qla2x00-source

$ cd /usr/src

$ rm linux

$ /bin/rm -r kernel-source-2.4.27

$ /bin/rm -r modules

Back to the future with VMware Server

Sunday, March 26th, 2006

A few weeks ago VMware released their free VMware Server Beta virtualization software which I downloaded and installed on my little Debian slave, an AMD Duron 1300 with 512MB RAM. This machine normally holds backups of my main computer and serves as a general purpose Linux box and webserver for me at home. Well, I had to learn that there is still much more that you can do with it.

Every now and then I wished to have more than one Linux box so that I could easily try something out and get rid of it afterwards without touching my default installation. And, yes, very seldom I’d like to have a Windows 98 environment to compile and test an older piece of software. But yet I was neither willing to provide a third computer for that nor to struggle with drive images or multi-boot setups.

And now these wishes become true at no cost with VMware Server. You see, I am excited. So I took the following screenshots to demonstrate how simple a new virtual machine can be brought to life. The shots are taken from VMware Server Console running on my Windows XP main machine to control the Debian slave with VMware Server.

You may complain about the one or another shot being redundant, but my intention is to also produce an authentic impression of this beautiful installation process that we all got to like that much over the years. Of course, the good old Windows 98 startup disk had been prepared and inserted into Debian slave’s disk drive ;-)


Perl – Apache::Htpasswd

Monday, March 13th, 2006

Imagine you set up dozens of virtual hosts and want each of them to have an individual default password for a protected area, i.e. a logfile directory being accessible via http://vhost/logs/. Putting .htaccess files into the target directories is step one and fairly simple. Whereas step two, adding the .htpasswd files, may end up unhandily, either juggling with cleartext and encrypted passwords or falling back on system() calls of htpasswd(2).

The example below shows how this can be handled with the modules Apache::Htpasswd and String::Random. Just provide a filename and a username, the subroutine will create the .htaccess file, add the user with a new random password and return the cleartext password to be handed out to your customer.


use String::Random;
use Apache::Htpasswd;

sub DefaultHtpasswd($$) {
  my($Filename,$Username) = @_;

  my $RandomString = new String::Random;
  my $PasswdString = $RandomString->randpattern('nnCcCnCc');

  my $Htpasswd = new Apache::Htpasswd($Filename);

  $Htpasswd->htpasswd($Username, $PasswdString, 1)
  or die($Htpasswd->error);

  return($PasswdString);
}


Perl – CatOS config via SNMP / TFTP

Sunday, March 12th, 2006

Below is a piece of code that I wrote a while ago when setting up a backup mechanism to automatically retrieve (and put) configuration files from (or to) Cisco Catalyst switches (running CatOS).

Usually, as a perl programmer with a new challenge, you will first do a search on CPAN and almost probably find the answer or at least a hint. But at that time I decided not to go for the Cisco::Conf module that uses telnet instead of SNMP commands and operates in writeNet mode. Today, the more recent Cisco::CopyConfig should be the module of choice, but it uses ccCopy mode and works for IOS devices only.

My example uses tftpGrp mode, a third variant, that has not yet been packed in a module.

Short explanation: Subroutine, give it your Catalyst’s hostname or IP address ($Host) and SNMP write community string ($Cty), the TFTP server’s hostname or IP address ($Server) and the filename on TFTP server ($Filename). The action ($Action) to be performed by Catalyst is given in clear text, see %Actions for allowed values. Module number ($Module) and timeout in seconds ($Timeout) are optional arguments and default to standard values if omitted. Returns result in clear text, see %Results for possible values.

Don’t forget to touch and chmod 666 file on TFTP server before transfer and remove it afterwards. Have fun!


use Convert::BER;
use Net::SNMP;

sub tftpGrp {
  my($Host,$Cty,$Server,$Filename,
     $Action,$Module,$Timeout) = @_; 
  ################################
  my %OIDs = (
   'tftpHost'   => '1.3.6.1.4.1.9.5.1.5.1.0',
   'tftpFile'   => '1.3.6.1.4.1.9.5.1.5.2.0',
   'tftpModule' => '1.3.6.1.4.1.9.5.1.5.3.0',
   'tftpAction' => '1.3.6.1.4.1.9.5.1.5.4.0',
   'tftpResult' => '1.3.6.1.4.1.9.5.1.5.5.0',
  );

  my %Actions = (
   'other'          => 1,
   'downloadConfig' => 2,
   'uploadConfig'   => 3,
   'downloadSw'     => 4,
   'uploadSw'       => 5,
   'downloadFw'     => 6,
   'uploadFw'       => 7,
  );

  my %Results = (
   1  => 'inProgress',
   2  => 'success',
   3  => 'noResponse',
   4  => 'tooManyRetries',
   5  => 'noBuffers',
   6  => 'noProcesses',
   7  => 'badChecksum',
   8  => 'badLength',
   9  => 'badFlash',
   10 => 'serverError',
   11 => 'userCanceled',
   12 => 'wrongCode',
   13 => 'fileNotFound',
   14 => 'invalidTftpHost',
   15 => 'invalidTftpModule',
   16 => 'accessViolation',
   17 => 'unknownStatus',
   18 => 'invalidStorageDevice',
   19 => 'insufficientSpaceOnStorageDevice',
   20 => 'insufficientDramSize',
   21 => 'incompatibleImage',
  );
  ################################
  $Action  = $Actions{$Action} or return(undef); 
  $Module  =  1 unless(int($Module));
  $Timeout = 10 unless(int($Timeout));

  my($Session,$Error) = Net::SNMP->session(
    -version   => 'snmpv2c',
    -hostname  => $Host,
    -community => $Cty
  );
  return($Error) unless(defined($Session));

  $Session->timeout($Timeout);

  $Session->set_request($OIDs{'tftpHost'},OCTET_STRING,$Server);
  $Session->set_request($OIDs{'tftpFile'},OCTET_STRING,$Filename);
  $Session->set_request($OIDs{'tftpModule'},INTEGER,$Module);
  $Session->set_request($OIDs{'tftpAction'},INTEGER,$Action);

  $Error = $Session->error();
  if($Error) { $Session->close(); return($Error); }

  for(my $Time = time(); time() <= $Time + $Timeout;) {
    sleep(1);
    my $Result = $Session->get_request($OIDs{'tftpResult'});
    my $Value  = $Result->{$OIDs{'tftpResult'}};
       $Error  = $Results{$Value};
    $Timeout++ if($Error eq 'inProgress');
    last       if($Error eq 'success');
  }
  $Session->close();
  return($Error);
}