Linux Tutorial

(Author: Manfred Schmid)
Last update: 19 Jun 2009


This tutorial is based on Redhat Linux 7.3 (RH7.3) ,Redhat Linux 9 (RH9) and Redhat Fedora Core 9 (FC9).
This tutorial deals mainly with using Linux in an embedded system rather than in a desktop system.

New Topic: uClinux for Altera Nios2


Commands are written with a fixed size font with an Cmd: indicator symbolizing the Command prompt.
Lines in a file are diplayed in blue color.
Paths and files are displayed in italic.
Text to be entered in edit boxes is displayed in red.





Simple Topics

How to start a java archive

Cmd: java -jar <filename>

How to edit the search-path

File: /etc/profile
edit the PATH section (e.g: PATH = "$PATH:/usr/bin")
Note: path has to be exported add following line:
export PATH

add lines to /etc/profile like:
pathmunge /usr/lib/anaconda-runtime after
to add /usr/lib/anaconda-runtime to the path.

How to rename a file

Cmd: mv <old filename> <new filename>

How to delete a file or directory

Cmd: rmdir <directoryname>
remove with all contents:
Cmd: rm -r <directoryname/filename>

How to create a file or directory

Cmd: mkdir <directoryname>
creates a file with 0 Bytes:
Cmd: touch <filename>

How to copy a file

Cmd: cp <filename> <destination>

How to create a symbolic link

Cmd: ln -s <source> <destination>

How to change file permissions

Cmd: chmod <permissions> <filename>
permissions can be a octal number or a string

Attributes: kuuugggooo
k........type (-...file,,, b...block) user-rights group-rights other-rights

each group is split into access modes: only (coding 0x04) (coding 0x02)
x....executable (coding 0x01)

octal number:
Sets all permission bits for a file or directory
e.g: permissions = 755 => -rwxr-xr-x (normal executable file): readable, writable and executable for u, readable and executable but not writable for g and o.
Cmd: chmod 755 <filename>

More flexible. It is possible to set a single permission bit and leave the others untouched.

permissions are set by specifying first user, group or other with u, g or o, then if the permission should be added or subtracted by setting + or - and last which access modes x,w or r are affected.
e.g: permissions = u+w => changes the permissions for the user to writable and does not change other permission bits.
Cmd: chmod u+w <filename>

How to show the process-list

Cmd: ps ax

How to use vi

A................Insert mode
i..................Insert mode
Esc.............End insert mode
:x................Save & Exit
u.................Undo (not in insert mode)
[#]dd..........Delete line
v.................Mark line with cursor (visual mode)
d.................Delete block
n..................Find next
:g/search-string/s//replace-string/g......Search and Replace

Up to RH9 vi showed DOS line endings as ^M, which was useful to find out problems when working in a mix between Windows and Linux environment.
In FC4 vi does autodetect of line endings and fills in line endings according to the file format. The ^M does not show up anymore by default.
To reenable this feature do following:
In your home directory create a file .vimrc if it is not already present.
Add a line
:set fileformats=unix

How to interpret colors and signs

dark blue.....Dir
light blue......Link

How to view log-files

Cmd: tail -f -n# <logfile>
n.......number of lines
<logfile>....location: /var/log/*.log

How to find out the current runlevel

Cmd: runlevel

If you need to change the default runlevel go to /etc/inittab

How to reboot

1) Ctrl+Alt+Del

2) Cmd: init 6

3) Cmd: reboot

How to check the network-interface

1) RedHat automatically installs the network-interface

2) Check hardware
in /proc/pci
you find your network-interface in section:
Ethernet controller.
In /etc/conf.modules or /etc/modules.conf
there should be following line present:
alias eth0 tulip
tulip stands for an network-interface of Tulip

in /etc/sysconfig/network-scripts/ifcfg-eth0
has to be set.

in /etc/hosts
only the line for the localhost should be present.

RedHat Release < 7.0 by default starts pump instead of dhcpcd.
This causes that the leasetime is ignored and you get a new IP-address after each reboot.
Change the default by editing
replace pump by dhcpcd by exchanging the if else condition.
RH9 starts dhclient instead of dhcpcd.

4) test
Cmd: ifconfig
lists all interfaces and shows you the IP-Address assigned from DHCP-server.
If you had no conection to the network while starting the PC, restart the network.
Cmd: /etc/rc.d/init.d/network restart

How to search a file

Cmd: find / -name <filename>

How to use FTP downloading a package

Cmd: ftp <servername>
Example: ftp
User: anonymous
Password: <your Email adress>
walk through the dirs using ls and cd
Cmd: get <filename>
Example: get ppp-2.2.0f-1.i386.rpm
Cmd: bye

How to add a library to the library searchpath

As an example let us add: /usr/local/lib
Edit file: etc/
add line:
at the end of the file.
run ldconfig.
Cmd: ldconfig

How to recover from forgotten root password

If you have forgotten the root pasword, there are 2 possibilities to recover:
1) Using LILO or grub: boot as linux single. You get a shell to change the password.
2) boot with a bootdisc

ad 1) booting with grub in single user mode
When the logo appears press escape and then e for edit commandline.
Choose the option that starts with kernel press e again and type single
Press enter to leave edit mode and boot with b

You can change the root password with
Cmd: passwd

How to find installed rpm packages

Cmd: rpm -qa

How to install a rpm package

packet present in form of a package .rpm or an archive .tgz
Cmd: tar xzvf <filename>
f...filename will follow


Cmd: rpm --install <filename>

or short

Cmd: rpm -i <filename>

uninstalling a rpm:

Cmd: rpm -e <package name>

How to unzip a tarball

tarballs have the file ending tgz, tar.gz or bz2

tgz and tar.gz
Cmd: tar xzf <filename>
f...filename will follow

Nowadays this format gets more popular, because it has higher compression than tgz, unfortunately Winzip does not support it.
Cmd: tar jxf <filename>
j...bzip2 archive
f...filename will follow

Advanced Topics

How to build a rpm package with a spec file

Cmd: rpm -ba <specfilename>
Cmd: rpm -bb <specfilename>

Cmd: rpmbuild -ba <specfilename>
Cmd: rpmbuild -bb <specfilename>

ba....builds the rpm with source files
bb....builds the rpm without source files

A spec-file is used to define the steps needed for installation.
It consists of different sections:
Summary:<description eg mypackage for test>
Name: <package name eg mypackage>
Version: <Version eg 1.00>
Release: <Release eg 1>
Requires: <list here all dependencies separated by colons eg apache,xinetd>
Copyright: <description eg Public Domain>
Group: <group name eg System>
URL: <url eg>
Distribution <name of distribution eg mylinux>
Vendor: <vendor name eg mycompany>
Packer: <emailaddress of packer eg>
<description of package>
<delete old files here eg rm -f /usr/bin/file>
<copy files from server to directories where they should reside eg cp <network>/file /usr/bin/file>
<change owner and permissions>
<list files to be installed eg /usr/bin/file>
<write shellscriptcommands what should happen after install eg change some configfiles>
<uninstall information.
files that are mentioned in %files are automatically uninstalled.
You have to decide between install and update of a rpm.
Use $1 to decide. 0...uninstall, other value = update>

How to install net-snmp

1) download ucd-snmp-4.2.6.tar.gz from
(sources have normally the ending tar.gz)
place it in /home/username

2) unzip the package
Cmd: tar xzf filename
f...filename will follow
a directory-structure named ucd-snmp will be created

3) view configure
change into this new directory
Cmd: ./configure --help
interesting is the --prefix (path where binaries will be placed)

4) configure
Cmd: ./configure
we leave the default path /usr/local

5) make
Cmd: make

Note: There is an incompatibility problem with a function of the openssl library which causes scapi.c failing to compile.
In order to compile you need to comment out the memset in line 612 and 725.

6) make install
Cmd: make install

7) snmpconf
Cmd: snmpconf
menu guided configuration
important: create snmpd.conf (choose Agent Operation Mode: Master and agentx)
important: create snmp.conf (choose directory for private MIB , see FAQ of netsnmp)

Altenatively create snmpd.conf with vi (those 3 lines are probably all you need):
rwcommunity private
rocommunity public
master agentx

run snmpd with this file:
Cmd: /usr/bin/snmpd -C -c /usr/share/snmp/snmpconf/snmpd.conf

8) execute
check the binary for needed libraries
Cmd: ldd snmpd
if needed install libraries not found then
copy the binary snmpd to the /usr/sbin directory

add service to the init-scripts

Note: MIBs
standard MIBs can be found in /usr/local/share/snmp
These MIBs will be used by the snmp-tools

I used the latest ucd-snmp version 4.2.6:
Get my modified ucd-snmp-4.2.6-1.i386.rpm package from the download section.
Platform: RH9

How to use mib2c

1)install snmp perl
change to .../ucd-snmp/perl/SNMP directory
Cmd: perl Makefile.PL
Cmd: make
Cmd: make test
Cmd: make install

copy the mibs with ending *.txt into the directory /usr/local/share/snmp/mibs (only this directory will work!!!)
change the environmentvariable MIBS:
Cmd: export MIBS=ALL
run mib2c
Cmd: mib2c -f <outputfilename> oid-name
Attention: oid-name is not the mibs filename but the root oid in the MIB file.

Edit mib2c.conf and mib2c.vartypes.conf to adjust the code output to your needs.

The translation from mibs to c code is limited to 256 scalar variables. This is because the variabe vp->magic is of type uchar
In order to get rid of this limitation it is necessary to change the type to uint and it is necessary to recompile the agent.
You need to change the variable magic from type uchar to uint in following files:
I use the static libraries for my subagent which are:

How to enable SNMPv3

Enabling SNMPv3 with ucd-snmp or net-snmp is done with a few lines in the snmpd.conf file.
rwcommunity private
rocommunity public
master agentx
gives you what is necessary to run SNMPv1 and SNMPv2c.
To add SNMPv3 capability following lines are needed for each user:
rwuser USER [noauth|auth|priv]
createUser USER (MD5|SHA) authpassphrase [DES] [priv- passphrase]
for example add a user with no authentication and no password:
rwuser cust noauth
createUser cust MD5 custpassword DES
an example for a user with authentication and encryption would be:
rwuser cust2 auth
createUser cust2 MD5 cust2password DES

Warning: the minimum pass phrase length is 8 characters.
It is a good idea not allow SNMPv1 and SNMPv2c access because this would compromise the security.
Therefore delete the rwcommunity and rocommunity lines .

How to start a service (systemV init process)

1) runlevels
supported runlevels in a systemV:
0: shut down
1: single user
2: multi user
3: multi user with network
4: ---
5: multi user with network and X (GUI)
6: reboot
Cmd: init <runlevelnumber>

copy a script and rename it.
Scripts are found in /etc/rc.d/init.d
enter the new servicename in the start and stopsection.

start possibilities: daemon <service> or <service>
daemon starts service only if its not running.

stop possibilities: killproc <service> or killall <service>
killproc stops service only if its running.

edit line:
# chkconfig: <runlevels> <startpriority> <stoppriority>
Rule: startpriority + stoppriority = 100
1...high priority
99...low priority

startsection in script: adds service to /var/lock/subsys/ and starts it
stopsection in script: deletes service in /var/lock/subsys/ and stops it with killall

You can make use the functions for your own purpose.
The line
. /etc/rc.d/init.d/functions
makes these available for you.
You can use the echo_success or echo_failure to print out the [OK] or [FAILED] messages.

The start of the subsystem is controlled by the script /etc/rc.d/rc
You can investigate this script if something is not started as expected.
Issues are:
a) Messages of your init script are not printed to stdout during booting.
b) Your service is started twice.

ad a) rc does a grep for the keywords "action,failure,success,daemon" followed by a space character.
If your script does not contain these keywords then it is started using "action" by the rc script (the stdout is controlled by action then, your messages are sent to the logger).
Note: I got caught by the space that needs to follow. (e.g.: I called echo_success on a single line followed by a newline instead of a space, I had to call echo_success #some comment to get my echos to work)

ad b) A service can be started twice in case of fault (depending on the return value of the startup script).

4) start
chkconfig does all the work for you.
Chkconfig creates the symbolic links necessary for the different startlevels.
Cmd: chkconfig --list
shows a list of services (after creation of service state is off)
Cmd: chkconfig <servicename> add
adds the service to the list of available services
Cmd: chkconfig <servicename> on
Inserts the service with the runlevels offered in the startupscript.
Service is started with
Cmd: /etc/rc.d/init.d/<servicename> start
path is necessary, otherwise not script but binary will be started.
Cmd: service <servicename> start

If there is no chkconfig the links must be added by the user for each startlevel.
startupscripts are located in /etc/rc.d/init.d
in rc.d you find the runlevedirectories.
In rc0.d all services that should run in runlevel 0 are inserted.
There exist symbolic links for each service:

S......start service
##....start order
servicename...must be the same as service

K......stop service
##....stop order
servicename...must be the same as service

Services must be added in /var/lock/subsys (done by startupscript)
Note: the entry is a file with the lenght of 0 Byte (created with touch).
The file will be deleted when the service is stopped.

rc in /etc/rc.d handles the services when runlevels are changed.

How to create an iso image

mkisofs -b images/boot.img -c -o ../<name>.iso -J -R -T -l -V<label> .

-b...boot image and location of output file
-J...Jolliet extensions
-R...Rock ridge extensions
-T...Create the TRANS.TBL files
. ...current directory

How to create a customized Redhat CD using kickstart

You will need 2 machines to to this task.
The 1st machine functions as build server.
The 2nd machine is our target server for testing the new distribution.
The first part (step 1) is different for RH7.3 and RH8 or RH9.
The difference is that the comps file comes as xml file in RH8 and RH9.
The second part (step 2) is the same for above distributions.

1) base packages

1a) RH7.3

Take Redhat CD #1 (Version 7.3).
Copy the whole CD onto the harddrive of the build server..
Delete all packages not needed from the RedHat/RPMS. (these are all packages except the ones from the Base group)
Edit the RedHat/base/comps file.
In this file only packages that are found on the 1st Redhat CD are allowed.
Delete every section except Base.
Delete all language related items. (leads to exception if package not found on 1st CD)

1b) RH8, RH9

Take Redhat CD #1 (Version 8.0 or 9.0).
Copy the whole CD onto the harddrive of the build server.
Delete all packages not needed from the RedHat/RPMS.(these are all packages except the ones from the Base, Core and Dialup group)
Run the genhdlist script. (see section below)
Edit the RedHat/base/comps.xml file:
Comment out all groups except Base,Core and Dialup.
Comment out packages not needed in above groups.
Delete the <package> section.
The package dependencies cannot be edited by hand you need a special script to compute this section.
The script can be found at /usr/share/comps-extras/
The original script needs to be run like this:
Run '/usr/share/comps-extras/ comps.xml /path/to/tree arch'
where /path/to/tree is the path to the base of your Red Hat Linux installation tree and arch is the architecture the tree is for. Note that this assumes that comps.xml exists as '/path/to/tree/arch/RedHat/base/comps.xml'. Redirect the output to a temporary file.
Unfortunately this script requires a directory structure which does not match the original structure of the 1st Redhat CD.
Because we want to maintain this structure without an "arch" directory added, we need to modify the script.
Remove the arch in lines: 22,24,60 (Note: dont forget to remove the %s either).
Save the new script as and make it executable.
Cmd: ./ comps.xml /path/to/tree i386 > pkg_list
Resolve all package dependencies by adding needed packages or remove unnecessary in RPMS.
After any change in the RPMS directory you need to run the genhdlist again.
Take the package list pkg_list finally and add it to the comps.xml file.

2) build new system and minimize space used on CD

You can try to make a CD now. You have to recompile the hdlist if you have changed packages in the RPMS directory.
Recompile the hdlist:
Use the package anaconda-runtime from the 2nd CD to obtain genhdlist.
Add genhdlist to your system PATH. (add /usr/lib/anaconda-runtime)
Run genhdlist.
Cmd: genhdlist --withnumbers --hdlist <dir of hdlist> <path to CD>
Use mkisofs to create the CD.
Test the new distribution on the target server.
Troubleshooting: if the RPMS, hdlist and comps do not match anaconda throws an exception.
- Scroll down to the end of the errormessage to find the missmatch.
If the installation on the target server is successful, you can log in to your new distribution and view the file /root/install.log
This file tells you which packages have been installed on your system.
Go back to your RPMS directory and remove every package not mentioned in install.log.
You now have saved as much space on your CD as you can.
Test the minimized system.

3) add own packages to RPMS

3a) RH7

Create your own section in the comps file (1 MyPackages{<packagename>}).
Add this package to your ks.cfg file.

3b) RH8,RH9

Make a new group in the comps.xml file.
Do this by copying one of the groups (e.g dialup)

Add your package names into your new group in the comps or comps.xml file.
Copy your packages into RedHat/RPMS.

Write the kickstart-file (described on the Redhat homepage).
Copy the ks.cfg to the CD-dir (into the root).
Change the boot.img so that boot-parameters automatically been chosen.
Boot parameter: linux ks=cdrom:/ks.cfg
Make the final isoimage.

How to change boot.img

Take the Redhat CD #1 and insert it to a PC with MS Windows.
Use rawritewin.exe in /dosutils/rawritewin.
After you started the program choose file boot.img to write to the floppy.
Edit the file Syslinux.cfg.
Change in the first line default to ks:
default ks
change the timeout:
timeout 1
and edit the ks sector:
label ks
kernel vmlinuz append ks=cdrom:/ks.cfg initrd=initrd.img lang= devfs=nomount ramdisk_size=8192

Change to a PC with Linux.
Mount the floppy.
Create a file boot.img with following command:
Cmd: dd if= /dev/fd0 of =/boot.img

How to configure samba for read/write access of a dir

The samba configuration file will be found at /etc/samba/smb.conf
change the following lines:
workgroup = BPD #workgroup you are in
security = share #share level security without password
in section for directories add:
path = /home
writable = yes
guest ok = yes
guest account = root

#In Windows you will see the directory /home as public with full read/write access

Instead of guest account = root, which is a security risk, the account of existing users on the Linux machine can be used.
guest account = some user
In order to get files and directories created on the windows machine to be owned by "some user" and not by "nobody" add following:
force user = some user
force group = some group

To create default permissions add:
create mask = 664
directory mask = 775

Note: comment the printer sections out as well as the master browser sections (to avoid Linux taking control over your printers)
Set following entries to "no" in order not to interfere with Windows master browser service:
local master = no
preferred master = no
domain master = no
domain logons = no

How to install comm.jar and RXTX drivers for Java serial connectivity

This build is to run on a i386 based system with JRE 1.2 or higher (Examples are for J2SDK 1.4.2), and RXTX 2.0.5. The compiles needed to build it require the Java 2 SDK, and the GNU Posix libraries.
The following packages are used to build rxtx:

install javax.comm:
copy comm.jar to /usr/java/j2sdk1.4.2/lib/ext/comm.jar
The file will be automatically generated by RXTX later.
It should be copied to /usr/java/j2sdk1.4.2/lib/

RXTX build:
Make sure your JAVA_HOME environment variable is set to you Java directory
Cmd: export JAVA_HOME=/usr/java/j2sdk1.4.2
expand rxtx-2-0-5.tar.gz
Cmd: tar -xzvf rxtx-2.0-5.tar.gz

From the new folder enter these commands:
Cmd: configure
Cmd: make install

Follow any prompts or questions that come up.

Finally the following 5 files are needed to setup the serial driver:

How to configure apache

Change document root:

This is the directory where your html files reside.
1) edit httpd.conf.
Search for DoumentRoot and change the path to your needs or leave it default (/var/www/html)

Add password protection for certain documents:

A) Basic Authentication

1) First you create a password file with the program htpasswd
Cmd: htpasswd -c /usr/local/bin/users admin
users is the filename and admin is the first user, you are prompted to enter a password for admin.
You can add additional users with the same command without the -c option.
2) The documents you want to protect must reside in a subdirectory, because you can only protect directories.
3) You need to create a .htaccess file in this directory. (pay attention to the dot!, it is necessary)
4) following lines must be in this file:

AuthName "some name"
AuthType Basic
AuthUserFile /usr/local/bin/users

require valid-user

5) edit httpd.conf
change AllowOveride to
AllowOveride AuthConfig

Hint: The .htaccess file does not appear when you use ls , use ls -a

B) Digest Authentication

A more secure logon than Basic authentication which uses only a slightly scrambled password which could be figured out with some skill.
To upgrade from Basic authentication following steps are needed.
1) Replace AuthType with Digest

AuthType Digest

2) Replace AuthUserFile with AuthDigestFile

AuthDigestFile /usr/local/bin/users

3) The password for Basic authentication and Digest authentication are not compatible.
If you use the htpasswd generated password you get an error message like this:
Digest: user 'admin' in realm 'myrealm' not found:
A new command is used to generate the password for digest authentication
Cmd: htdigest -c /usr/local/bin/users myrealm admin
users is the filename, myrealm is the realm name (myrealm must match the name in AuthName "some name")

AuthName myrealm

and admin is the username. You are promted to enter the password for admin.

Note: htpasswd offered the possibility to enter the password on the commandline with the -b option, so you could use it in a shell script. htdigest does not offer
this option. So I recompiled it and added this capability. You can download the new version as an rpm, which will install a 2nd version of htdigest with the name
my_htdigest in /usr/bin. Call my_htdigest instead of htdigest if you need the commandline password option. (download section)

I testet Digest Authentication on IE6 and Netscape 7.1

However IE6 has a bug:
If a request url has a query string attached then you get a server error message.
Query strings are handled wrong in IE6.
example for a query string is:
If you can upgrade to apache 2.0.51 then there is a workaround provided
BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
into your .htaccess file.
RH9 runs apache 2.0.40 and therefore you are out of luck.
We worked around by using Basic Auth in case a query string is needed.

Customize error messages:

This is very easy.
a) There is a new directory /var/www/error
You can modify the files there. This has the advantage that language specific messages will remain.

b) edit the httpd.conf file and point to your own error html files. Create own files in /var/www/error

module mod_unique_id:

This module is by default disabled.

This module is by default enabled.
This may lead to following error message in your /var/log/httpd/error_log
[alert] (22002)Name or service not known: mod_unique_id: unable to find IPv4 address of "your hostname"
Configuration Failed!

There are two fixes that will work:
a) disable the module in the httpd.conf by commenting out the line where mod_unique_id is loaded. (This is recommended by me) or
b) if you really need this module for instance to run clusters of apache:
Enter following line into your /etc/hosts file:     "your hostname"
Of course it is also possible to update the IP address of your machine in the hosts file dynamically, but I found so far that its not needed.

How to configure as DDNS client

For DDNS (dynamic dmain name service) following needs to be present in your network.
A DHCP server and a DDNS server.
When a client conncts to the network following should happen:

1) The client is configured as DHCP client and asks for an IP address.
2) The DHCP server assigns an IP address and other information to the client (a hostname can be one of those and the domainname)
3) The DHCP server tells the hostname to the DNS server.

A) using dhcpcd (RH7.3)

Changing the hostname:

1) The hostname needs to be entered in /etc/sysconfig/network

HOSTNAME = <localhost.localdomain>
DHCP_HOSTNAME = <localhost.localdomain>

2) The DHCP_HOSTNAME forces dhcpcd to send the hostname to the DHCP server

3) Lease release

cmd: dhcpcd -k eth#

4) Lease renew

cmd: dhcpcd -n -h localhost.localdomain eth#

5) you should be able to ping the computer by its name now.

B) using dhclient (RH8, RH9)

Changing the hostname:

1) The hostname needs to be entered in /etc/sysconfig/network

HOSTNAME = <localhost.localdomain>
DHCP_HOSTNAME = <localhost.localdomain>

2) The DHCP_HOSTNAME forces dhcpcd to send the hostname to the DHCP server

3) Lease release

cmd: dhclient -r -q -pf /var/run/ eth#
-q...suppress stdout except for errors
-pf...location of pid file (necessary to specify if there is more than one NIC in the system, with eth0 only you do not need this argument)


delete the leases file /var/lib/dhcp/dhclient-eth#.leases (this is necessary with some DHCP-DNS servers)


You need to have a file /etc/dhclient.conf with following entry
send host-name "hostname.domainname";

4) Lease renew

dhclient -1 -q  -lf /var/lib/dhcp/dhclient-eth#.leases -pf /var/run/ -cf /etc/dhclient.conf eth#
-1...send the lease only once
-q...suppress stdout except for errors
-lf...location of lease file
-pf...location of pid file
-cf...location of configuration file

5) you should be able to ping the computer by its name now.

How to install a timeserver

You need to install the packages ntp and libcap.

If you start the ntpd with dhcpcd running and a valid IP address, then the dhcpcd automatically
generates the ntp.conf configuration file.

If you dont like this you have to start the dhcpcd with -N option or
start the ntpd with -c <my own configfile>
You can edit the options in /etc/sysconfig/ntpd
Note: quotes are necessary for the option line, without quotes everything gets ignored (bug?)

In order that you get the right time displayed you need to enter the correct timezone.
If the correct timezone is entered the system clock automatically adjusts to daylight saving time.
You have 2 choices for the system clock. It can run on UTC or on local time.
I prefer to let it run on local time.
Check the Flag in /etc/sysconfig/clock
is the value for system clock on local time.
set the timezone with
Cmd: timeconfig <timezone>
dont use the -utc option because this will set the sytem clock to UTC time.

Because there are many timezones available under Linux that are redundant,
I picked out the ones used on Windows OS to get a shorter list to offer in my perlscripts:


If you get an error message like:
ntpd: Synchronizing with time server: [FAILED]
This means that the timeserver probably cannot be reached.
a) Try to ping it.
b) check your gateway.
Cmd: route -n


The cmd: timeconfig <timezone>
does no longer work in RH9. For some reason the version without GUI has been deprecated.
You need to manipulate the zone file directly, which I admit is not a very nice solution but I could not find a better way.
Replace the above command with following workaround:
Cmd: echo -e "ZONE= <timezone>'\n'UTC=false'\n'ARC=false > /etc/sysconfig/clock"
Cmd: ln -sf /usr/share/zoneinfo/<timezone> /etc/localtime

How to install Perl GD

GD is a graphical library used to draw pictures on the fly. There exists a perl module that allows you to use the GD library.
The module is called With you can compute graphs on the fly out of a cgi script.


Following packages need to be installed (the order reflects the dependancies):
-perl (perl-5.6.1-34.99.6.i386.rpm)

-freetype (freetype-2.0.9-2.i386.rpm)
-libjpeg (libjpeg-6b-19.i386.rpm)
-libpng (libpng-1.0.12-2.i386.rpm)
-gd (gd-1.8.4-4.i386.rpm)
-XFree86-libs (XFree86-libs-4.2.0-8.i386.rpm)
-perl-GD (perl-GD-1.33-1.i386.rpm)


same packages but newer versions (perl v=2.8.0)
-perl-GD (perl-GD-1.41-1.i386.rpm)

install the from the download section in your cgi-directory of the webserver and try to get it working.
Dont forget to set the right permissions and change the script header so that it points to your perl program.

How to install a dhcp-server and set up masquerading

You will need a hardware with 2 network interfaces.
The 1st gets its IP as a dhcp-client (assuming this is eth1).
The 2nd is used for our local network and acts as dhcp server (assuming this is eth0).
In order to set up a dhcp-server you need to install the package dhcp.
Get the sample dhcpd.conf file and put it to /etc
Change the contents of dhcpd.conf:
-set the network
-set the DNS-servers (comma separated list. These are the DNS-servers you get by dhcp on eth1, you pass them through)
-set the dhcp range
-change the leasetime (default = 1day)
Because we want to run the dhcp server on eth0 we need to set a parameter for the dhcpd.
Set DHCPDARGS in /etc/sysconfig/dhcpd to
The dhcp server should work now after you enabled the service in chkconfig.

there is a new parameter needed for the dhcpd.conf file to be compatible with RH7.3
Add it at the top of the file:
ddns-update-style none;

For masquerading enter the following lines:
Cmd: iptables -F; iptables -t nat -F; iptables -t mangle -F
Cmd: iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to
Cmd: echo 1 > /proc/sys/net/ipv4/ip_forward is an example of the IP address you got assigned on eth1, so put your IP address there.

In order to have these settings permanent after reboot you have to write a service that calls these commands. (See how to start a service)

How to use sudo

Sudo is a program that lets users execute a command as superuser (root) without knowing the root password.
The commands which can be executed are entered in the /etc/sudoers file.
Edit the sudoers file with visudo. visudo checks the file for syntax errors and sets the right permissions.

Example 1:
Lets presume a user named cust needs to watch the log file /var/log/messages which is only readable by root.
Add following line at the end of the sudoers file:
cust           ALL=NOPASSWD: /usr/bin/less    /var/log/messages

ALL....allowed on all machines
NOPASSWD...user is not asked for a password again (if you use password the user has to enter his own password not
the password of root)
/usr/bin/less.....allowed command (must be entered with the full path)
/var/log/messages....allowed file to access

User cust can run the command by invoking
Cmd: sudo less  /var/log/messages

Example 2:
Sometimes it is necessary that a cgi script has to do a job like zipping a file and make it available in document root.
Apache needs to have root access to the zip program.
apache       ALL=NOPASSWD:/usr/bin/zip     /var/www/html/messages    /var/log/messages
Cmd: sudo zip /var/www/html/messages    /var/log/messages
This command will zip the messages file and provide it in the document root directory for download.

Note: Be very restrictive on what is allowed. Be careful when allowing to use editors like vi or if you use wildcards.

How to install CVS

1) Create a repository
Run this command as root.
Cmd: cvs -d <repository directory> init
Example: cvs -d /var/cvs init.

2) Create a admin group
Cmd: groupadd admin

3) Create the admin user
Cmd: useradd admin -p <some name>
Replace the password with !! in /etc/shadow
The !! means that no password will be used

4) change the directory permissions of CVSROOT and let it be owned by admin
Cmd: chown admin CVSROOT

5) login as admin
Cmd: su admin

6) checkout the configuration files
Cmd: cvs -d <repository directory> checkout CVSROOT

7) change config
enable the lock file option
Cmd: cd [repository directory] CVSROOT
Cmd: vi config
Uncomment the line #LockDir=/var/lock/cvs

8) create the lockfile directory
Cmd: su root
Cmd: mkdir /var/lock/cvs
Cmd: su admin

9) change notify
enable emails for watches
Cmd: cd [repository directory] CVSROOT
Cmd: vi notify
Uncomment the line #ALL mail -s "CVS notification" %s

10) Create users and groups for the CVS clients
Groups may be made up by people working on the same project.
Set the users up that they dont have a password by using !!
Add a file invisible file .forward into their home directories containing their email address.

12) Download PuTTY and WinCVS (assuming you are working on a windows machine, otherwise search for the clients suitable for your platform)
Install those programs.

13) Set up SSH authentication.
In order that you do not need to put in a password for the server all the time when accessing the CVS server we need to set up SSH authentication.

14) open PuTTYgen
Set the type of keypair to generate to SSH1.
Warning: There are incompatibillity issues using SSH2 keys (These keys are somehow not compatible between client and CVS server)
Press generate.
Store the private key on your client in some folder.
Copy the public key to the CVS server into the users home directory under home/<username>/.ssh/ and rename it to authorized_keys
Create a short cut (link) for the Pageant (in the puTTY directory) add the private key as parameter in Target.
Example: "C:\Program Files\PuTTY\pageant.exe" h:\private_key\private.PPK
Put the link into the Autostart menu.

15) Configure WinCVS
Goto: Admin->Preferences
Globals tab:

Enter the CVSROOT: :ext:<username>@<hostname>:<repository directory>
Pay attention to the leading colon.
Set Authentication to: SSH Server

Ports tab:

check "Check for alternate rsh name:" and write plink into the edit box

Note: make shure that you added the puTTY directory to your Path variable.

16) add a new project
Create directories on the server for the project to import and change the group to the project's group
Goto: Create -> Import Module

Choose the project from your harddrive or networkdrive.
You need to enter something in "Vendor Tag": Suggestion: use the username here.
You need to enter something in "Release": Suggestion: use initial here.
The project should be copied to the server automatically after pressing ok.

Troubleshoot: Change the default protocol in PuTTY "Default Settings" to SSH (instead of Telnet)

17) Check out a project
1st time: Goto: Create -> Check out
2nd and more: Goto: Modify -> Update selection

18) Check in a project or file
Goto: Modify -> Commit

19) Installing the scc provider pushok
Pushok is an scc provider with which you can interface to programs like CodeWright.
Pushok is not freeware and costs $ 19 a seat, however you can get a 30 days trial registration.
Simply download the interface and integrate it to Codewright in VersionControl -> Setup.

How to copy files from 1 machine to another using scp

Cmd: scp [-r] <file or dir> root@<hostname>:<file or dir>
Example: scp -r /var/cvs
-r ... copy recursively

You have to put in the root password of the computer where you want to copy the files to.
In order to avoid putting in a password especially when you run the commands from a shellscript you can use key certification.

Create a keypair with ssh-keygen on machine 1 (your source)
Cmd: ssh-keygen -b1024 -tdsa
Answer all questions with ENTER.
You get 2 files id_dsa and in the directory .ssh in the home directory of the user.
Likewise: /root/.ssh/
copy the file to the target (destination) host into the home directory of the user and rename it to authorized_keys2.
2 represents ssh2 protocol. If you use ssh1 the name would be just authorized_keys
If the user is root the path is: /root/.ssh/

How to write to a port using /dev/port

If you need to write to a port in a shell script you can use /dev/port.
For example writing to the parallel port works as follows
Cmd: echo -e \001 | dd of=/dev/port bs=1 count=1 seek=888
This command writes a 1 to D0 of the parallel port.
\NNN is a character in octal when used the -e option of echo.
888 is the decimal value of 378, the parallel ports base address.

How to configure an ELO touchscreen display

ELO touchscreen drivers are supported by RH9 by default. All it needs is to add some necessary lines to the XF86Config file.
First of all connect the ELO display and run
Cmd: XFree86 -configure
Cmd: Xorg -configure
Add to the section "ServerLayout"

InputDevice "Elo" "SendCoreEvents"

Add a new Section "InputDevice"

Section "InputDevice"
   Identifier "Elo"
   Driver "elographics"
   Option "Device" "/dev/touchscreen"
   Option "AlwaysCore"
   Option "screenno" "0"
   Option "MinX" "369"
   Option "MaxX" "3757"
   Option "MinY" "434"
   Option "MaxY" "3586"
   Option "UntouchDelay" "16"
   Option "ReportDelay" "4"

The /dev/touchsreen needs to point to the serial port the touchscreen is connected to. Establish a softlink in the /dev directory.
The UntouchDelay, responsible for realizing when your finger left the control, has a wrong value in the recommendations found in other places in the internet.
Also the ReportDelay, which is responsibly first noticing a touch, is too sensitive.
You can play with these values, which have a range from 0 to 255 for best results, but we found the above values to be optimal after several tests.
The original values in these fields are too sensitive and let you sometimes end up with a sticky button that does not release.

The XF86Config file finally needs to be placed in /etc/X11 directory to take effect.

How to recompile and patch a SRPM package

If you just want to get the RPM from a SRPM type
Cmd: rpmbuild --rebuild <package>.src.rpm
After lots of output you find the RPM in /usr/src/redhat/RPMS

If you need to modify the package sources more work is required.
Install the SRPM package on your system with
Cmd: rpm -i <package>.src.rpm
You will find the results in 2 directories in the redhat rpm section.
/usr/src/redhat/SOURCES and
The <package>.spec file is used to rebuild the package.
In the SOURCES directory you find the source code in a gnu zip format.
Unzip the sources with
Cmd: tar xzf <package>.tar.gz
1 more step usually is required to get the make files needed for recompile.
If the makefiles are in a format lime you need to run the configure script
Cmd: ./configure
In order to make a patch later in the specs file you need to copy the complete package directory under SOURCES.
If the extracting <package>-1.0.tar.gz created a directory named <package>1.0 then copy it to <package>1.0p
Cmd: cp -r <package>1.0 <package>1.0p
Now its time to do your changes in the source code in <package>1.0p
When you are done you can create the patch for reconstructing the RPM and SRPM
Make the patchfile with diff using the u,N and r option
Cmd: diff -uNr <package>1.0 <package>1.0p > ../SOURCES/<package>1.0-my.patch
Now you need to add the patch to the specs file
There may be patches already listed in the specs file. If this is the case add your patch at the end giving it a higher number than the previous ones.
In the header section add
Patch#: <package>1.0-my.patch
Replace the # with the apropriate number (e.g. 0)
Pump up the release number by 1.
In the %prep section add
%patch# -p1
The "-p1" strips out directory levels from the patch file. "-p1" should be ok if you followed above rules.
Rebuild the package now with
Cmd: rpmbuild -ba SPECS/<package>.spec
This gives you a RPM and SRPM in the RPMS and SRPMS directory, ready for the next person to add a patch in the future.

How to setup a mail relay with sendmail

I assuming you can send mails with
Cmd: mail [email address]
for example:

Having this working we go on from there.
First of all we need to change a setting in /etc/mail/
By default port 25 is only open for localhost.
To open sendmail to all interfaces we need to comment out
dnl DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA')
The dnl actually is the command for comments, this is different from the usual # sign. The # sign in the sendmail config file is not a comment.

Sendmails config file is /etc/mail/
To create it we must compile the file.
Run the make in /etc/mail
Cmd: make
Test if the file /etc/mail/ is created by renaming it before running make.
If the file is not created or make comes back with an error, then you probably have the package sendmail-cf not installed which is required to do the compile.
Test if this package is installed by running
Cmd: rpm -qa sendmail-cf
If you got a new file you need to restart sendmail.
Cmd: service sendmail restart
Check if sendmail is open to all interfaces by running
Cmd: netstat -na | grep :25
The output should be this
tcp 0 0* LISTEN
Test if the hostname of your machine can be resolved
Cmd: host [hostname]
for example:
You need to enter the fully quallified hostname
The output should be something like this: has address
Relaying is turned off by default. (It was on my system)
You may enter trusted domains in the /etc/mail/relay-domains file
By default this file does not exist.
Create it with
Cmd: vi relay-domains
and enter trusted domainnames.
Restart sendmail again and it should work.

Test with telnet from a different computer:
open <hostname> 25
220 ESMTP Sendmail 8.12.8/8.12.8; Wed, 21 Sep 2005 15:27:18 -0400
250 2.1.0 Sender ok
250 2.1.5 Recipient ok
write some text

This should send an email to the specified email address.
More detailed information can be found at:

How to setup a Raid1

Motherboards tend to provide Raid fuctionallity. These so called fake Raids usually do not work with Linux.
The solution for Linux therefore tends to be software raid.
This article is a simple guide on how to setup a raid1 with 2 disks, how to test it and what problems may arise.
For FC9 disk druide is used.


3 partitions should be made /boot, / and swap.
The partitions /boot and / should go to the raid1.
2 SATA drives are used for the raid.

At the beginning one should see the harddrives /dev/sda and /dev/sdb with free space.
1) Select RAID => Create a software RAID partition
2) In the popup "Add Partition" select "sda" and set size to 1GB and select "Force to be a primary partition"
3) Repeat step 1 and 2 for the 2nd drive sdb
4) Select RAID => Create a RAID device
5) For mount point select /boot for members select sda1 and sdb1
6) Create a swap partition (does not reside on the raid)
7) Select NEW and create a swap partition with the size of the RAM on each harddrive
8) Follow step 1 to 5 for the /

Complete the Fedora installation and boot the computer without the Fedora setup CD.

Watch /proc/mdstat for building the raid arrays. Wait for this process to complete.
Finally all raid arrays should say:
mdx: active raid1 sdbx[1] sdax[0]
xxxx blocks [2/2] [UU]

Now the bootloader GRUB needs to be populated on both drives.
Cmd: grub
Cmd: grub> device (hd0) /dev/sda
Cmd: grub> root (hd0,0)
Cmd: grub> setup (hd0)

Cmd: grub> device (hd1) /dev/sdb
Cmd: grub> root (hd1,0)
Cmd: grub> setup (hd1)

Cmd: grub> quit

For monitoring the raid add email notification:

in /etc/sysconfig/network provide a valid domain name

in /etc/mdadm.conf enter your email address:
MAILADDR <your email address>

in /etc/init.d/mdmonitor add in start ( ) section after cd /
mdadm --monitor --delay=1800 /dev/md0 &

add a line for each mdx

Setup of the raid is now complete.


Fault an array:
Cmd: mdadm --manage --set-faulty /dev/mdx /dev/sdxx
Example: mdadm --manage --set-faulty /dev/md0 /dev/sda1

Remove array:
Cmd: mdadm /dev/mdx -r /dev/sdxx

Add array:
Cmd: mdadm /dev/mdx -a /dev/sdxx


Make a clone of sda and sdb with a disk clone program. Save this 2 harddrives for later matainance.
In case of failure insert the harddrive sda or sdb and perform the Add array commands.


Here some scenarios are listed if a drive fails.

A) The remaining drive does not boot and just writes GRUB to the console.

Reason: The raid was build without a copy of the bootloader.
Solution: Not known

B) The remaining drive starts the bootloader grub and waits for input.

Reason: The raid was build without a copy of the bootloader but luckily this is the disk which had the bootloader on.
Solution: boot if you know the boot parameters, or better take the FC9 installation disk and start rescue mode. You can save your data.

C) The remaining drive boots but not all raid arrays can be assembled, leaving you with a message that you can go to maintainance.

Reason: Not known
Solution: Insert the spare disk, reboot, assemble the raid with
Cmd: mdadm -Av /dev/mdx
Try to add the array
Cmd: mdadm /dev/mdx -a /dev/sdxx

Natsemi Geode GX1 lockup

There is a problem running RH7.3 on this processor. The processor completely locks up after an unspecified amount of time.
The time interval ranges from 1 hour to some days or never. The lockup manifests itself that network, keyboard and monitor
are dead, so you have no clue what happened. There are no log entries giving a hint. The lockup may be due to a bug
in the glibc-2.2.5. But we did not know how to debug. Changing to RH9 seems to work better.


description distribution version kernel package/file
ucd SNMP agent RH9 4.2.6 2.4 ucd-snmp-4.2.6-1.i386.rpm
Apache webserver with htdigest modified RH9 2.0.40-22 2.4 httpd-2.0.40-22.i386.rpm
Perl GD RH9