Store the windows and system directories as long path names.
[wine.git] / documentation / PACKAGING
blobe1a965b366969dbf9df3e3fddeae915a09102a96
1 INTRODUCTION
2 ~~~~~~~~~~~~
4 This document attempts to establish guidelines for people making binary 
5 packages of Wine.
7 It expresses the basic principles that the Wine developers have agreed 
8 should be used when building Wine. It also attempts to highlight the areas
9 where there are different approaches to packaging Wine, so that the packager
10 can understand the different alternatives that have been considered and their 
11 rationales.
13 TERMS
14 ~~~~~
16 There are several terms and paths used in this document as place holders 
17 for configurable values. Those terms are described here.
18     * WINEPREFIX: is the user's Wine configuration directory.
19         This is almost always ~/.wine, but can be overridden by
20         the user by setting the WINEPREFIX environment variable.
22     * PREFIX: is the prefix used when selecting an installation target.
23         The current default is /usr/local. This results in binary 
24         installation into /usr/local/bin,  library installation into 
25         /usr/local/wine/lib, and so forth.
26         This value can be overridden by the packager. In fact, FHS 2.2
27         (http://www.pathname.com/fhs/) specifications suggest that a better
28         prefix is /opt/wine.  Ideally, a packager would also allow the 
29         installer to override this value.
31     * ETCDIR: is the prefix that Wine uses to find the global 
32         configuration directory. This can be changed by the configure 
33         option sysconfdir.  The current default is $PREFIX/etc.
35     * WINDOWSDIR: is an important concept to Wine.  This directory specifies
36         what directory corresponds to the root Windows directory
37         (e.g. C:\WINDOWS). This directory is specified by the user, in
38         the user's configuration file.  Generally speaking, this directory 
39         is either set to point at an empty directory, or it is set to point 
40         at a Windows partition that has been mounted through the vfat driver.
41         NOTE:   It is extremely important that the packager understand the 
42                 importance of WINDOWSDIR and convey this information and 
43                 choice to the end user.
45 DEPENDENCIES
46 ~~~~~~~~~~~~
48 There are two types of dependencies: hard and soft dependencies.
50 A hard dependency must be available at runtime for Wine to function,
51 if  compiled into the code. Soft dependencies on the other hand
52 will degrade gracefully at runtime if unavailable on the runtime system.
53 Ideally, we should eliminate all hard dependencies in favour of
54 soft dependencies.
56 To enable a soft dependency, it must be available at compile time.
57 As a packager, please do your best to make sure that as many soft 
58 dependencies  are available during compilation. Failing to have a 
59 soft dependency available means that users cannot benefit
60 from a Wine capability.
62 Here is a list of the soft dependencies. We suggest packagers
63 install each and every last of those before building the package. 
64 These libraries are not dependencies in the RPM sense. In DEB packages, 
65 they should appear as "Suggests" or "Recommends", as the case may be.
66     * FreeType: http://www.freetype.org
67       This library is used for direct rendering of fonts. It provides 
68       better support of fonts than using the X11 fonts engine. It is 
69       only needed for the X11 back end engine. Used from GDI.
71     * Alsa: "http://sourceforge.net/projects/alsa (Linux only)
72       This library gives sound support to the Windows environment.
74     * JACK: http://jackit.sourceforge.net
75       Similar to Alsa, it allow Wine to use the JACK audio server.
77     * CUPS: http://www.cups.org
78       This library allows Windows to see CUPS defined printers.
80     * OpenGL
81       This is used for both OpenGL and Direct3D (and some other 
82       DirectX functions as well) support in Wine. There are many many 
83       libraries for providing this functionality. It is enough for one
84       of them to be available when compiling Wine. Wine can work with 
85       any other library during runtime.
86       If no library is available, packagers are encouraged to compile 
87       Wine with Mesa3D (http://www.mesa3d.org), which requires no 
88       hardware support to install.
90 GOALS
91 ~~~~~
93 An installation from a Wine package should:
94     * Install quickly and simply:
95         The initial installation should require no user input.  An 
96                 'rpm -i wine.rpm' or 'apt-get install wine'
97         should suffice for initial installation.
98                 
99     * Work quickly and simply:
100         The user should be able to launch Solitaire
101         within minutes of downloading the Wine package.
102               
103     * Comply with Filesystem Hierarchy Standard
104         A Wine installation should, as much as possible, comply
105         with the FHS standard (http://www.pathname.com/fhs/).
106                 
107     * Preserve flexibility
108         None of the flexibility built into Wine should
109         be hidden from the end user.
111     * Easy configuration
112         Come as preconfigured as possible, so the user does
113         not need to change any configuration files.
115     * Small footprint
116         Use only as much diskspace as needed per user.
118     * Reduce support requirements.
119         A packaged version of Wine should be sufficiently easy to use and
120         have quick and easy access to FAQs and documentation such that 
121         requests to the newsgroup and development group go down.
122         Further, it should be easy for users to capture good bug reports.
124 REQUIREMENTS
125 ~~~~~~~~~~~~
127 Successfully installing Wine requires:
128     * Much thought and work from the packager (1x)
130     * A configuration file
131         Wine will not run without a configuration file.  Wine provides a
132         a sample config file and it can be found in documentation/samples.
133         Some packagers may attempt to provide (or dynamically generate) a 
134         default configuration file. Some packagers may wish to rely on 
135         winesetup to generate the configuration file.
137     * A writeable C drive
138         A writeable C:\ directory structure on a per-user basis. 
139         Applications do dump .ini file into C:\WINDOWS, installer
140         dump .exe/.dll/etc. files into C:\WINDOWS or C:\Program Files.
142     * An initial set of registry entries.
143         The current Wine standard is to use the regedit tool against 
144         the 'winedefault.reg' file to generate a default registry.
145         The current preferred method of configuring/installing
146         Wine is to run /toos/wineinstall.  There are several other 
147         choices that could be made; registries can be imported from 
148         a Windows partition.  At this time, Wine does not completely 
149         support a complex multi-user installation ala Windows NT,
150         but it could fairly readily.
152      * Special files
153         Some special .dll and .exe files in the C:\WINDOWS\SYSTEM
154         directory, since applications directly check for their presence.
156 WINE COMPONENTS
157 ~~~~~~~~~~~~~~~
159    * Executable Files
160         - notepad : The windows Notepad replacement.
161         - progman : A Program Manager replacement.
162         - regedit : A command-line tool to edit your registry or for 
163                 important a windows registry to Wine.
164         - regsvr32 : A program to register/unregister .DLL's and .OCX files. 
165                 Only works on those dlls that can self-register.
166         - uninstaller: A program to uninstall installed Windows programs. 
167                 Like the Add/Remove Program in the windows control panel.
168         - wcmd :  Wine's command line interpreter, a cmd.exe replacement.
169         - widl : Wine IDL compiler compiles (MS-RPC and DCOM) Interface 
170                 Definition Language files.
171         - wine :  The main Wine executable. This program will load a Windows 
172                 binary and run it, relying upon the Wine shared object libraries.
173         - wineboot : This program is executed on startup of the first wine 
174                 process of a particular user.wineboot won't automatically run 
175                 when needed.  Currently you have to manually run it after you 
176                 install something.
177         - winebuild : Winebuild is a tool used for building Winelib applications 
178                 (and by Wine itself) to allow a developer to compile a .spec file 
179                 into a .spec.c file.
180         - wineclipserv : The Wine Clipboard Server is a standalone XLib application
181                 whose purpose is to manage the X selection when Wine exits.
182         - wineconsole : Render the output of CUI programs.
183         - winedbg : A application making use of the debugging API to allow 
184                 debugging of Wine or Winelib applications as well as Wine itself 
185                 (kernel and all DLLs).
186         - winedump : Dumps the imports and exports of NE and PE files.
187         - winefile : A clone of the win3x filemanager.
188         - winegcc/wineg++: Wrappers for gcc/g++ respectively, to make them behave 
189                 as MinGW's gcc. Used for porting apps over to Winelib.
190         - winemaker : Winemaker is a perl script which is designed to help you 
191                 bootstrap the conversion of your Windows projects to Winelib. 
192         - winemine :  A clone of "Windows Minesweeper" a demo WineLib app.
193         - winepath :  A tool for converting between Windows paths and Unix paths 
194         - wineserver : The Wine server is the process that manages resources, 
195                 coordinates threads, and provides synchronization and interprocess 
196                 communication primitives to Wine processes.
197         - wineshelllink : This shell script can be called by Wine in order to 
198                 propagate Desktop icon and menu creation requests out to a 
199                 GNOME or KDE (or other Window Managers).
200         - winewrap : Takes care of linking winelib applications. Linking with 
201                 Winelib is a complex process, winewrap makes it simple.
202         - winhelp : A Windows Help replacement.
203         - wmc : Wine Message Compiler it allows Windows message files to be 
204                 compiled into a format usable by Wine.
205         - wrc : the Wine Resource Compiler. A clone of Microsoft's rc.
207     * Shared Object Library Files
208         To obtain a current list of DLLs, run:
209                 ls dlls/*.so
210         it the root of the Wine _build_ tree, after a successful build.
212     * Man Pages
213         To obtain a current list of man files that need to be installed, run:
214                 find . -name "*.man"
215         it the root of the Wine _build_ tree, after you have run ./configure.
217     * Include Files
218         An up to date list of includes can be found in the include/Makefile.in file.
220     * Documentation files
221         After building the documentation with:
222                 cd documentation; make html
223         install all the files from: wine-user/, wine-devel/ and winelib-user/.
225      * Dynamic Wine Files
226         Wine also generates and depends on a number of dynamic
227         files, including user configuration files and registry files.
229         At the time of this writing, there was not a clear
230         consensus of where these files should be located, and how
231         they should be handled.  This section attempts
232         to explain the alternatives clearly.
234         - WINEPREFIX/config
235             This file is the user local Wine configuration file.
236             At the time of this writing, if this file exists,
237             then no other configuration file is loaded.
239         - ETCDIR/wine.conf
240             This is the global Wine configuration file. It is only used
241             if the user running Wine has no local configuration file.
242             Global wine configuration is currently not possible;
243             this might get reenabled at some time.
244             Some packagers feel that this file should not be supplied, 
245             and that only a wine.conf.default should be given here.
246             Other packagers feel that this file should be the predominant
247             file used, and that users should only shift to a local 
248             configuration file if they need to.  An argument has been
249             made that the local configuration file should inherit the 
250             global configuration file.  At this time, Wine does not do this;
251             please refer to the WineHQ discussion archives for the debate 
252             concerning this.
253             This debate is addressed more completely below, in the
254             'Packaging Strategy' section.
256     * Registry Files
257             In order to replicate the Windows registry system,
258             Wine stores registry entries in a series of files.
260             For an excellent overview of this issue, read this
261             http://www.winehq.org/News/2000-25.html#FTR
262             Wine Weekly News feature.
264             The bottom line is that, at Wine server startup,
265             Wine loads all registry entries into memory
266             to create an in memory image of the registry.
267             The order of files which Wine uses to load
268             registry entries is extremely important,
269             as it affects what registry entries are
270             actually present.  The order is roughly that
271             .dat files from a Windows partion are loaded,
272             then global registry settings from ETCDIR,
273             and then finally local registry settings are
274             loaded from WINEPREFIX.  As each set are loaded,
275             they can override the prior entries.  Thus,
276             the local registry files take precedence.
278             Then, at exit (or at periodic intervals),
279             Wine will write either all registry entries
280             (or, with the default setting) changed
281             registry entries to files in the WINEPREFIX.
283             - WINEPREFIX/system.reg
284                 This file contains the user's local copy of the 
285                 HKEY_LOCAL_MACHINE registry hive.  In general use, it will
286                 contain only changes made to the default registry values.
288             - WINEPREFIX/user.reg
289                 This file contains the user's local copy of the 
290                 HKEY_CURRENT_MACHINE registry hive.  In general use, it will
291                 contain only changes made to the default registry values.
293             - WINEPREFIX/userdef.reg
294                 This file contains the user's local copy of the 
295                 HKEY_USERS\.Default registry hive.  In general use, it will
296                 contain only changes made to the default registry values.
298             - WINEPREFIX/cachedmetrics.[display]
299                 This file contains font metrics for the given X display.
300                 Generally, this cache is generated once at Wine start time.
301                 cachedmetrics can be generated if absent. 
302                 You should note this can take a long time.
304             - ETCDIR/wine.systemreg 
305                 This file contains the global values for HKEY_LOCAL_MACHINE. 
306                 The values in this file can be overridden by the user's 
307                 local settings. The location of this directory is hardcoded 
308                 within wine, generally to /etc. 
310             - ETCDIR/wine.userreg
311                 This file contains the global values for HKEY_USERS.  
312                 The values in this file can be overridden by the user's 
313                 local settings.  This file is likely to be deprecated in
314                 favor of a global wine.userdef.reg that will only contain 
315                 HKEY_USERS/.Default.
317     * Important Files from a Windows Partition
318         Wine has the ability to use files from an installation of the
319         actual Microsoft Windows operating system.  Generally these
320         files are loaded on a VFAT partition that is mounted under Linux.
322         This is probably the most important configuration detail.
323         The use of Windows registry and DLL files dramatically alters the 
324         behaviour of Wine. If nothing else, pacakager have to make this 
325         distinction clear to the end user, so that they can intelligently
326         choose their configuration.
328         - WINDOWSDIR/system32/system.dat
329         - WINDOWSDIR/system32/user.dat
330         - WINDOWSDIR/win.ini
332     * Windows Dynamic Link Libraries (WINDOWSDIR/system32/*.dll)
333         Wine has the ability to use the actual Windows DLL files
334         when running an application.  An end user can configure
335         Wine so that Wine uses some or all of these DLL files
336         when running a given application.
338 PACKAGING STRATEGIES
339 ~~~~~~~~~~~~~~~~~~~~
341 There has recently been a lot of discussion on the Wine
342 development mailing list about the best way to build Wine packages.
344 There was a lot of discussion, and several diverging points of view.
345 This section of the document attempts to present the areas of common 
346 agreement, and also to present the different approaches advocated on 
347 the mailing list.
349     * Distribution of Wine into packages
350         The most basic question to ask is given the Wine CVS tree,
351         what physical files are you, the packager, going to produce?
352         Are you going to produce only a wine.rpm (as Marcus has done),
353         or are you going to produce 6 Debian files (libwine, libwine-dev,
354         wine, wine-doc, wine-utils and winesetuptk) as Ove has done?
355         At this point, common practice is to adopt to the conventions
356         of the targeted distribution. 
358     * Where to install files
359         This question is not really contested.  It will vary
360         by distribution, and is really up to the packager.
361         As a guideline, the current 'make install' process
362         seems to behave such that if we pick a single PREFIX then:
363             - binary files go into PREFIX/bin
364             - library files go into PREFIX/lib/wine
365             - include files go into PREFIX/include/wine
366             - man pages go into PREFIX/share/man
367             - documentation files go into PREFIX/share/doc/wine-VERSION
369         You might also want to use the wine wrapper script winelauncher
370         that can be found in tools/ directory, as it has several important
371         advantages over directly invoking the wine binary.
372         See the Executable Files section for details.
374     * The question of /opt/wine
375         The FHS 2.2 specification suggests that Wine as a package
376         should be installed to /opt/wine.  None of the existing packages 
377         follow this guideline (today; check again tomorrow).
379     * What files to create
380         After installing the static and shareable files, the next
381         question the packager needs to ask is how much dynamic
382         configuration will be done, and what configuration
383         files should be created.
384         There are several approaches to this:
385             - Rely completely on user file space - install nothing
386                 This approach relies upon the new winesetup utility
387                 and the new ability of Wine to launch winesetup if no
388                 configuration file is found.  The basic concept is
389                 that no global configuration files are created at
390                 install time.  Instead, Wine configuration files are
391                 created on the fly by the winesetup program when Wine
392                 is invoked.  Further, winesetup creates default
393                 Windows directories and paths that are stored
394                 completely in the user's WINEPREFIX.  This approach
395                 has the benefit of simplicity in that all Wine files
396                 are either stored under /opt/wine or under ~/.wine.
397                 Further, there is only ever one Wine configuration
398                 file.  This approach, however, adds another level of
399                 complexity.  It does not allow Wine to run Solitaire
400                 'out of the box'; the user must run the configuration
401                 program first.  Further, winesetup requires Tcl/Tk, a
402                 requirement not beloved by some.  Additionally, this
403                 approach closes the door on multi user configurations
404                 and presumes a single user approach.
406             - Build a reasonable set of defaults for the global wine.conf,
407               facilitate creation of a user's local Wine configuration.
408                 This approach, best shown by Marcus, causes the
409                 installation process to auto scan the system,
410                 and generate a global wine.conf file with best
411                 guess defaults.  The OpenLinux packages follow
412                 this behaviour.
413                 The keys to this approach are always putting
414                 an existing Windows partition into the
415                 path, and being able to run Solitaire
416                 right out of the box.
417                 Another good thing that Marcus does is he
418                 detects a first time installation and
419                 does some clever things to improve the
420                 user's Wine experience.
421                 A flaw with this approach, however, is it doesn't
422                 give the user an obvious way to choose not to
423                 use a Windows partition.
425             - Build a reasonable set of defaults for the global wine.conf,
426               and ask the user if possible
427                 This approach, demonstrated by Ove, causes the
428                 installation process to auto scan the system,
429                 and generate a global wine.conf file with best
430                 guess defaults.  Because Ove built a Debian
431                 package, he was able to further query debconf and
432                 get permission to ask the user some questions,
433                 allowing the user to decide whether or not to
434                 use a Windows partition.
436 IMPLEMENTATION
437 ~~~~~~~~~~~~~~
439 This section discusses the implementation of a Red Hat 8.0 .spec file.
440 For a current .spec file, please refer to any one of the existing SRPMs.
442 1. Building the package
444 Wine is configured the usual way (depending on your build environment). 
445 The PREFIX is chosen using your application placement policy
446 (/usr/, /usr/X11R6/, /opt/wine/, or similar).  The configuration files
447 (wine.conf, wine.userreg, wine.systemreg) are targeted for /etc/wine/
448 (rationale: FHS 2.2, multiple readonly configuration files of a package).
450 Example (split this into %build and %install section for rpm:
453         CFLAGS=$RPM_OPT_FLAGS ./configure --prefix=/usr/X11R6 --sysconfdir=/etc/wine/ --enable-dll
454         make
455         BR=$RPM_BUILD_ROOT
456         make install prefix=$BR/usr/X11R6/ sysconfdir=$BR/etc/wine/
457         install -d $BR/etc/wine/
458         install -m 644 wine.ini $BR/etc/wine/wine.conf
460         # Put all our DLLs in a separate directory. (this works only if you have a buildroot)
461         install -d $BR/usr/X11R6/lib/wine
462         mv $BR/usr/X11R6/lib/lib* $BR/usr/X11R6/lib/wine/
464         # the clipboard server is started on demand.
465         install -m 755 dlls/x11drv/wineclipsrv $BR/usr/X11R6/bin/
467         # The Wine server is needed.
468         install -m 755 server/wineserver $BR/usr/X11R6/bin/
470 Here we unfortunately do need to create wineuser.reg and winesystem.reg
471 from the Wine distributed winedefault.reg. This can be done using regedit
472 once for one example user and then reusing his WINEPREFIX/user.reg and
473 WINEPREFIX/system.reg files.
474 FIXME: this needs to be done better.
476         install -m 644 wine.sytemreg $BR/etc/wine/
477         install -m 644 wine.userreg $BR/etc/wine/
479 There are now a lot of libraries generated by the build process, so a 
480 separate library directory should be used.
482         install -d 755 $BR/usr/X11R6/lib/
483         mv $BR/
484         
485 You will need to package the files:
487         $prefix/bin/wine, $prefix/bin/dosmod, $prefix/lib/wine/*
488         $prefix/man/man1/wine.1, $prefix/include/wine/*,
489         $prefix/bin/wineserver, $prefix/bin/wineclipsrv
491         %config /etc/wine/*
492         %doc ... choose from the toplevel directory and documentation/
494 The post-install script:
496         if ! grep /usr/X11R6/lib/wine /etc/ld.so.conf >/dev/null; then
497             echo "/usr/X11R6/lib/wine" >> /etc/ld.so.conf
498         fi
499         /sbin/ldconfig
501 The post-uninstall script:
503         if [ "$1" = 0 ]; then
504             perl -ni -e 'print unless m:/usr/X11R6/lib/wine:;' /etc/ld.so.conf
505         fi
506         /sbin/ldconfig
508 2. Creating a good default configuration file. 
510 For the rationales of needing as less input from the user as possible arises 
511 the need for a very good configuration file. The one supplied with Wine is 
512 currently lacking. We need:
514     * [Drive X]: 
515         - A for the floppy. Specify your distribution's default floppy mountpoint.
516                 Path=/auto/floppy
517         - C for the C:\ directory. Here we use the user's home directory, for most
518           applications do see C:\ as root-writeable directory of every windows
519           installation and this basically is it in the UNIX-user context.
520           Don't forget to identify environment variables as DOS ones (ie, surrounded by '%').
521                 Path=%HOME%
522         - R for the CD-Rom drive. Specify your distribution's default CD-ROM mountpoint.
523                 Path=/auto/cdrom
524         - T for temporary storage. We do use /tmp/ (rationale: between process 
525           temporary data belongs to /tmp/ , FHS 2.0)
526                 Path=/tmp/
527         - W for the original Windows installation. This drive points to the
528           WINDOWSDIR subdirectory of the original windows installation.
529           This avoids problems with renamed WINDOWSDIR directories (as for 
530           instance lose95, win or sys\win95). During compile/package/install
531           we leave this to be / , it has to be configured after the package install.
532         - Z for the UNIX Root directory. This avoids any roblems with 
533           "could not find drive for current directory" users occasionally complain
534           about in the newsgroup and the irc channel. It also makes the whole 
535           directory structure browseable. The type of Z should be network,
536           so applications expect it to be readonly.
537                 Path=/
538           
539     * [wine]:
540         Windows=c:\windows\             (the windows/ subdirectory in the user's
541                                  home directory)
542         System=c:\windows\system\       (the windows/system subdirectory in the user's
543                                          home directory)
544         Path=c:\windows;c:\windows\system;c:\windows\system32;w:\;w:\system;w:\system32;
545         ; Using this trick we have in fact two windows installations in one, we
546         ; get the stuff from the readonly installation and can write to our own.
547         Temp=t:\                        (the TEMP directory)
549     * [Tweak.Layout]
550         WineLook=win95                (just the coolest look ;)
552     * Possibly modify the [spooler], [serialports] and [parallelports] sections.
553       FIXME: possibly more, including printer stuff.
555 Add this prepared configuration file to the package.
557 3. Installing Wine for the system administrator
558                 
559 Install the package using the usual packager 'rpm -i wine.rpm'.
560 You may edit /etc/wine/wine.conf , [Drive W], to point to a
561 possible Windows installation right after the install. That's it.
563 Note that on Linux you should somehow try to add the unhide mount optioni
564 (see 'man mount') to the CD-ROM entry in /etc/fstab during package install,
565 as several stupid Windows programs mark some setup (!) files as hidden 
566 (ISO9660) on CD-ROMs, which will greatly confuse users as they won't find 
567 their setup files on the CD-ROMs as they were used on Windows systems when
568 unhide is not set ;-\ And of course the setup program will complain
569 that setup.ins or some other mess is missing... If you choose to do so, 
570 then please make this change verbose to the admin.
572 Also make sure that the kernel you use includes the Joliet CD-ROM support, 
573 for the very same reasons as given above (no long filenames due to missing 
574 Joliet, files not found).
575               
576 4. Installing Wine for the user
578 The user will need to run a setup script before the first invocation of Wine. 
579 This script should:
580     * Copy /etc/wine/wine.conf for user modification.
581     * Allow specification of the original windows installation to use
582       (which modifies the copied wine.conf file).
583     * Create the windows directory structure (c:\windows, c:\windows\system,
584       c:\windows\Start Menu\Programs, c:\Program Files, c:\Desktop, etc.)
585     * Symlink all .dll and .exe files from the original windows installation
586       to the windows directory. Why? Some programs reference 
587       "%windowsdir%/file.dll" or "%systemdir%/file.dll" directly and fail
588       if they are not present.  This will give a huge number of symlinks, yes.
589       However, if an installer later overwrites one of those files, it will 
590       overwrite the symlink (so that the file now lies in the windows/
591       subdirectory). FIXME: Not sure this is needed for all files.
592     * On later invocation the script might want to compare regular files in 
593       the user's windows directories and in the global windows directories
594       and replace same files by symlinks (to avoid diskspace problems).
595     
596 AUTHORS
597 ~~~~~~~
599 Written in 1999 by Marcus Meissner <marcus@jet.franken.de>
600 Updated in 2000 by Jeremy White <jwhite@codeweavers.com>
601 Updated in 2002 by Andreas Mohr <andi@rhlx01.fht-esslingen.de>
602 Updated in 2003 by Tom Wickline <twickline2@triad.rr.com>
603 Updated in 2003 by Dimitrie O. Paun <dpaun@rogers.com>