Thursday, January 27, 2005

ATI Radeon 7000/VE Dual head configuration

I have Sony 20" LCD alongside a 17" Nec MultiSync both being driven by a single ATI Radeon 7000/VE. Needless to say I prefer my 20" to my 17", but anyway here is the configuration that I used to make them both work at the same time:

# Xorg configuration created by system-config-display

Section "ServerLayout"
Identifier "Multihead layout"
Screen 0 "Screen0" LeftOf "Screen1"
Screen 1 "Screen1" 0 0
InputDevice "Mouse0" "CorePointer"
InputDevice "Keyboard0" "CoreKeyboard"
# Option "Xinerama" "on"
# Option "Clone" "off"
Option "Clone" "off"
EndSection

Section "ServerFlags"
Option "Xinerama"
EndSection

Section "Files"

# RgbPath is the location of the RGB database. Note, this is the name of the
# file minus the extension (like ".txt" or ".db"). There is normally
# no need to change the default.
# Multiple FontPath entries are allowed (they are concatenated together)
# By default, Red Hat 6.0 and later now use a font server independent of
# the X server to render fonts.
RgbPath "/usr/X11R6/lib/X11/rgb"
FontPath "unix/:7100"
EndSection

Section "Module"
Load "dbe"
Load "extmod"
Load "fbdevhw"
Load "glx"
Load "record"
Load "freetype"
Load "type1"
Load "dri"
EndSection

Section "InputDevice"

# Specify which keyboard LEDs can be user-controlled (eg, with xset(1))
# Option "Xleds" "1 2 3"
# To disable the XKEYBOARD extension, uncomment XkbDisable.
# Option "XkbDisable"
# To customise the XKB settings to suit your keyboard, modify the
# lines below (which are the defaults). For example, for a non-U.S.
# keyboard, you will probably want to use:
# Option "XkbModel" "pc102"
# If you have a US Microsoft Natural keyboard, you can use:
# Option "XkbModel" "microsoft"
#
# Then to change the language, change the Layout setting.
# For example, a german layout can be obtained with:
# Option "XkbLayout" "de"
# or:
# Option "XkbLayout" "de"
# Option "XkbVariant" "nodeadkeys"
#
# If you'd like to switch the positions of your capslock and
# control keys, use:
# Option "XkbOptions" "ctrl:swapcaps"
# Or if you just want both to be control, use:
# Option "XkbOptions" "ctrl:nocaps"
#
Identifier "Keyboard0"
Driver "keyboard"
Option "XkbModel" "pc105"
Option "XkbLayout" "us"
EndSection

Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "IMPS/2"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5"
Option "Emulate3Buttons" "no"
EndSection

Section "Monitor"
Identifier "Monitor0"
VendorName "Monitor Vendor"
ModelName "LCD Panel 1600x1200"
HorizSync 28.0 - 90.0
VertRefresh 60.0 - 60.0
Option "dpms"
EndSection
Section "Monitor"
Identifier "Monitor1"
VendorName "Monitor Vendor"
ModelName "LCD Panel 1280x1024"
DisplaySize 410 310
HorizSync 31.5 - 67.0
VertRefresh 50.0 - 75.0
Option "dpms"
EndSection


Section "Device"
Identifier "Videocard0"
Driver "radeon"
VendorName "Videocard Vendor"
BoardName "ATI Radeon 7000"
BusID "PCI:1:0:0"
Screen 0
EndSection
Section "Device"
Identifier "Videocard1"
Driver "radeon"
VendorName "Videocard vendor"
BoardName "ATI Radeon 7000"
BusID "PCI:1:0:0"
Screen 1
EndSection

Section "Screen"
Identifier "Screen1"
Device "Videocard0"
Monitor "Monitor1"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Modes "1600x1200"
EndSubSection
EndSection

Section "Screen"
Identifier "Screen0"
Device "Videocard1"
Monitor "Monitor0"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 16
Modes "800x600" "640x480"
EndSubSection
SubSection "Display"
Viewport 0 0
Depth 24
Modes "1280x1024" "1280x960" "1152x864" "1024x768" "800x600" "640x480"
EndSubSection
EndSection


Section "DRI"
Group 0
Mode 0666
EndSection


For whatever reason having the NEC as the second screen would cuase Xorg to delete the second screen and unload the driver to run it, but when switched around everything was hunkydory.

Unix Script to report network listeners

Some folks at worked were having problems with thier server visibility so I suggessted something like:

#!/bin/bash
TMPFILE=`/bin/mktemp`
ADMINS="linux-support@yourdomain.com"
BOX=`/bin/hostname -s`
/usr/sbin/lsof -i -n -P | /bin/grep '(LISTEN|UDP)' > $TMPFILE
/bin/cat $TMPFILE | mail -s "Network listeners for box $BOX" $ADMINS
[ -f $TMPFILE ] && /bin/rm -f $TMPFILE

Concerned about information disclosure? That's cool just add
TMPMAIL=`bin/mktemp`
cat $TMPFILE | gpg -e -a -r "Some Label for PGP enabled email user" > $TMPMAIL
cat $TMPMAIL > $TMPFILE

After the lsof line

Then at the end add
[ -f $TMPMAIL ] && /bin/rm -f $TMPMAIL

This could be its own script like /etc/cron.daily/linux_port_reporter.sh

Selecting a date range in Microsoft Access

I needed to select dates that fell within a range today and today - 30 days using Microsoft Access.

Initial questioning made me think I could make use of mysql type dates like
"2004-01-27". No such luck so looking for a good function I found that Now() like in most DBMS provides a current timestamp. I later discovered that Microsoft Access treats this object special and as such you can perform calculations on Now().

The simple little query that I used consisted of the following:

Select Username, Lastupdate from Employee where
Lastupdate Between Now() and Now()-30;

References: www.microsoft-accesssolutions.co.uk/select_birthday.htm

Wednesday, January 26, 2005

Parsing unix date with perl

I recently had a need to parse pretty "date" like: Wed Jan 26 19:39:50 PST 2005

I wanted to turn this back into unix time like: 1106797190

I found a wonderful module on cpan Date::Parse that can do this in one function :D

So you could do something like:
perl -MDate::Parse
$date = "Wed Jan 26 19:39:50 PST 2005";
$time = str2time($date);
print "$time\n";

Wednesday, January 12, 2005

It recently came to my attention that bash numerical comparison operators "-lt -gt -eq -ne", are not capable of comparing non integer numbers. As a result the statement:

one=1.2
two=2.1
if [ $one -lt $two ]; then
echo "One is less than two";
fi

The way to deal with this problem is to make use of ascii comparison although I'm not entirely certain this solves all cases it worked for the case I was trying to use it under.

Your ending statement would look like

one=1.2
two=2.1
if [[ "$one" < "$two" ]]; then
echo "One is less then two"
fi

You need make use of the double [[ or escape the comparison operator as with a single [ the comparison operator is interpreted by the shell so you would end up with a syntax error.

Tuesday, January 11, 2005

Shell script performing comparisons on decimals

It recently came to my attention you cannot make use of typical numeric comparison operators -gt -lt -eq -ne on float point numbers.

The test case

#!/bin/bash

one=1.2
two=2.1

if [ $one -lt $two ]; then
echo "One is smaller than two"
fi

The error you'll produce will go like: "bash: [: 1.2: integer expression expected"

So you need to make use of ascii comparison operators in order to work around this problem. I'm not sure of all the implications of such an action, but for the cases I needed it to work it did :)

So your test would end up looking something like

one=1.2
two=2.1
if [[ "$one" < "$two" ]]; then
echo "One is smaller than two"
fi

Note: You need to make use of double "[" or escape the comparison operator otherwise the shell will interpret the comparison operator as an input redirector, and you'll end up with an error like: "bash: 2.1]: No such file or directory".

Monday, January 10, 2005

Doing date calculations in bash shell arrays and looping and stuff

I was working with a set of files, and some of them had unix epoch time entries for start and stop time. I wanted to calculate the number of days between start and stop. I cobble together the following code chunk that provides the facility for just that.

FILES=( `find run -type f -name "D*" -mtime -20 -print`)
#obtain the files used in the run
counter=0
while [ ${FILES[$counter]} ]; do
STARTTIME[$counter]=`grep -P 'S:\d{3,}' ${FILES[$counter]} | cut -f 2 -d ":" `
#throw start time into its own array
ENDTIME[$counter]=`grep -P 'T:\d{3,}.*Done' ${FILES[$counter]} | cut -f 2 -d ":" `
#throw end time into its own array
if [ ! ${STARTTIME[$counter]} ]; then
echo "ERROR: Variable STARTTIME not defined in file: ${FILES[$counter]}"
elif [ ${ENDTIME[$counter]} ]; then
TOTALTIME[$counter]=`echo "scale=2;( ${ENDTIME[$counter]} - ${STARTTIME[$counter]} ) / 86400"| bc `
#since both start and stop time exist calculate using "bc" to 2 decimal places.
#Note the use of scale=2 in the echo.
#This was determined to be the shortest way to implement the calculation.

else
echo "ERROR: Variable ENDTIME not defined in file: ${FILES[$counter]}"
fi
let counter=$counter+1
done

Wednesday, January 05, 2005

Printing the largest number in a bash or ksh shell array

I was in need of a shell sort script that allowed me me to print out the largest number in a ksh or bash shell array.

The following example displays how to print the the number of lines from a file in your home directory with the largest number of lines.

#!/bin/bash
counter=0
STARTT=( `find $home -type f -exec wc -l {} \; | cut -f 1 -d " " ` )
big=${STARTT[0]}
while [ ${STARTT[$counter]} ]; do
if [ $big -lt ${STARTT[$counter]} ]; then
big=${STARTT[$counter]}
fi
let counter=$counter+1
done
echo "of $counter items the largest is: $big"

gnu grep is -Perfect

I wanted to use grep recently and needed to grab a couple of lines using a regular expression that I knew would work in perl, but I couldn't make work in egrep functionality.

A little trolling through the man page pointed me to the -P option which provides perl like regular expression capabilities.

All of a sudden you have access to things like \d{3,6} and other perl regex niceities.

No more cat | perl -ne 'chomp($_);print "$_\n" if(/^\d{3,9}\s+\w+/);'

grep -P is perfect