Diary and notebook of whatever tech problems are irritating me at the moment.
20091225
Restricting SSH logins to specific groups on Ubuntu
20090929
Basic apt key management
Ubuntu's keyserver, keyserver.ubuntu.com, has a lot of problems lately. I was trying to add the Pidgin repository to work around bug #389322 but kept getting timeout errors from the server. One of my systems did successfully get the key so all I had to do was transfer it to the others.
These are the commands you can use to do the same. I used a terminal because I couldn't find a way to export the keys graphically with either the Synaptic package manager or Seahorse.
First list the keys:
gpg --list-keys --no-default-keyring --keyring /etc/apt/trusted.gpg
/etc/apt/trusted.gpg
--------------------
pub 1024D/437D05B5 2004-09-12
uid Ubuntu Archive Automatic Signing Key
sub 2048g/79164387 2004-09-12
...
pub 1024R/A1F196A8 2009-01-20
uid Launchpad PPA for Pidgin Developers
The "--no-default-keyring" and "--keyring" tells gpg to use only the specified apt trusted keyring. Next, find the key you want to export from the list and specify either the key ID or user ID with the following command:
gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --armor --export A1F196A8>pidgin.gpg
The "--armor" tells gpg to output an encoded text key instead of binary one. The Pidgin package signing key ID is A1F196A8 and it is captured to a "pidgin.gpg" file in the current directory. Then you copy the key file to your other systems and add it to their apt keyrings using either Synaptic (Settings > Repositories > Authentication > Import Key File) or the apt-key command in a terminal:
sudo apt-key add pidgin.gpg
Then you add the repository as shown in the Pidgin download page. To upgrade Pidgin you can use Synaptic (Reload, Mark All Upgrades, Apply), the text-based package manager aptitude (u,U,g), or apt-get on the command line:
sudo apt-get update
sudo apt-get upgrade
Then you just need to restart Pidgin and try connecting to your Yahoo! Messenger account.
20090815
Writing UDEV rules to get a SCSI scanner working on Ubuntu
I'm building some Ubuntu 9.04 (Jaunty Jackalope) systems for relatives and using them as a way to get rid of a lot of old hardware that has been taking up space in my office. This includes several old USB, parallel port, and SCSI scanners. SCSI scanners pretty much ruled in the days before USB as they were much faster than parallel ports. However, they were a pain to configure and required heavy (and usually short) cables which made them difficult to fit into your work area. I tested a Microtek ScanMaker E3 (MRS-600E3) and UMAX Vista S8 scanner first. They worked without problems although the former was picky about termination. Unfortunately a Hewlett-Packard ScanJet 6100C (Q2950A) didn't work at all. Checking the kernel messages indicated that it was represented by /dev/sg7 but the permissions were 0660 root:root so sane couldn't access it. Changing the permissions solved the problem but the /dev directory is a virtual filesystem controlled by udev and the changes are lost after reboot. I could just put a chmod comand in /etc/rc.local but that is the wrong way to fix it. A search on launchpad found bug #378989 which describes the problem with this model. I'm not sure if the fault lies with udev or HAL but creating a udev rule is a simple enough way to fix it for now. I'll describe how to create such a rule using this as an example but udev rules can do much more than just change device permissions.
First you need to be root. Either add "sudo" to the beginning of the following commands or switch to a root shell with "sudo su". Next install lsscsi which makes it easy to identify device node assignments:
apt-get install lsscsi
Then run it to get a list of SCSI devices:
lsscsi -g
[0:0:0:0] disk ATA Maxtor 33073U4 BAC5 /dev/sda /dev/sg0
[0:0:1:0] cd/dvd LITE-ON COMBO SOHC-4836V SG$4 /dev/sr0 /dev/sg1
[4:0:5:0] process HP C2520A 3644 - /dev/sg7
[5:0:0:0] disk USB 2.0 Flash Disk 0.00 /dev/sdb /dev/sg2
[6:0:0:0] disk Generic USB SD Reader 1.00 /dev/sdc /dev/sg3
[6:0:0:1] disk Generic USB CF Reader 1.01 /dev/sdd /dev/sg4
[6:0:0:2] disk Generic USB SM Reader 1.02 /dev/sde /dev/sg5
[6:0:0:3] disk Generic USB MS Reader 1.03 /dev/sdf /dev/sg6
Note that the scanner is at /dev/sg7. With this information you can then use udevadm to find out what is known about the device in the udev database and where in hierarchy of systems it lies:
udevadm info -a -p /sys/class/scsi_generic/sg7
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:1e.0/0000:01:01.0/host4/target4:0:5/4:0:5:0/scsi_generic/sg7':
KERNEL=="sg7"
SUBSYSTEM=="scsi_generic"
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:01:01.0/host4/target4:0:5/4:0:5:0':
KERNELS=="4:0:5:0"
SUBSYSTEMS=="scsi"
DRIVERS==""
ATTRS{device_blocked}=="0"
ATTRS{type}=="3"
ATTRS{scsi_level}=="3"
ATTRS{vendor}=="HP "
ATTRS{model}=="C2520A "
ATTRS{rev}=="3644"
ATTRS{state}=="running"
ATTRS{timeout}=="0"
ATTRS{iocounterbits}=="32"
ATTRS{iorequest_cnt}=="0x8"
ATTRS{iodone_cnt}=="0x8"
ATTRS{ioerr_cnt}=="0x1"
ATTRS{modalias}=="scsi:t-0x03"
ATTRS{evt_media_change}=="0"
ATTRS{queue_depth}=="2"
ATTRS{queue_type}=="none"
looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:01:01.0/host4/target4:0:5':
KERNELS=="target4:0:5"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:01:01.0/host4':
KERNELS=="host4"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:01:01.0':
KERNELS=="0000:01:01.0"
SUBSYSTEMS=="pci"
DRIVERS=="aic7xxx"
ATTRS{vendor}=="0x9004"
ATTRS{device}=="0x7178"
ATTRS{subsystem_vendor}=="0x0000"
ATTRS{subsystem_device}=="0x0000"
ATTRS{class}=="0x010000"
ATTRS{irq}=="22"
ATTRS{local_cpus}=="ffffffff,ffffffff" ATTRS{local_cpulist}=="0-63"
ATTRS{modalias}=="pci:v00009004d00007178sv00000000sd00000000bc01sc00i00"
ATTRS{enable}=="1"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}==""
looking at parent device '/devices/pci0000:00/0000:00:1e.0':
KERNELS=="0000:00:1e.0"
SUBSYSTEMS=="pci"
DRIVERS==""
ATTRS{vendor}=="0x8086"
ATTRS{device}=="0x244e"
ATTRS{subsystem_vendor}=="0x0000"
ATTRS{subsystem_device}=="0x0000"
ATTRS{class}=="0x060400"
ATTRS{irq}=="0"
ATTRS{local_cpus}=="ffffffff,ffffffff"
ATTRS{local_cpulist}=="0-63"
ATTRS{modalias}=="pci:v00008086d0000244Esv00000000sd00000000bc06sc04i00"
ATTRS{enable}=="1"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}=="1"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
Note that the DRIVERS=="aic7xxx" indentifies the Adaptec AHA-2940 SCSI card. All of this data can be referenced by a udev rule to identify when and how to manipulate the device. That is what udev does - run everything through a list of rules, matching or excluding attributes as specified by a rule, then performing an operation when the conditions of a rule is met. The manual for udev is at /usr/share/doc/udev/writing_udev_rules/index.html and it gives many good examples of what you can do. In this case the scanner device needs different permissions and group ownership so that users can access it with Xsane. Most of the rules included with packages are in /lib/udev but local rules can be added to /etc/udev/rules.d and they can override existing rules. There is a file name standard for the rule files (see the README in the directory) - they always start with a number (which indicates priority) and end with ".rules". My rule file is "/etc/udev/rules.d/45-scsi-scanner.rules", owned by root and in group root with 0644 (rw-r--r--) permissions. You have to reboot to make it active. This is what it contains:
# permissions for HP ScanJet 6100C SCSI scanner
SUBSYSTEM=="scsi_generic",ATTRS{vendor}=="HP",ATTRS{model}=="C2520A", NAME="%k", SYMLINK="scanner%n", MODE="0660", GROUP="scanner"
So what does this all mean? First the SUBSYSTEM keyword says it only applies to devices in the "scsi_generic" subsystem (as per the first few lines that udevadm reported). The "==" is a comparison operator. Next the ATTRS{vendor} keyword specifies that an attribute named "vendor" in the subsystem (or any parent subsystem) has to have a value of "HP" (which the SCSI module reports via the SCSI card). Then the ATTRS{model} keyword tells udev to look in the same subsystem that matched the vendor for a model attribute that matches "C2520A". If it finds one, and since there are no other comparisons specified, then the rule matches and the rest is processed. NAME is the keyword for setting the device node name (sg7 in this case) and the %k is a string substitution operator that udev will expand to the original name assigned by the kernel (again sg7). The "=" is the assignment operator. So this part of the rule sets the NAME assignment key to the original "sg7" effectively keeping the default device node "/dev/sg7" as is. The SYMLINK keyword creates symlinks to the default device node. The %n operator is expanded by udev to the kernel number of the device (the 7 in sg7). The resulting symlink will be scanner7 in this case and if the default node changes due to a SCSI device being added or removed the symlink will change to match (scanner5 for sg5, etc.) For the scanner rule it is for convenience only as a device named "scanner" is easier to figure out than "sg", especially when trying to do user support over the phone. The MODE just sets the permissions in octal and GROUP assigns a specific group membership of "scanner".
When this rule is activated, /dev/sg7 will be root:scanner with rw-rw---- permissions and a /dev/scanner7 symlink will also be created that points to it. For the user to access the scanner they need to be in the scanner group. If the scanner group doesn't exist (not in /etc/group) then you can add it with:
addgroup --system scanner
This will dynamically create a system group somewhere in the range of 100-999. Any users added to the group need to relogin for it to take effect.
20090802
Introducing Winesharer - so pre-alpha it doesn't even work
About a year ago I was setting up a Ubuntu system for a family of non-technical users. They like to play games and one of their favorites is Diablo II. It works well on Wine if you set it to use Glide and install a Glide wrapper. The game's copy protection is properly supported by Wine but it's not necessary as Blizzard removed the CD check in the recent patches.
There are two problems with installing Windows applications like Diablo II for multiple users. First, because of the isolation of user accounts on *nix systems, you have to login and repeat the install process for each account. Second, each installation after the first wastes disk space and with Diablo II it's several gigabytes, especially if you have a lot of mods.
It's possible to manually copy the first installation and edit the Wine registry, menu entries, and fix symlinks, but it's tedious. So I began messing around with some shell scripts to automate the process. I'm not an expert with shell scripts but I improved with time and some help from my LUG-mates. After several false starts I got a basic script functioning. That solved the first problem but not the space issue.
After messing around with some LiveCDs, I got the idea to try to share the wine directory with a union mount. First I tried FunionFS but it had several bugs that prevented it from working (like not being able to change an existing file). So I switched to Aufs. It worked but it can't be run by a user as it requires root permission to mount. To keep it easy for users I had to use pam_mount and mount it at login. I added the ability for the script to export a sample mount entry for pam_mount.conf.xml to save time.
I then got the idea to add handling for separate Wine directories for each application (like CrossOver Bottles). That brought up another issue, the desktop menu entries for Wine's utilities like winefile and winecfg. I needed to add duplicate entries with different WINEPREFIX settings and associate them with each application. I came up with a primitive solution for locating the entries and duplicating them in an alternate location as a submenu below the primary application's menu (Wine > Programs > (application) > Wine Utils).
I then got another idea - application merging. One problem with games is that there are a lot of third-party mods and other customizations for them. There are also a lot of updates. This requires editing of configuration files, extracting files from archives, and file management. These can't always be done easily with Linux tools. One problem is patches for older games are often in zip files. The contents are intended to overwrite existing files but sometimes the filenames have different case. If you extract them with a native Linux application you end up with duplicates instead of overwrites. The other problem with Linux tools is that they always give a "/" or "/home/user" oriented view when the user expecting C:, especially when following an online instructions for installing a patch or mod. The concept of application merging is simple - select some utilities that have minimal dependences, install to a separate Wine directory, then add it as an Aufs branch to the mount for each main application. You install each one once and share it but then it can be used within every other Wine application directory (and behaves as if it was installed in each) without wasting much storage space. Wine's registry files are text so entries for a merging application can be duplicated with just diff and patch.
Then I realized this had another major benefit for game mods - it would be possible to install multiple, even conflicting mods, and mount them as separate Aufs mount points at the same time. This is especially useful for games that don't have integrated mod management. Using Diablo II as an example, you would install and update it, share it with wineappshare.sh, then mount it via Aufs with a new read/write directory branch. Then install a mod like MedianXL (which ends up in the read/write branch). Then unmount the directory, move and share the read/write directory as a new read-only branch for MedianXL and mount it on top of the Diablo II directory with a new read/write branch. If you mount the Diablo II directory again using a different read/write branch, you can run regular Diablo II and the MedianXL version at the same time. Effectively they are in separate "bottles" but share the bulk of the install in read-only branches so there is little additional overhead.
Of course the tricks don't stop there. You can imagine putting the shared parent branches on a compressed volume to save space, mount it on a server via NFS, and use pam_mount to mount the read/write branches on a USB drive on the client. Imagine the possibilities for a gaming cafe system.
At this point I knew Winesharer would revolutionize Windows gaming on Linux. Just as soon as I finish writing it. Then perfecting it. Then documenting some really complicated examples. And make some awesome video demonstrations. And write the book. Then push it out of the code cave and bask in the glory. At least that was the plan about a year ago before life and reality got in the way. So now I'm down to the old "release early and often" process which completely eliminates the "shock and awe" value. At least this way it may have an impact before Wine is forgotten due to lack of interest in running legacy Windows applications and everyone switching to GNU/Hurd.
Winesharer consists of three scripts:
wineappshare.sh - strips out user-specific directory links, tracks down related icons and XDG menu entires, and copies the Wine directory (bottle) to a shared location - /srv/wine by default. The hardest part was finding the menu entries (*.desktop) as Wine doesn't keep track of them. I had to do a linear search by grepping for matching WINEPREFIX values then calculating what the matching menu directory (*.menu) path would be. It also doesn't help that the "Icon=" references can specify icon file extensions with ".png", ".xpm", or not at all.
winemergeprep.sh - makes registry diffs and a list of modified files for "mergeable" utilities. The file listing excludes any unchanged/unused files like the fake DLLs that Wine adds in the System directory. It is run twice - after initial creation and configuration of the Wine directory and before the target application is installed, and again after installation and configuration of the application. The applications I was using are 7-Zip, xplorer², FontPage, IPaddress, SciTE (or EditPad Lite), @icon sushi, and Dependency Walker. Some of these are only for debugging. After prep the mergeable application directory is shared with wineappshare.sh like other applications and wineappinstall.sh performs the special handling of their branches and patches when other applications are installed for users.
wineappinstall.sh - where things got ugly. Setting up the read/write directory and creating the template pam_mount entry for Aufs mounting was easy. So was copying over the icons. Recreating symlinks between the user's profile directories (My Doucments > ~/Documents, etc.) was a lot more complicated. I wanted to do it correctly by following the XDG Base Directory Specification, first by checking for a local (user) configuration, then the system-wide defaults, then look for commonly-used defaults, and finally just defaulting to ~. I got that part sort of working. The final problem was trying to merge the shared application menu entries, the "mergeable" applications entires, and any existing entries without damage. Doing this in an orderly (and deterministic) fashion is difficult and shell scripts aren't great for text processing. That's where I left off.
The scripts all require the Wine directory name and it's assumed to be in ~. For example, specifying Diablo II's directory would just be ".wine-Diablo_II". Note that spaces should not exist in the directory name. The Winesharer scripts handle them but others, like Dan Kegel's winetricks, had trouble with them. Second, the scripts search through the registry for the username of the installer in order to change it to the target user's name later. Because of this it needs to be globally unique (in ALL Windows applications) so the scripts don't change something that is not related to the user. I had a Wine administration account named "wineadmin" which should be safe as long as there isn't any client/server wine (the drinking type) management applications that use the same keyword or value in the registry. The sharing directory is in /srv to comply with v2.3 of the Filesystem Hierarchy Standard. I was using a "_rw" suffix for the read/write branch directories.
What's next? Nothing. This was intended to be a one week feasibility study but suffered from a ridiculous amount of feature creep. Between the earlier draft scripts and command-line tests I know it's possible to do but text processing in shell scripts is tedious and I don't have the time to finish it. The scripts are ugly, broken, and can't handle all possible problems. I do like cats so I made it a point to eliminate cat abuse but I left a lot of dysfunctional grep|sed marriages since reducing them is time consuming and the extra processes give my idle Phenom cores something to do. There's a lot of arrays and case statements. I didn't follow any column limits either. Because this was a work-in-progress I also discarded the Unixy notion of minimal feedback - my scripts write entire novels to the terminal. There are a lot of comments, especially in the unfinished portions of wineappinstall.sh (which is guaranteed to not work). I didn't even begin implementing the integrated multimedia help styled after 0verkill. Instead, this pre-alpha work includes a bonus pack of bugs. I don't think the scripts can fail in such a way as to wipe out your filesystems and install Vista but I'm not guaranteeing they won't either. This mess was developed on Ubuntu 8.04 (Hardy Heron).
My goal with this project is to inspire others to implement a more robust (not to mention functional) solution incorporating these ideas. A user space union filesystem like FunionFS would be more convenient than Aufs but I don't know of any alternatives. I think that having submenus for mergeables in each application menu is ugly. A front-end utility for dynamically setting WINEPREFIX and launching them would be better. One problem I thought of but don't know how to handle are applications that require registration keys at installation instead of first-run. For some, their registration keys can be purged from the registry and they will prompt for a new key when executed again. Others won't and may lock-out and refuse to run even with a valid key, requiring a full reinstall.
20090708
The fun of legacy hardware
I have an old embedded system that uses an SBC-MAX (pdf) board from Computer Dynamics. The unit was part of a vehicle monitoring system that used Windows 98 (one of many fundamental flaws in the design). It has a K6/2 333MHz CPU and 128MB of EDO DRAM. It features a whole bunch of integrated devices and a fairly broken BIOS. As an embedded system it has a PC/104 bus for which I have a few modules including a GPS. I'm would like to get that working but getting Ubuntu to even install on it has been a pain.
The source of the problem is an ITE IT8330G PCI-ISA bridge with IDE controller that is only supported by the ide-generic driver. This is rather obsolete and isn't loaded in most kernel images including bootable CDs. The latest Ubuntu CD that would boot is the 7.10 (Gutsy Gibbon) alternate CD.
Gutsy's install worked up to where it loaded packages where it would hang after a while. I suspected it was running out of memory so I tried again. After formatting the partitions I switched to a different terminal and activated swap before continuing. This solved the problem:
free
fdisk -l /dev/hda
swapon /dev/hda5
free
When the install completed, it hung at restarting so I power-cycled it. It does this at power-off (halt) as well which may be a board limitation as the system originally used a serial port to shut off power via an "intelligent" power supply made by Dynamic Engineering. The system booted and Grub loaded initrd (containing the kernel) and then the init scripts started but then it stalled for a while - ending up at an initramfs prompt. Rebooting and editing the boot line in Grub to remove the "quiet" and "splash" entries resulted in more detailed messages which showed it couldn't find the drive. Basically the only driver that supports the ID8330G is ide-generic and it's not in linux-generic which Gutsy and later releases use by default.
The solution to getting Linux to boot is to add the driver but it's in linux-386. To install it, I rebooted with the CD and entered "rescue" mode. After a series of prompts it gives you the option to open a root terminal on a chrooted partition. I selected the root partition and got a bterm session. On Gutsy, it's not a friendly environment as you don't get tab completion or history so you get a lot of finger exercise. First thing was to activate swap then use apt-get to install linux-386.
This is were the next problem was encountered. Gusty is obsolete so the repos have moved to the old releases server. Trying to fix the sources.list file with vi was impossible due to refresh and scrolling bugs with either it or bterm. I tried Midnight Commander (mc) and had to set the TERM environment variable (export TERM=linux or whatever) but it was also rather ugly. I eventually figured out a sed script to fix them faster:cp /etc/apt/sources.list /etc/apt/sources.list_orig
sed 's/us\.archive\|security/old-releases/' /etc/apt/sources.list_orig >/etc/apt/sources.list_oldr
This just looks for "us.archive" or "security" and replaces them with "old-releases". The next problem was that Gutsy's installer had disabled the repos since it couldn't find them during installation. Another sed script fixed this:
sed 's/^#[# ]*\(deb .*$\|deb-src .*$\)/\1/' /etc/apt/sources.list_oldr > /etc/apt/sources.list
This looks for lines starting with the comment character # followed by "deb" and attempts to skip other comment lines. Then I ran "apt-get update" and "apt-get install linux-386" and was good to go - almost.
After rebooting it ended up at the initramfs prompt again. I entered "modprobe ide-generic" and it found the drive. I entered a Ctrl-D and the boot completed. I filed bug 128833 about this a while back but I know now that the driver can have problems with more-specific IDE drivers so normally it isn't loaded. To fix it I wrote a basic init script named "idegeneric" and put it in "/usr/share/initramfs-tools/scripts/local-top":
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;
esac
modprobe ide-generic
I just basically copied one of the other scripts and modified it. I then created a new initrd image with the command "update-initramfs". It loaded on the next reboot without problems.
Next I updated Gutsy with "apt-get -y upgrade" which updated a whole lot of stuff and installed a new kernel (which included the idegeneric script automatically). On a system this old it's like watching grass grow so I worked on something else for a few hours but later found it had locked up (the Magic SysRq keys didn't work). After a power cycle I ran dpkg --configure -a" and it completed without problems but it found some bad inodes on the next reboot and had to fix them (should have done this first before finishing). Then it was time to upgrade to something a little more modern, Ubuntu 8.04 (Hardy Heron). The command to do this is "do-release-upgrade". The first thing it does after finding a new release is change the release targets in the sources.list file to "hardy". Next it loads in the new package lists. Of course this failed as it was looking for them on the old-releases server so I had to change the entries back to "us.archive" first. Then it was happy and began the upgrade. After a reboot Hardy loaded without problems.
An upgrade to Intrepid Ibex (8.10) was next but "do-release-upgrade" couldn't find a newer version. This is because Hardy is a "Long Term Support" version and the next LTS release will be 10.04 which isn't out yet. To fix it, you have to edit "/etc/update-manager/release-upgrades" and change "Prompt=lts" to "Prompt=normal". This upgrade continued without problems.
Jaunty Jackalope (9.04) is the latest but after the upgrade it failed to load the driver. A message was shown:
ide_generic: please use "probe_mask=0x3f" module parameter for probing all legacy ISA IDE ports
Looks like "probe_mask=0x3f" was needed at the end of the modprobe line in the script to make it happy. Luckily the older Intrepid kernel was still configured in Grub so I was able to boot it instead. I added the parameter to idegeneric, then ran "update-initramfs" with the "-k" parameter to specify the Jaunty kernel (referencing it in the form that "uname -r" returns). After a reboot it loaded without problems but then started segfaulting all over the place. Apparently ide-generic is broke in Jaunty or doesn't like the ID8330G so it's back to Gutsy and restart the process. I stopped at Hardy as I have better things to do. I did try Puppy Linux but both the regular and "retro" versions failed to find the drive even with the "all-generic-ide" boot option.
20090603
My Paperwork Reduction Act
I have a habit of keeping receipts of every sales transaction I make. This is good for taxes, returns, rebates, billing, resale, and just trivia. After a decade or so it really piles up.
Several years ago I built my first PC, a Pentium 133MHz system with a Micronics M54Hi motherboard and a screaming Quantum Fireball 7200RPM 4GB SCSI drive (which later failed so I guess the screaming was a bad thing). This was one awesome Doom playing system. The advantage of SCSI over IDE was the number of devices a port could support (7 instead of 2), speed, and the ability to brag that your system cost 10x what everyone else bought. Of course a 50 pound, 30in high tower case with 3x the space needed was essential.
I also bought a HP ScanJet 3C (C2520A) 600dpi 8.5x14in SCSI scanner. This alone was about $900. While the scanner did get some use it mostly just sat on the shelf collecting dust and depreciating. It was rather large and I didn't have enough space on my desk to keep it handy. Several PCs later I bought a Visioneer OneTouch 8100 USB scanner for $50 - which was a waste of money as Staples had it on sale a month later for $25. This worked well and was much smaller but I still didn't get around to catching up with the paperwork. A unique feature of the 8100 was that it's power jack matched the plug on my Toshiba laptop power supply. However the power supply output was not compatible and after getting the plugs mixed up one day I had to buy another scanner. This time I got an Agfa SnapScan 1212U which has worked rather well.
Last week, while tripping over another box of paperwork I decided to finally start scanning things in. I'm using Xsane on Ubuntu 8.04 (Hardy Heron) and it's working rather well. I fit as many receipts as I can on the glass then preview them, draw a selection box around each in the Preview window, then hit the Scan button. Some of the receipts are too long for the Agfa so I installed an Adaptec SCSI card and hooked up the ScanJet. Xsane (0.995) doesn't let you switch between two scanners except at startup but you can run two instances of it simultaneously. It keeps track of preferences for each scanner separately too. Some of the documents I'm scanning have several numbered pages and Xsane has a numeric filename auto-increment function. It's not very flexible but it does the job. My only complaint is that some hotkeys, like Ctrl-V, are used for changing settings instead of the default copy/paste functions that most apps use so I have to use alternates like Shift-Insert. This makes copying and pasting filenames into the save dialog boxes annoying.
I find that scanning most things in at 300dpi grayscale and saving them as JPEGs works best. For items where color is important I use 600dpi. The ScanJet has one design flaw in that it's pad is white while the SnapScan's is black. The white pad causes printing on the back side of receipts to show up when scanning the front so it takes some fiddling around with the contrast and brightness settings to suppress it.
I'm not just scanning in receipts either. I'm also scanning contracts, notepads, holiday greeting cards, photographs, and user manuals I can't get PDFs for. It takes a long time but DVDs take up a lot less space than file cabinets.
20090324
Be wary of CPU upgrades on old motherboards
Twice now I've encountered burned power connectors on older ATX motherboards. The first was a pair of Tyan S2460 boards with dual Athlon MP CPUs. The owner was having problems with them and thought one of the CPUs had failed. He gave them to me and while testing I noticed the problem. Both of these boards were designed to the original ATX specifications and only had a 20-pin power connector. The CPU regulators used +5 volts as their input supply to generate the CPU voltages. The increasing power requirements of CPUs in this era (especially dual CPUs) resulted in increased current (amperes) through the connectors. Since increasing current results in increasing heat dissipation (due to wire and connector resistance) and the increased heat also increases the resistance the same, a thermal runaway condition can occur. This greatly reduces the life of them - the plastic of the connectors bakes and melts and eventually the solder on the motherboard connector pins melt. All of this is bad for stability.
I deemed the boards were useless and, not finding any economical Socket A replacements, decided to upgrade two other systems and give the rest of the parts to a PC recycling center. One of the CPUs, an XP 1800, replaced a 1.3GHz Thunderbird in a Gigabyte GA-7ZXE. This solved a problem with it's Nvidia 6600GT AGP video card and the newer drivers requiring SSE support. Everything was good for a few months but eventually instability set in. I found the +5V pins (red wires) on the ATX connectors had burned and fused together. The 6600GT had it's own power connector and I didn't think one CPU would cause an overload on the ATX connector. Burned twice you might say.
Newer versions of the ATX specification, ATX12V, added the second four-pin CPU power connector that uses +12V instead which greatly reduces the problem. In electrical physics, for the same amount of power (P, in watts), doubling the voltage (V) halves the current (I). The voltage (the amount of energy each electron is carrying) doesn't affect wire or connector heating, only the current (the quantity of electrons moving through the wire) and the conductor's resistance (R, in ohms) does. This heating effect is described by the formula P=I²R and is called "I squared R" losses. Something to keep in mind when upgrading or recycling old systems.
Note that this problem doesn't just affect the connectors. I almost fried a 400W ATX power supply while testing the Tyans with two CPUs because of the current requirements on the +5V rail was more than it could handle.
About Me
- jhansonxi
- Omnifarious Implementer = I do just about everything. With my usual occupations this means anything an electrical engineer does not feel like doing including PCB design, electronic troubleshooting and repair, part sourcing, inventory control, enclosure machining, label design, PC support, network administration, plant maintenance, janitorial, etc. Non-occupational includes residential plumbing, heating, electrical, farming, automotive and small engine repair. There is plenty more but you get the idea.