The Cube - Assimilating Technology

The Cube

Adding cups to Thinstation

For Humans only


Adding cups to Thinstation Print E-mail
Sunday, 23 December 2007 04:45

I recently bought an Epson Stylus Photo R285 printer for home use.

This printer is connected direct to my Thinstation, which is in the lounge, and was accessed via the lp daemon on the thinstation.
I was not happy with this, and wanted to have CUPS running on the Thinstation, thus allowing easier sharing of the printer to my network, and more control over the printer options/settings.

I could not find anyone who had done this via some google searches, and thus done it myself.

Before I start, I must mention three issues that nearly stopped the install.

The first was file permissions on the thinstation. If the cupsd daemon is not run as root, then I had issues with accessing the usb device, and some of the cups configuration files and required folders. I think the main one to mention here was /etc/fonts/fonts.conf. Cups actually failed pretty silently about this file not being accessible. Took quite some time to hunt this one down!

My thinstation is on a secure internal home network, so I just opted to run cupsd as root. To do this, I had to patch one of the cups files, which checks, and prevents, cups to function as root. This is a potential security issue, especially if your thinstation is not on a secure network. The patch is described in more details in the install guide below.

The second issue was fonts. For cups to print properly, it required access to fonts. I initially tried to include the font folder into the pxe (initrd) boot image, but this pushed the image beyond 80mb, and it would not boot. I only have 128mb of memory in my thinstation, so the 80mb was just to large. I opted to have a shared nfs folder on my linux network server, and mount this folder onto my thinstation at boot (see the init script in the install guide below). This way I can get the fonts, and not have a large initrd image. Also to mention here is that I just copied all the fonts from /usr/share/fonts folder (on my gentoo laptop) to the linux server. I did not download/install fonts or fontconfig onto the thinstation, or even onto my server.

Last, and third issue, was cups dependency to ghostscript, and guttenprint (formely called gimp-print). In my install I first compiled cups, added the packages to thinstation, then found I need ghostscript. I then added ghostscript, and then found I need guttenprint, so thirdly I compiled guttenprint. You may want to follow the same install sequence, as I am unsure if the act of compiling them in a different order will change any of the compiled in options.

After each build/compile I rebuilt the thinstation image, and tested the setup to the point where I got. The printing actually worked without guttenprint, but I wanted the more advanced guttenprint printer ppd files, as they supported more options - specifically the ability to select different cd image types as the paper feed to the printer. 

Also note that the setup is in stages.

1. build cups (Build thinstation boot image)
2. test cups is running (prelimanary test - web interface is up, admin is available)
3. build ghostscript (Build thinstation boot image)
4. test ghostscript (just test if 'gs' executable runs)
5. build guttenprint
6. Build thinstation boot image
7. Reboot into new thinstation build
8. Setup your printer using cups interface
9. Test it all works
10. Copy setup files (in /etc/cups) out to thinstation build area
11. Rebuild thinstation boot images with new config files included

If you do not do steps 8-11, then you will have to configure your printer after every reboot.
This is not the only way to do this. You could also mount /etc/cups folder to a remote writeable folder (preferably with nfs).
The nfs method may be a better solution, as any changes will be saved immediately. 

Ok, so here goes.

 

The first step was to get the thinstation 2.2 compile evnvironment setup.

I already have this done, as I had previously built and added 'saned' to my thinstation, but for completeness, I will include the instructions again.

I use my gentoo based laptop to do the build.

All the work is done under my home folder on the laptop :

cd /home/<username> 
mkdir thinstation-compile
cd thinstation-compile
I use thinstation 2.2, so I get the appropriate source tree:
wget http://optusnet.dl.sourceforge.net/sourceforge/thinstation/thinstation_src-2.2.tar.bz2 
Unpack it and cd into the unpacked folder
tar xvf ./thinstation_src-2.2.tar.bz2 
cd thinstation_src-2.2
Inside the unpacked folder is a source folder (called source)
This is where Thinstation stores the source for packages
cd into this folder
cd source

You are now in the folder where all the real work to build cups will be done. 

Download the cups sources. The latest stable cups version was 1.3.5, so I get those.

wget ftp://ftp.easysw.com/pub/cups/1.3.5/cups-1.3.5-source.tar.bz2

Unpack it

tar xvf ./cups-1.3.5-source.tar.bz2
cd into the new cups folder
cd cups-1.3.5

You need to create a setup script.
Use your  editor (I like joe) and create a new blank file, then paste my file contents into it:

setup.sh

THINSTATION_PATH=`cat ../../THINSTATION_PATH`
. ../SET_ENV
./configure --prefix=/ --bindir=/bin --sbindir=/bin --libexecdir=/lib --sysconfdir=/etc --libdir=/lib --disable-ssl \
--disable-slp --enable-pam --with-cups-user=root --with-cups-group=root
make clean
make
strip cups/libcups.so.2

If (when you have finished all this and installed cups, you have problems, add '--enable-debug' to the list of options shown,
and rebuild. The debug information was invaluable to me to solve issues.
Once any issues solved and cups is working, remove it again, and rebuild.
This will make the compiled binaries smaller.

make the file executable

chmod +x ./setup.sh

Patch the cups system, to allow cupsd to run as root (security risk!)

sed  -i 's/if (normal_user <= 0)/if (normal_user < 0)/' ./scheduler/cups-deviced.c

Enter the thinstation build environment (DON'T FORGET TO DO THIS!)  

cd ../../
./RUNME
cd back into the source/cups folder and run the setup.sh file
cd ./source/cups-1.3.5
./setup.sh

Sit back, and pray the compile works.
After the compile install it. Note: The makefile tries to run a chgrp command, which fails. just ignore it.

make install
exit the compile environment
exit
Thats it for the compile/build bit, next you will create the thinstation package
cd into where you have the thinstation package build setup.
mine is located in my home folder under the a folder called Thinstation-2.2
cd /home/<username>/Thinstation-2.2/packages
Create a cups packages folder by copying the template
cp -xav ./template ./cups
cd into the new folder
cd cups

Now you must copy all the required files (those that you have just built) into this folder, thus creating the thinstation package.

I have created a script that does all this for you. You can download it here
For those who cannot download the file, here it is:

#!/bin/bash

echo "have $1"
if [ -n "$1" ];
then
        COMPILEFOLDER=$1
else   
        echo "please call with path to your Thinstation compile folder"
        exit 1;
fi
# fix dependancies file
sed -i 's/^\#\(.*\)//' ./dependencies
sed -i '/^$/d' ./dependencies
#echo "ghostscript" >>./dependencies
#echo "guttenprint" >>./dependencies

# setup files in etc
rm -rf ./etc/cmd/*
echo 'CMD_GLOBAL=""' >>./etc/cmd/cupsd.global
rm -rf ./etc/console/*
touch ./etc/console/cupsd
mkdir -p ./etc/fonts
cp -xav ${COMPILEFOLDER}/usr/local/etc/fonts/fonts.conf ./etc/fonts/
mkdir -p ./etc/cups
cp -xav ${COMPILEFOLDER}/etc/cups/* ./etc/cups/
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/conf/cupsd.conf ./etc/cups


# bin folder
mkdir -p ./bin
rm -rf ./bin/*
cp -xav ${COMPILEFOLDER}/bin/cups* ./bin/
cp -xav ${COMPILEFOLDER}/sbin/cups* ./bin/

#shared files
mkdir -p ./share
cp -xav ${COMPILEFOLDER}/usr/share/cups/ ./share/
#mkdir -p ./share/doc
#cp -xav ${COMPILEFOLDER}/usr/share/doc/cups/ ./share/doc/

#libs
mkdir -p ./lib/cups/cgi-bin
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/cgi-bin/*.cgi ./lib/cups/cgi-bin/

mkdir -p ./lib/cups/daemon
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/scheduler/{cups-deviced,cups-driverd,cups-lpd} ./lib/cups/daemon
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/scheduler/{cups-polld,cupsd,cupsfilter,testdirsvc} ./lib/cups/daemon
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/scheduler/{testlpd,testmime,testspeed,testsub}  ./lib/cups/daemon

mkdir -p ./lib/cups/backend
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/backend/{betest,ipp,lpd,parallel}  ./lib/cups/backend
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/backend/{scsi,serial,snmp,socket,test1284,usb}  ./lib/cups/backend

mkdir -p ./lib/cups/driver

mkdir -p ./lib/cups/filter
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/filter/{hpgltops,imagetops,imagetoraster,libcupsimage.order} ./lib/cups/filter
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/filter/{libcupsimage.so.2,pstops,rasterbench} ./lib/cups/filter
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/filter/{rastertolabel,testimage,testraster,texttops}  ./lib/cups/filter
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/filter/{rastertoepson,rastertohp,libcupsimage.so,gziptoany}  ./lib/cups/filter

mkdir -p ./lib/cups/monitor
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/monitor/{bcp,tbcp}  ./lib/cups/monitor

mkdir -p ./lib/cups/notifier
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/notifier/{mailto,rss,testnotify}  ./lib/cups/notifier
cp -xav ${COMPILEFOLDER}/source/cups-1.3.5/filter/libcupsimage.so* ./lib
cp -xav ${COMPILEFOLDER}/lib/libcups.so* ./lib 
# some cleanup and add folders needed
ln -s ./lib ./libexec
mkdir -p ./var/spool/cups
mkdir -p ./var/cache/cups
rm -rf ./lib/lib
mkdir -p ./usr 
cd ./usr
ln -s ../share ./share
ln -s ../lib ./lib
cd ../
echo "done"

Setup the init scripts:

cd ./etc/init.d
mv ./your_start_up_script ./cups

Edit the file with your editor.
You will notice that it is in this script that I mount my remote nfs fonts folder.
Mine looks like this:

#! /bin/sh

. /etc/thinstation.global

# note you can replace this package with a symlink to /etc/thinstation.packages
# for GUI apps, or /etc/thinstation.console for console apps
# if you do then you will need to create a separate initilization script for
# any other parameters which need to be started at bootup


case "$1" in
init)
if ! pkg_initialized $PACKAGE; then

# Your startup instructions go here
mkdir -p /usr/share/fonts
mount -t nfs 10.0.0.3:/usr/share/fonts /usr/share/fonts
/bin/cupsd
pkg_set_init_flag $PACKAGE
fi
;;
console)
;;
window)
;;
fullscreen)
;;
help)
echo "Usage: $0 init"
;;
*)
exit 1
;;
esac

exit 0
 

Link the init script to the runlevel system

cd ../rc5.d
ln -s ../init.d/cups ./S10cups
cd ../

Setup your cupsd.conf file. (this must be in the /etc/cups/ folder. A example file should have been copied in place)
Basically what i did was to take out any access restrictions, so it is WIDE open. This is not ideal, but on my home system it is not an issue. You may want to do this bit more secure if your thinstation is not on a secure network.

My cupsd.conf looks like this:

LogLevel info
SystemGroup root root

# Allow remote access
Port 631
Listen /var/run/cups/cups.sock

# Enable printer sharing and shared printers.
Browsing On
BrowseAddress @LOCAL
BrowseDeny All
BrowseAllow 127.0.0.1
BrowseAllow @LOCAL
BrowseOrder deny,allow
DefaultAuthType Basic

<Location />
Order Deny,Allow
Deny From All
Allow From 127.0.0.1
Allow From @LOCAL
</Location>

<Location /admin>
  # Allow remote administration...
  Order allow,deny
  Allow From 127.0.0.1
  Allow From @LOCAL
</Location>

<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Allow all
  # Allow remote access to the configuration files...
  Order Deny,Allow
  Allow From 127.0.0.1
  Allow From @LOCAL
</Location>

<Policy default>
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs \
   Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription \
   Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>
    Require user @OWNER @SYSTEM
Order Deny,Allow
    Allow From 127.0.0.1
    Allow From @LOCAL
  </Limit>

  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class \
   CUPS-Delete-Class CUPS-Set-Default>
    AuthType Default
    Require user @SYSTEM
    Order Deny,Allow
    Allow From 127.0.0.1
    Allow From @LOCAL
  </Limit>

<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer \
   Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs \
   Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer \
   Startup-Printer Promote-Job Schedule-Job-After CUPS-Accept-Jobs CUPS-Reject-Jobs>
    AuthType Default
    Require user @SYSTEM
    Order Deny,Allow
    Allow From 127.0.0.1
    Allow From @LOCAL  
  </Limit>

<Limit CUPS-Authenticate-Job>
    Require user @OWNER @SYSTEM
    Order Deny,Allow
    Allow From 127.0.0.1
    Allow From @LOCAL  
  </Limit>

  <Limit All>
    Order deny,allow
    Order Deny,Allow
    Allow From 127.0.0.1
    Allow From @LOCAL  
  </Limit>
</Policy>

To note: The lines starting with '<Limit Send-Document' , '<Limit CUPS-Add-Modify-Printer' and '<Limit Pause-Printer Resume-Printer' is all on one line in my config file. I broke them into separate lines to paste here, so you may want to restore them back to one-liners.

You also might want to change the 'LogLevel info' setting to 'LogLeve debug', if you have any issues, to help with debugs.

Ok, time to rebuild your thinstation build, and then test the initial build of cupsd.

Get to the build folder. If you were in the /etc/cups folder the following line will get you there. If not just go to the folder that contains the 'build.conf' config file for the thinstation build. 

cd ../../../../ 

Add cups to the build config

echo "package cups # cups printing" >> ./build.conf

and rebuid...

./build 

After the rebuild, reboot from your new image (I use pxe network boot, so I copied the new boot image to my bootp server)

scp ./boot-images/pxe/initrd root@10.0.0.3:/tftpboot/ 

and reboot the thinstation to load the new image.
Once rebooted test the cups install via the command line. Either telnet into the thinstation, or use the local thinstation console (CTRL+ALT+F2)

First see if it actually started:

ts_lounge:~# ps -xav |grep cups

if all went well, you will get this : 

2407 root       1136 S   /bin/cupsd  

Good, mine started first time.

>> Trouble shooting:

If it did not start, try and run it from the command line using '/bin/cupsd', and check if it tells you why and the command line.

Also check the error log..

cat /var/log/cups/error_log 

Read through the lines carefully, and see if it tells you why it did not start. Make sure you have  'LogLevel debug' in /etc/cupsd.conf,
and you will get more info.

<< End Trouble Shooting

Ok, so cupsd is actually running, but can we get to the web interface ? test using a browser and browse to

http://<ip of thinstation>:631 

If the web interface loads, feel happy :), again if not look at the erro_log file. Reasons will be there.

Ok, so lets do a basic test, see if a printer can be added. 

First test click on 'Add Printer'.
In the next screen, put anything for the Name, Location and Description, and then click  'Continue'.
The next screen should produce a drop-down box with a list of devices.
If this list is blank, look at the error log. If it is populated then you can stop testing and assume the install was good.
Nothing stops you from doing a test all the way, and actually setup the printer or a more complete test. I did not.

This completes the first part of the install.

Next we must install ghostscript, as described in my 'Add Ghostscript to thinstation ' guide.

Once you have done that, come back here for the next part.

Ok,  the next part involves building guttenprint (nearly done, this one is very short and easy to do).

Follow my guide 'Install guttenprint to thinstation '

Once you have done that, come back here for the last bit.... 

Ok,  so you have now installed Cups, ghostscript and guttenprint, now we must configure the printer.

As you setup now stands you will have to re-configure your printer after every thinstation reboot, not very ideal. To solve this, we will simply configure the printer, set all the the setup as we want, and then copy the /etc/cups configuration folder back out to the build environment, and then rebuild the whole image again, thus including your default config. The end effect is a properly configured printer after reboot.

Open the cups onfiguration screen, and configure your printer via the 'Administartion' screens

http://<ip of thinstation>:631/ 

and select 'Add Printer'. Once the printer is added, use the 'Set Printer Options' screen to set your wanted default options.

After the setup, click on 'Start printer', and try a test page. If your test page print, feel happy :)

No actual commands shown for the next few steps, just a guide on what to do, as it has mostly been done above, we just have to redo some of the commands. 

Ok, so now copy your config file (/etc/cups/printers.conf) to your machine where you do the thinstation boot image build.
Copy it any way you like.  As I already have my server mounted as a drive (recall the mount for the fonts), I just copy the file to the share, and from there I can scp copy it to my laptop. Seems a bit round-abount, but it works.

Once you have the file on the build machine, place it into your 'packages/cups/etc/cups' folder, then rebuild the thinstation image and copy it over to your boot image area (I am still using tftboot), and then reboot your thinstation. (Make sure the copied file has the 755 file permission before you build - chmod 755 printers.conf)

After reboot you will have a printer installed from the start :) Do a test print. Feel even more happy as your are basically done.

Additional setup stuff.

With the guttenprint install, a nice command line util, called escputil, gets built which allows you to control an epson printer from the command line. It allows some other stuff like head cleaning, ink level checking and head testing.

To make this util accessable via the network, you can add the required controls to the thinstation web interface.

first make sure you have the web interface enabled in build.conf

cat build.conf |grep www
package www                     # Web access to client.  From a browser: "http://<IP number>"

if the resulting line has a hash in front of it, then edit your build.conf, and remove it.

next you need to go add the controls to the web interface, but first you need the control programs

from your thinstation build root folder, cd to the www cgi-bin folder

cd  ./packages/www/lib/www/html/general/cgi-bin/

create three file, one for Show ink levels, one for Clean heads, and one for Test heads. Use your favourite editor, I use joe.

First one :

joe Epson.cgi

paste the following into the file

#! /bin/sh
. /etc/thinstation.env
. $TS_GLOBAL
header
echo '<pre>'
escputil -q -e --raw-device /dev/usb/lp0
echo '</pre>'
trailer

save the file

Next one : 

joe Epson_clean.cgi

paste the following into it:

#! /bin/sh
. /etc/thinstation.env
. $TS_GLOBAL
header
echo '<pre>'
escputil -c --raw-device /dev/usb/lp0
echo '</pre>'
trailer

and the third file

joe Epson_test.cgi

and again paste this into the file

#! /bin/sh
. /etc/thinstation.env
. $TS_GLOBAL
header
echo '<pre>'
escputil -n --raw-device /dev/usb/lp0
echo '</pre>'
trailer

ok, so now make them all executable.

chmod 755 Epson* 

now enter the html folder and adjust the menu page

cd ..

edit the  template html file

joe index.html.tpl 

find the line that looks like this

<a href="/cgi-bin/CdControl.cgi">Control CD Player</a><br> 

and add the following lines just after it:

<a href="/cgi-bin/Epson.cgi">Show Epson Ink Levels</a><br>
<a href="/cgi-bin/Epson_clean.cgi">Clean Epson Ink Heands</a><br>
<a href="/cgi-bin/Epson_test.cgi">Test Heads</a><br>

save, and yes you guesed it, rebuild your thinstation image, reboot your thinstation. Once rebooted you can access the new commands via your web browser on the ip address of your thinstation.

Memory improvements

May sound strange, but your thinstation's free memory is directly related to the amount of packages your have loaded, and the size of their files. (the whole thing is loaded into ram), so by making the files smaller, and removing any unwanted docs, you can free up more memory.

On my system I only have a 127 mb module loaded, so free memory is critical. i had found with usage that larger printouts fail due to lack of free memory to allow for processing.

To check your free memory run the 'free' command

ts_lounge:~# free
              total         used         free       shared      buffers
  Mem:       127040        81760        45280            0        53496
 Swap:            0            0            0
Total:       127040        81760        45280

so, from the above I can see I have 45 mb free (should be more than enough), but lets see how we can free up a bit more.

The 'strip' command is pretty handy, but be very very carefull how you use it. Stripping the wrong type of file, with the wrong switches will break things.

basically you don't want to use --strip-uneeded on any lib folder.

so lets go strip the bin folders in the new cups, guttenprint and ghostscript packages. you may want to make a back up of your build folder first...

cd ./packages/cups/bin
strip --strip-unneeded *

You will get a few errors, just ignore them, they are for files that cannot be stripped.

now do the libs

cd ../lib
strip --strip-debug *

repeat the strippping in the bin and lib folders of guttenprint and ghostscript, then

yep, rebuild, and reboot into the thinstation again. 

after the reboot, run the free command again

ts_lounge:~# free
              total         used         free       shared      buffers
  Mem:       127040        73536        53504            0        47324
 Swap:            0            0            0
Total:       127040        73536        53504

whoo hoo, that was a space/memory saving of 8224.  With only 127 mb, every bit helps (no pun intended)

you can repeat the stripping with other packages in your build, just be carefull, and make backups as you go along.

Also remove unwanted man pages, and docs. 53 mb is fine for now, so i am leaving mine with that.

Last but not least, the most irretating problem I have had. This could just be my printer, as I had not been able to test this with anyother printer. My printer seems to get 'lost' if it stays connected, and switched on for a bit (I have not been able to determine the exact time, as I got bored waiting), and just switching it off and on did not remedy the issue. I had to reboot the thinstation to get it back. Any ideas why ?

Some testing, and I found that if I did a head clean using escputil described above, then it would 'wake up' again. This helped, but it is a massive waste of ink, so I hunted for a solution (I suspected the printer just needed a soft reset)

I came accross a utility called 'mtink', which is another epson printer control util, simmilar to escputil that comes with guttenprint. It however had an option to do a soft reset.

So, download it and compile it. Do this in the thinstation compile environment, in the source folder.

wget  http://www.dedmeet.com/files/mtink-1.0.16.tar.gz ./

unpack it

tar xvf  mtink-1.0.16.tar.gz

cd into the folder

cd mtink-1.0.16

create a setup.sh file, and paste the following data into it:

THINSTATION_PATH=`cat ../../THINSTATION_PATH`
. ../SET_ENV
./Configure --prefix / --no-x --no-gimp 
make clean
make

make the file excecutable

chmod +x ./setup.sh

enter the thinstation compile environment

cd ../../
./RUNME

go back to the mtink build folder

cd ./source/mtink-1.0.16 

run the setup.sh file, and wait for it to compile.

exit the compile environment

exit 

After the compile you are just interested in the mtink binary. No need to create a whole mtink package for thinstation, so just copy the file into the cups bin folder in the thinstation build area

cd /home/<username>/Thinstation-2.2/packages/cups/bin
cp /home/<username>/Thinstation-compile/source/mtink-1.0.16/ttink ./

Now you must setup the thinstation udev rules to run this file whenever the printer is connected/detected.

edit the base udev rules file.

cd  ../../base/etc/udev/rules.d 
joe 50-udev.rules
look for the line with  
BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k"

and change it to

BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k"  RUN+="/bin/restart_printer.sh"

and save the file.

now create the /bin/restart_printer.sh file. I placed it in the cups package bin folder. The base bin folder will also do.

joe ../../../../cups/bin/restart_printer.sh 

paste this into the file

#!/bin/sh

/bin/ttink -r -d /dev/usb/lp0

save the file, make it executable

chmod +x ../../../../cups/bin/restart_printer.sh 

and finnally the last rebuild, last copy to the boot image folder, and then reboot the thinstation.

after the reboot, telnet into the thinstation, and tail the log file. We are looking to see if the reset command runs when the printer gets switched on.

tail -f /var/log/messages

switch the printer off and on and look for a message like

run_program: '/bin/restart_printer.sh' returned with status 0

exit status 0 is good, anything else is an error. Look in the file, it will tell you what the problem was if it is not 0. 

Well, thats it.

I hope this guide was helpfull.

 

 

 

Last Updated on Friday, 09 January 2009 08:09
 
Share on facebook