Building and Installing Software Packages for Linux
 _M_e_n_d_e_l _C_o_o_p_e_r _<mailto:[email protected]> ---
 http://personal.riverusers.com/~thegrendel/ <http://per-
 sonal.riverusers.com/~thegrendel/>
 v1.91, 27 July 1999

 This is a comprehensive guide to building and installing "generic"
 UNIX software distributions under Linux. Additionally, there is some
 coverage of "rpm" and "deb" pre-packaged binaries.
 ______________________________________________________________________

 Table of Contents


 1. Introduction

 2. Unpacking the Files

 3. Using Make

 4. Prepackaged Binaries

    4.1 Whats wrong with rpms?
    4.2 Problems with rpms: an example

 5. Termcap and Terminfo Issues

 6. Backward Compatibility With a.out Binaries

    6.1 An Example

 7. Troubleshooting

    7.1 Link Errors
    7.2 Other Problems
    7.3 Tweaking and fine tuning
    7.4 Where to go for more help

 8. Final Steps

 9. First Example: Xscrabble

 10. Second Example: Xloadimage

 11. Third Example: Fortune

 12. Fourth Example: Hearts

 13. Fifth Example: XmDipmon

 14. Where to Find Source Archives

 15. Final Words

 16. References and Further Reading

 17. Credits



 ______________________________________________________________________

 11..  IInnttrroodduuccttiioonn

 Many software packages for the various flavors of UNIX and Linux come
 as compressed archives of source files.  The same package may be
 "built" to run on different target machines, and this saves the author
 of the software from having to produce multiple versions. A single
 distribution of a software package may thus end up running, in various
 incarnations, on an Intel box, a DEC Alpha, a RISC workstation, or
 even a mainframe.  Unfortunately, this puts the responsibility of
 actually "building" and installing the software on the end user, the
 de facto "system administrator", the fellow sitting at the keyboard --
 you.  Take heart, though, the process is not nearly as terrifying or
 mysterious as it seems, as this guide will demonstrate.





 22..  UUnnppaacckkiinngg tthhee FFiilleess

 You have downloaded or otherwise acquired a software package.  Most
 likely it is archived (_t_a_r_r_e_d) and compressed (_g_z_i_p_p_e_d), in .tar.gz or
 .tgz form (familiarly known as a "tarball").  First copy it to a
 working directory. Then _u_n_t_a_r and _g_u_n_z_i_p it. The appropriate command
 for this is ttaarr xxzzvvff _f_i_l_e_n_a_m_e, where _f_i_l_e_n_a_m_e is the name of the
 software file, of course.  The de-archiving process will usually
 install the appropriate files in subdirectories it will create.  Note
 that if the package name has a _._Z suffix, then the above procedure
 will serve just as well, though running uunnccoommpprreessss, followed by a ttaarr
 xxvvff also works. You may preview this process by a ttaarr ttzzvvff ffiilleennaammee,
 which lists the files in the archive without actually unpacking them.

 The above method of unpacking "tarballs" is equivalent to either of
 the following:

 +o  gzip -cd filename | tar xvf -

 +o  gunzip -c filename | tar xvf -

    (The '-' causes the _t_a_r command to take its input from stdin.)

 Source files in the new _b_z_i_p_2 (.bz2) format can be unarchived by a
 bbzziipp22 --ccdd ffiilleennaammee || ttaarr xxvvff --, or, more simply by a ttaarr xxyyvvff
 ffiilleennaammee, assuming that tar has been appropriately patched (refer to
 the Bzip2 HOWTO for details). Debian Linux uses a different patch for
 tar, one written by Hiroshi Takekawa, so that the _-_I_, _-_-_b_z_i_p_2_,
 _-_-_b_u_n_z_i_p_2 options work with that particular tar version.

 [Many thanks to R. Brock Lynn and Fabrizio Stefani for corrections and
 updates on the above information.]



 Sometimes the archived file must be untarred and installed from the
 user's home directory, or perhaps in a certain other directory, such
 as /, /usr/src, or /opt, as specified in the package's config info.
 Should you get an error message attempting to untar it, this may be
 the reason. Read the package docs, especially the README and/or
 Install files, if present, and edit the config files and/or Makefiles
 as necessary, consistent with the installation instructions. Note that
 you would nnoott ordinarily alter the Imake file, since this could have
 unforseen consequences.  Most software packages permit automating this
 process by running mmaakkee iinnssttaallll to emplace the binaries in the
 appropriate system areas.


 +o  You might encounter shar files, or _s_h_e_l_l _a_r_c_h_i_v_e_s, especially in
    the source code newsgroups on the Internet.  These remain in use
    because they are readable to humans, and this permits newsgroup
    moderators to sort through them and reject unsuitable ones.  They
    may be unpacked by the uunnsshhaarr ffiilleennaammee..sshhaarr command. Otherwise the
    procedure for dealing with them is the same as for "tarballs".



 +o  Some source archives have been processed using nonstandard DOS,
    Mac, or even Amiga compression utilities such _z_i_p, _a_r_c, _l_h_a, _a_r_j,
    _z_o_o, _r_a_r, and _s_h_k.  Fortunately, Sunsite <http://metalab.unc.edu>
    and other places have Linux uncompression utilities that can deal
    with most or all of these.

 Occasionally, you may need to update or incorporate bug fixes into the
 unarchived source files using a patch or diff file that lists the
 changes.  The doc files and/or README file will inform you should this
 be the case. The normal syntax for invoking Larry Wall's powerful
 _p_a_t_c_h utility is ppaattcchh << ppaattcchhffiillee.

 You may now proceed to the build stage of the process.





 33..  UUssiinngg MMaakkee

 The Makefile is the key to the build process. In its simplest form, a
 Makefile is a script for compiling or building the "binaries", the
 executable portions of a package. The Makefile can also provide a
 means of updating a software package without having to recompile every
 single source file in it, but that is a different story (or a
 different article).

 At some point, the Makefile launches cc or gcc. This is actually a
 preprocessor, a C (or C++) compiler, and a linker, invoked in that
 order.  This process converts the source into the binaries, the actual
 executables.

 Invoking _m_a_k_e usually involves just typing mmaakkee. This generally builds
 all the necessary executable files for the package in question.
 However, make can also do other tasks, such as installing the files in
 their proper directories (mmaakkee iinnssttaallll) and removing stale object
 files (mmaakkee cclleeaann).  Running mmaakkee --nn permits previewing the build
 process, as it prints out all the commands that would be triggered by
 a make, without actually executing them.


 Only the simplest software uses a generic Makefile. More complex
 installations require tailoring the Makefile according to the location
 of libraries, include files, and resources on your particular machine.
 This is especially the case when the build needs the X11 libraries to
 install. _I_m_a_k_e and _x_m_k_m_f accomplish this task.

 An Imakefile is, to quote the man page, a "template" Makefile. The
 imake utility constructs a Makefile appropriate for your system from
 the Imakefile. In almost all cases, however, you would run xxmmkkmmff, a
 shell script that invokes imake, a front end for it.  Check the README
 or INSTALL file included in the software archive for specific
 instructions.  (If, after dearchiving the source files, there is an
 Imake file present in the base directory, this is a dead giveaway that
 xxmmkkmmff should be run.)  Read the Imake and xmkmf man pages for a more
 detailed analysis of the procedure.

 Be aware that xmkmf and make may need to be invoked as root,
 especially when doing a mmaakkee iinnssttaallll to move the binaries over to the
 /usr/bin or /usr/local/bin directories.  Using make as an ordinary
 user without root privileges will likely result in _w_r_i_t_e _a_c_c_e_s_s _d_e_n_i_e_d
 error messages because you lack write permission to system
 directories. Check also that the binaries created have the proper
 execute permissions for you and any other appropriate users.

 Invoking xxmmkkmmff uses the Imake file to build a new Makefile appropriate
 for your system. You would normally invoke xxmmkkmmff with the --aa argument,
 to automatically do a _m_a_k_e _M_a_k_e_f_i_l_e_s_, _m_a_k_e _i_n_c_l_u_d_e_s_, and _m_a_k_e _d_e_p_e_n_d.
 This sets the variables and defines the library locations for the
 compiler and linker.  Sometimes, there will be no Imake file, instead
 there will be an INSTALL or configure script that will accomplish this
 purpose. Note that if you run configure, it should be invoked as
 ..//ccoonnffiigguurree to ensure that the correct configure script in the current
 directory is called. In most cases, the README file included with the
 distribution will explain the install procedure.

 It is usually a good idea to visually inspect the Makefile that xmkmf
 or one of the install scripts builds. The Makefile will normally be
 correct for your system, but you may occasionally be required to
 "tweak" it or correct errors manually.


 Installing the freshly built binaries into the appropriate system
 directories is usually a matter of running mmaakkee iinnssttaallll as root. The
 usual directories for system-wide binaries on modern Linux
 distributions are /usr/bin, /usr/X11R6/bin, and /usr/local/bin. The
 preferred directory for new packages is /usr/local/bin, as this will
 keep separate binaries not part of the original Linux installation.

 Packages originally targeted for commercial versions of UNIX may
 attempt to install in the /opt or other unfamiliar directory. This
 will, of course, result in an installation error if the intended
 installation directory does not exist. The simplest way to deal with
 this is to create, as root, an /opt directory, let the package install
 there, then add that directory to the PATH environmental variable.
 Alternatively, you may create symbolic links to the /usr/local/bin
 directory.



 Your general installation procedure will therefore be:

 +o  Read the README file and other applicable docs.

 +o  Run xxmmkkmmff --aa, or the INSTALL or configure script.

 +o  Check the Makefile.

 +o  If necessary, run mmaakkee cclleeaann, mmaakkee MMaakkeeffiilleess, mmaakkee iinncclluuddeess, and
    mmaakkee ddeeppeenndd.

 +o  Run mmaakkee.

 +o  Check file permissions.

 +o  If necessary, run mmaakkee iinnssttaallll.


 _N_o_t_e_s_:


 +o  You would not normally build a package as root. Doing an ssuu to root
    is only necessary for installing the compiled binaries into system
    directories.

 +o  After becoming familiar with _m_a_k_e and its uses, you may wish to add
    additional optimization options passed to gcc in the standard
    Makefile included or created in the package you are installing.
    Some of these common options are _-_O_2, _-_f_o_m_i_t_-_f_r_a_m_e_-_p_o_i_n_t_e_r,
    _-_f_u_n_r_o_l_l_-_l_o_o_p_s, and _-_m_p_e_n_t_i_u_m (if you are running a Pentium cpu).
    Use caution and good sense when modifying a Makefile!

 +o  After the _m_a_k_e creates the binaries, you may wish to ssttrriipp them.
    The ssttrriipp command removes the symbolic debugging information from
    the binaries, and reduces their size, often drastically. This also
    disables debugging, of course.

 +o  The Pack Distribution Project <http://sunsite.auc.dk/pack/> offers
    a different approach to creating archived software packages, based
    on a set of Python scripting tools for managing symbolic links to
    files installed in separate _c_o_l_l_e_c_t_i_o_n _d_i_r_e_c_t_o_r_i_e_s. These archives
    are ordinary _t_a_r_b_a_l_l_s, but they install in /coll and /pack
    directories. You may find it necessary to download the _P_a_c_k_-
    _C_o_l_l_e_c_t_i_o_n from the above site should you ever run across one of
    these distributions.




 44..  PPrreeppaacckkaaggeedd BBiinnaarriieess



 44..11..  WWhhaattss wwrroonngg wwiitthh rrppmmss??


 Manually building and installing packages from source is apparently so
 daunting a task for some Linux users that they have embraced the
 popular _r_p_m and _d_e_b or the newer Stampede _s_l_p package formats. While
 it may be the case that an _r_p_m install normally runs as smoothly and
 as fast as a software install in a certain other notorious operating
 system, some thought should certainly be given to the disadvantages of
 self-installing, prepackaged binaries.

 First, be aware that software packages are normally released first as
 "tarballs", and that prepackaged binaries follow days, weeks, even
 months later.  A current _r_p_m package is typically at least a couple of
 minor version behind the latest "tarball".  So, if you wish to keep up
 with all the 'bleeding edge' software, you might not wish to wait for
 an _r_p_m or _d_e_b to appear. Some less popular packages may never be
 _r_p_m'ed.

 Second, the "tarball" package may well be more complete, have more
 options, and lend itself better to customization and tweaking.  The
 binary rpm version may be missing some of the functionality of the
 full release.  Source _r_p_m's contain the full source code and are
 equivalent to the corresponding "tarballs", and they likewise need to
 be built and installed using either of the rrppmm ----rreeccoommppiillee
 ppaacckkaaggeennaammee..rrppmm or rrppmm ----rreebbuuiilldd ppaacckkaaggeennaammee..rrppmm options.

 Third, some prepackaged binaries will not properly install, and even
 if they do install, they could crash and core-dump. They may depend on
 different library versions than are present in your system, or they
 may be improperly prepared or just plain broken. In any case, when
 installing an _r_p_m or _d_e_b you necessarily trust the expertise of the
 persons who have packaged it.

 Finally, it helps to have the source code on hand, to be able to
 tinker with and learn from it. It is much more straightforward to have
 the source in the archive you are building the binaries from, and not
 in a separate source _r_p_m.


 Installing an _r_p_m package is not necessarily a no-brainer.  If there
 is a dependency conflict, an _r_p_m install will fail. Likewise, should
 the _r_p_m require a different version of libraries than the ones present
 on your system, the install may not work, even if you create symbolic
 links to the missing libraries from the ones in place.  Despite their
 convenience, _r_p_m installs often fail for the same reasons "tarball"
 ones do.

 You must install _r_p_m's and _d_e_b's as root, in order to have the
 necessary write permissions, and this opens a potentially serious
 security hole, as you may inadvertently clobber system binaries and
 libraries, or even install a _T_r_o_j_a_n _h_o_r_s_e that might wreak havoc upon
 your system.  It is therefore important to obtain _r_p_m and _d_e_b packages
 from a "trusted source". In any case, you should run a 'signature
 check' (against the MD5 checksum) on the package, rrppmm ----cchheecckkssiigg
 ppaacckkaaggeennaammee..rrppmm, before installing. Likewise highly recommended is
 running rrppmm --KK ----nnooppggpp ppaacckkaaggeennaammee..rrppmm.  The corresponding commands
 for _d_e_b packages are ddppkkgg --II || ----iinnffoo ppaacckkaaggeennaammee..ddeebb and ddppkkgg --ee ||
 ----ccoonnttrrooll ppaacckkaaggeennaammee..ddeebb.


 +o  rpm --checksig gnucash-1.1.23-4.i386.rpm






 gnucash-1.1.23-4.i386.rpm: size md5 OK


 +o  rpm -K --nopgp gnucash-1.1.23-4.i386.rpm






 gnucash-1.1.23-4.i386.rpm: size md5 OK

 For the truly paranoid (and, in this case there is much to be said for
 paranoia), there are the _u_n_r_p_m and _r_p_m_u_n_p_a_c_k utilities available from
 the Sunsite utils/package directory for unpacking and checking the
 individual components of the packages.

 Klee Diene <mailto:[email protected]> has written an experimental
 _d_p_k_g_c_e_r_t package for verifying the integrity of installed _._d_e_b files
 against MD5 checksums.  It is available from the Debian ftp archive
 <ftp://ftp.debian.org/pub/debian/project/experimental>.  The current
 package name / version is _d_p_k_g_c_e_r_t___0_._2_-_4_._1___a_l_l_._d_e_b. The Jim Pick
 Software <http://dpkgcert.jimpick.com> site maintains an experimental
 server database to provide _d_p_k_g_c_e_r_t certificates for the packages in a
 typical Debian installation.

 In their most simple form, the commands rrppmm --ii ppaacckkaaggeennaammee..rrppmm and
 ddppkkgg ----iinnssttaallll ppaacckkaaggeennaammee..ddeebb automatically unpack and install the
 software.  Exercise caution, though, since using these commands
 blindly may be dangerous to your system's health!

 Note that the above warnings also apply, though to a lesser extent, to
 Slackware's _p_k_g_t_o_o_l installation utility. All "automatic" software
 installations require caution.

 The martian
 <http://www.people.cornell.edu/pages/rc42/program/martian.html> and
 alien <http://kitenet.net/programs/alien/> programs allow conversion
 between the _r_p_m, _d_e_b, Stampede _s_l_p, and _t_a_r_._g_z package formats. This
 makes these packages accessible to all Linux distributions.

 Carefully read the man pages for the _r_p_m and _d_p_k_g commands, and refer
 to the RPM HOWTO, TFUG's Quick Guide to Red Hat's Package Manager
 <http://www.tfug.org/helpdesk/linux/rpm.html>, and The Debian Package
 Management Tools <http://www.debian.org/doc/FAQ/debian-faq-7.html> for
 more detailed information.



 44..22..  PPrroobblleemmss wwiitthh rrppmmss:: aann eexxaammppllee


 Jan Hubicka <mailto:[email protected]> wrote a very nice fractal
 package called _x_a_o_s.  At his home page
 <http://www.paru.cas.cz/~hubicka/XaoS>, both .tar.gz and rpm packages
 are available.  For the sake of convenience, let us try the rpm
 version, rather than the "tarball".

 Unfortunately, the rpm of _x_a_o_s fails to install. Two separate rpm
 versions misbehave.

 rrppmm --ii ----tteesstt XXaaooSS--33..00--11..ii338866..rrppmm


      error: failed dependencies:
              libslang.so.0 is needed by XaoS-3.0-1
              libpng.so.0 is needed by XaoS-3.0-1
              libaa.so.1 is needed by XaoS-3.0-1




 rrppmm --ii ----tteesstt xxaaooss--33..00--88..ii338866..rrppmm


      error: failed dependencies:
              libaa.so.1 is needed by xaos-3.0-8




 The strange thing is that libslang.so.0, libpng.so.0, and libaa.so.1
 are all present in /usr/lib on the system tested. The rpms of _x_a_o_s
 must have been built with slightly different versions of those
 libraries, even if the release numbers are identical.

 As a test, let us try installing xaos-3.0-8.i386.rpm with the _-_-_n_o_d_e_p_s
 option to force the install. A trial run of _x_a_o_s crashes.


      xaos: error in loading shared libraries: xaos: undefined symbol: __fabsl




 Let us stubbornly try to get to the bottom of this.  Running _l_d_d on
 the _x_a_o_s binary to find its library dependencies shows all the
 necessary shared libraries present. Running _n_m on the
 /usr/lib/libaa.so.1 library to list its symbolic references shows that
 it is indeed missing _____f_a_b_s_l.  Of course, the absent reference _c_o_u_l_d
 be missing from one of the other libraries...  There is nothing to be
 done about that, short of replacing one or more libraries.


 Enough! Download the "tarball", XaoS-3.0.tar.gz, available from the
 ftp site <ftp://ftp.ta.jcu.cz/pub/linux/hubicka/XaoS/3.0>, as well as
 from the home page.  Try building it. Running ..//ccoonnffiigguurree, mmaakkee, and
 finally (as root) mmaakkee iinnssttaallll, works flawlessly.

 This is one of an number of examples of prepackaged binaries being
 more trouble than they are worth.





 55..  TTeerrmmccaapp aanndd TTeerrmmiinnffoo IIssssuueess



 According to its man page, _"_t_e_r_m_i_n_f_o _i_s _a _d_a_t_a _b_a_s_e _d_e_s_c_r_i_b_i_n_g
 _t_e_r_m_i_n_a_l_s_, _u_s_e_d _b_y _s_c_r_e_e_n_-_o_r_i_e_n_t_e_d _p_r_o_g_r_a_m_s_._._._".  It defines a generic
 set of control sequences (escape codes) used to display text on
 terminals, and makes possible support for different terminal hardware
 without the need for special drivers. The _t_e_r_m_i_n_f_o libraries are
 located in /usr/share/terminfo on modern Linux distributions.

 The _t_e_r_m_i_n_f_o database has largely supplanted the older _t_e_r_m_c_a_p and the
 totally obsolete _t_e_r_m_l_i_b ones. This is usually of no concern for
 program installation except when dealing with a package that requires
 _t_e_r_m_c_a_p.

 Most Linux distributions now use _t_e_r_m_i_n_f_o, but still retain the older
 termcap libraries for compatibility with legacy applications (see
 /etc/termcap). Sometimes there is a special compatibility package that
 needs to be installed to facilitate use of termcap linked binaries.
 Very occasionally, an _#_d_e_f_i_n_e _t_e_r_m_c_a_p statement might need to be
 commented out of a source file.  Check the appropriate doc files for
 your particular distribution for definitive information on this.




 66..  BBaacckkwwaarrdd CCoommppaattiibbiilliittyy WWiitthh aa..oouutt BBiinnaarriieess


 In a very few cases, it is necessary to use a.out binaries, either
 because the source code is not available or because it is not possible
 to build new ELF binaries from the source for some reason.

 As it happens, ELF installations almost always have a complete set of
 a.out libraries in the /usr/i486-linuxaout/lib directory.  The
 numbering scheme for a.out libraries differs from that of ELF ones,
 cleverly avoiding conflicts that could cause confusion.  The a.out
 binaries should therefore be able to find the correct libraries at
 runtime, but this might not always be the case.

 Note that the kernel needs to have a.out support built into it, either
 directly or as a loadable module. It may be necessary to rebuild the
 kernel to enable this. Moreover, some Linux distributions require
 installation of a special compatibility package, such as Debian's
 xcompat for executing a.out X applications.


 66..11..  AAnn EExxaammppllee


 Jerry Smith wrote a very handy _r_o_l_o_d_e_x program some years back. It
 uses the Motif libraries, but fortunately is available as a statically
 linked binary in a.out format. Unfortunately, the source requires
 numerous tweaks to rebuild using the _l_e_s_s_t_i_f libraries. Even more
 unfortunately, the a.out binary bombs on an ELF system with the
 following error message.


      xrolodex: can't load library '//lib/libX11.so.3'
      No such library




 As it happens, there is such a library, in /usr/i486-linuxaout/lib,
 but xrolodex is unable to locate it at run time. The simple solution
 is to provide a symbolic link in the /lib directory:

 ln -s /usr/i486-linuxaout/lib/X11.so.3.1.0 libX11.so.3


 It turns out to be necessary to provide similar links for the
 libXt.so.3 and libc.so.4 libraries. This needs to be done as root, of
 course. Note that you should make absolutely certain you will not
 overwrite or cause version number conflicts with pre-existing
 libraries.  Fortunately, the new ELF libraries have higher version
 numbers than the older a.out ones, to anticipate and forestall just
 such problems.

 After creating the three links, _x_r_o_l_o_d_e_x runs fine.

 The _x_r_o_l_o_d_e_x package was originally posted on Spectro
 <http://www.spectro.com/>, but seems to vanished from there. It may
 currently be downloaded from Sunsite
 <http://metalab.unc.edu/pub/Linux/apps/reminder/xrolodex.tar.z> as a
 _t_a_r_._Z format source file [512k].




 77..  TTrroouubblleesshhoooottiinngg


 If _x_m_k_m_f and/or _m_a_k_e succeeded without errors, you may proceed to the
 ``next section''.  However, in "real life", few things work right the
 first time.  This is when your resourcefulness is put to the test.


 77..11..  LLiinnkk EErrrroorrss


 +o  Suppose _m_a_k_e fails with a Link error: -lX11: No such file or
    directory, even after xmkmf has been invoked. This may mean that
    the _I_m_a_k_e file was not set up properly. Check the first part of the
    _M_a_k_e_f_i_l_e for lines such as:



      LIB=            -L/usr/X11/lib
      INCLUDE=        -I/usr/X11/include/X11
      LIBS=           -lX11 -lc -lm





 The -L and -I switches tell the compiler and linker where to look for
 the _l_i_b_r_a_r_y and _i_n_c_l_u_d_e files, respectively. In this example, the _X_1_1
 _l_i_b_r_a_r_i_e_s should be in the /usr/X11/lib directory, and the _X_1_1 _i_n_c_l_u_d_e
 _f_i_l_e_s should be in the /usr/X11/include/X11 directory. If this is
 incorrect for your machine, make the necessary changes to the _M_a_k_e_f_i_l_e
 and try the _m_a_k_e again.


 +o  Undefined references to math library functions, such as the
    following:


               /tmp/cca011551.o(.text+0x11): undefined reference to `cos'




 The fix for this is to explicitly link in the math library, by adding
 an --llmm to the _L_I_B or _L_I_B_S flags in the Makefile (see previous exam-
 ple).




 +o  Yet another thing to try if _x_m_k_m_f fails is the following script:


               make -DUseInstalled -I/usr/X386/lib/X11/config




 This is a sort of bare bones equivalent of _x_m_k_m_f.


 +o  In a very few cases, running _l_d_c_o_n_f_i_g as _r_o_o_t may be the solution:







 ## llddccoonnffiigg updates the shared library symbolic links. _T_h_i_s _m_a_y _n_o_t _b_e
 _n_e_c_e_s_s_a_r_y _.


 +o  Some Makefiles use unrecognized aliases for libraries present in
    your system. For example, the build may require libX11.so.6, but
    there exists no such file or link in /usr/X11R6/lib. Yet, there is
    a libX11.so.6.1. The solution is to do a llnn --ss
    //uussrr//XX1111RR66//lliibb//lliibbXX1111..ssoo..66..11 //uussrr//XX1111RR66//lliibb//lliibbXX1111..ssoo..66, as root.
    This may need to be followed by a llddccoonnffiigg.



 +o  Sometimes the source needs the older release X11R5 libraries to
    build.  If you have the R5 libs in /usr/X11R6/lib (you were given
    the option of having them when first installing Linux), then you
    need only ensure that you have the links that the software needs to
    build.  The R5 libs are named libX11.so.3.1.0, libXaw.so.3.1.0, and
    libXt.so.3.1.0. You generally need links, such as _l_i_b_X_1_1_._s_o_._3 _-_>
    _l_i_b_X_1_1_._s_o_._3_._1_._0. Possibly the software will also need a link of the
    form _l_i_b_X_1_1_._s_o _-_> _l_i_b_X_1_1_._s_o_._3_._1_._0.  Of course, to create a
    "missing" link, use the command llnn --ss lliibbXX1111..ssoo..33..11..00 lliibbXX1111..ssoo, _a_s
    _r_o_o_t.



 +o  Some packages will require you to install updated versions of one
    or more libraries. For example, the 4.x versions of the _S_t_a_r_O_f_f_i_c_e
    suite from StarDivision GmbH were notorious for needing a libc
    version 5.4.4 or greater. Even the more recent _S_t_a_r_O_f_f_i_c_e 5.0 will
    not run after installation with the new glibc 2.1 libs.
    Fortunately, the newer _S_t_a_r_O_f_f_i_c_e 5.1 solves these problems.  If
    running an older version of _S_t_a_r_O_f_f_i_c_e you would, as _r_o_o_t, need to
    copy one or more libraries to the appropriate directories, remove
    the old libraries, then reset the symbolic links (check the latest
    version of the StarOffice miniHOWTO for more information on this).

    CCaauuttiioonn:: EExxeerrcciissee eexxttrreemmee ccaarree iinn tthhiiss,, aass yyoouu ccaann rreennddeerr yyoouurr
    ssyysstteemm nnoonnffuunnccttiioonnaall iiff yyoouu ssccrreeww uupp..

    You can usually find the latest updated libraries at Sunsite.


 77..22..  OOtthheerr PPrroobblleemmss



 +o  An installed _P_e_r_l or shell script gives you a No such file or
    directory error message. In this case, check the file permissions
    to make sure the file is executable and check the file header to
    ascertain whether the shell or program invoked by the script is in
    the place specified.  For example, the scrip may begin with:


      #!/usr/local/bin/perl




 If _P_e_r_l is in fact installed in your /usr/bin directory instead of the
 /usr/local/bin one, then the script will not run.  There are two meth-
 ods of correcting this. The script file header may be changed to
 #!/usr/bin/perl, or a symbolic link to the correct directory may be
 added, llnn --ss //uussrr//bbiinn//ppeerrll //uussrr//llooccaall//bbiinn//ppeerrll.


 +o  Some X11 software requires the Motif libraries to build.  The
    standard Linux distributions do not have the Motif libraries
    installed, and at present Motif costs an extra $100-$200 (though
    the freeware Lesstif <http://www.lesstif.org/> also works in many
    cases). If you need Motif to build a certain package, but lack the
    Motif libraries, it may be possible to obtain _s_t_a_t_i_c_a_l_l_y _l_i_n_k_e_d
    _b_i_n_a_r_i_e_s. Static linking incorporates the library routines in the
    binaries themselves.  This results in much larger binary files, but
    the code will run on systems lacking the libraries.








 When a package requires libraries not present on your system for the
 build, it will result in link errors (undefined reference errors).
 The libraries may be expensive proprietary ones or difficult to find
 for sone other reason.  In that case, obtaining a _s_t_a_t_i_c_a_l_l_y _l_i_n_k_e_d
 binary either from the author of the package or from a Linux user
 group may be the easiest to implement fix.



 +o  Running a _c_o_n_f_i_g_u_r_e script creates a strange Makefile, one
    seemingly unrelated to the package you are attempting to build.
    This means the wrong _c_o_n_f_i_g_u_r_e ran, one found somewhere else in
    your path. Always invoke _c_o_n_f_i_g_u_r_e as ..//ccoonnffiigguurree to prevent this.



 +o  Most Linux distributions have changed over to the libc 6 / glibc 2
    libraries from the older libc 5. Precompiled binaries that worked
    with the older library may bomb if you have upgraded your library.
    The solution is to either recompile the applications from the
    source or to obtain newer precompiled binaries.  If you are in the
    process of upgrading your system to libc 6 and are experiencing
    problems, refer to Eric Green's _G_l_i_b_c _2 _H_O_W_T_O.








 Note that there are some minor incompatibilities between glibc ver-
 sions, so a binary built with glibc 2.1 may not work with glibc 2.0,
 and vice versa.



 +o  Sometimes it is necessary to remove the _-_a_n_s_i option from the
    compile flags in the Makefile. This enables gcc's extra, non-ANSI
    features, and allows building packages that require these
    extensions. (Thanks to Sebastien Blondeel for pointing this out.)


 +o  Some programs require having _s_e_t_u_i_d _r_o_o_t, in order to run with _r_o_o_t
    _p_r_i_v_i_l_e_g_e_s. The command to implement this is cchhmmoodd uu++ss ffiilleennaammee, _a_s
    _r_o_o_t (note that the program must already be owned by root). This
    has the effect of setting the _s_e_t_u_i_d bit in the file permissions.
    This issue comes up when the program accesses the system hardware,
    such as a modem or CD ROM drive, or when the SVGA libs are invoked
    from console mode, as in one particularly notorious emulation
    package. If a program works when run by root, but gives _a_c_c_e_s_s
    _d_e_n_i_e_d error messages to an ordinary user, suspect this as the
    cause.



    WWaarrnniinngg:: A program with _s_e_t_u_i_d as root may pose a security risk to
    your system. The program runs with root privileges and thus has the
    potential for doing significant damage. Make certain that you know
    what the program does, by looking at the source if possible, before
    setting the _s_e_t_u_i_d bit.




 77..33..  TTwweeaakkiinngg aanndd ffiinnee ttuunniinngg


 You may wish to examine the Makefile to make certain that the best
 compilation options for your system are invoked. For example, setting
 the _-_O_2 flag chooses the highest level of optimization and the _-_f_o_m_i_t_-
 _f_r_a_m_e_-_p_o_i_n_t_e_r flag results in a smaller binary (though debugging will
 then be disabled). DDoo nnoott ppllaayy aarroouunndd wwiitthh tthhiiss uunnlleessss yyoouu kknnooww wwhhaatt
 yyoouu aarree ddooiinngg,, aanndd iinn aannyy ccaassee,, nnoott uunnttiill aafftteerr aa ttrriiaall _b_u_i_l_d wwoorrkkss..

 77..44..  WWhheerree ttoo ggoo ffoorr mmoorree hheellpp


 In my experience, perhaps 25% of applications build "right out of the
 box". Another 50% or so can be "persuaded" to build with an effort
 ranging from trivial to herculean. That still means a significant
 number of packages will not build no matter what. Even then, the Intel
 ELF and/or a.out binaries for these might possibly be found at Sunsite
 or the TSX-11 archive.  Red Hat <http://redhat.com> and Debian
 <http://www.debian.org> have extensive archives of prepackaged
 binaries of most of the popular Linux software.  Perhaps the author of
 the software can supply the binaries compiled for your particular
 flavor of machine.


 Note that if you obtain precompiled binaries, you will need to check
 for compatibility with your system:

 +o  The binaries must run on your hardware (i.e., Intel x86).

 +o  The binaries must be compatible with your kernel (i.e., a.out or
    ELF).

 +o  Your libraries must be up to date.

 +o  Your system must have the appropriate installation utility (rpm or
    deb).

 If all else fails, you may find help in the appropriate newsgroups,
 such as comp.os.linux.x or comp.os.linux.development.

 If nothing at all works, at least you gave it your best effort, and
 you learned a lot.







 88..  FFiinnaall SStteeppss

 Read the software package documentation to determine whether certain
 environmental variables need setting (in .bashrc or .cshrc) and if the
 .Xdefaults and .Xresources files need customizing.

 There may be an applications default file, usually named Xfoo.ad in
 the original Xfoo distribution. If so, edit the Xfoo.ad file to
 customize it for your machine, then rename (mmvv) it Xfoo and install it
 in the /usr/lib/X11/app-defaults directory, _a_s _r_o_o_t.  Failure to do
 this may cause the software to behave strangely or even refuse to run.

 Most software packages come with one or more preformatted man pages.
 _A_s _r_o_o_t, copy the Xfoo.man file to the appropriate /usr/man,
 /usr/local/man, or /usr/X11R6/man directory (man1 - man9), and rename
 it accordingly.  For example, if Xfoo.man ends up in /usr/man/man4, it
 should be renamed Xfoo.4 (mv Xfoo.man Xfoo.4).  By convention, user
 commands go in man1, games in man6, and administration packages in
 man8 (see the _m_a_n _d_o_c_s for more details).  Of course, you may deviate
 from this on your own system, if you like.

 A few packages will not install the binaries in the appropriate system
 directories, that is, they are missing the _i_n_s_t_a_l_l option in the
 Makefile. Should this be the case, you can install the binaries
 manually by copying the binaries to the appropriate system directory,
 /usr/bin, /usr/local/bin or /usr/X11R6/bin, _a_s _r_o_o_t, of course. Note
 that /usr/local/bin is the preferred directory for binaries that are
 not part of the Linux distribution's base install.

 Some or all of the above procedures should, in most cases, be handled
 automatically by a mmaakkee iinnssttaallll, and possibly a mmaakkee iinnssttaallll..mmaann or
 mmaakkee iinnssttaallll__mmaann. If so, the README or INSTALL doc file will specify
 this.



 99..  FFiirrsstt EExxaammppllee:: XXssccrraabbbbllee

 Matt Chapman's Xscrabble seemed like a program that would be
 interesting to have, since I happen to be an avid ScrabbleTM player. I
 downloaded it, uncompressed it,  and built it following the procedure
 in the README file:


           xmkmf
           make Makefiles
           make includes
           make




 _O_f _c_o_u_r_s_e _i_t _d_i_d _n_o_t _w_o_r_k_._._.



      gcc -o xscrab -O2 -O -L/usr/X11R6/lib
      init.o xinit.o misc.o moves.o cmove.o main.o xutils.o mess.o popup.o
      widgets.o display.o user.o CircPerc.o
      -lXaw -lXmu -lXExExt -lXext -lX11 -lXt -lSM -lICE -lXExExt -lXext -lX11
      -lXpm -L../Xc -lXc

      BarGraf.o(.text+0xe7): undefined reference to `XtAddConverter'
      BarGraf.o(.text+0x29a): undefined reference to `XSetClipMask'
      BarGraf.o(.text+0x2ff): undefined reference to `XSetClipRectangles'
      BarGraf.o(.text+0x375): undefined reference to `XDrawString'
      BarGraf.o(.text+0x3e7): undefined reference to `XDrawLine'
      etc.
      etc.
      etc...




 I enquired about this in the comp.os.linux.x newsgroup, and someone
 kindly pointed out that apparently the Xt, Xaw, Xmu, and X11 libs were
 not being found at the link stage. Hmmm...

 There were two main Makefiles, and the one in the src directory caught
 my interest. One line in the Makefile defined LOCAL_LIBS as:
 LOCAL_LIBS = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) Here were
 references to the libs not being found by the linker.

 Looking for the next reference to LOCAL_LIBS, I saw on line 495 of
 that Makefile:


            $(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(LOCAL_LIBS) $(LDLIBS)
      $(EXTRA_LOAD_FLAGS)



 Now what were these LDLIBS?


            LDLIBS = $(LDPOSTLIB) $(THREADS_LIBS) $(SYS_LIBRARIES)
      $(EXTRA_LIBRARIES)




 The SYS_LIBRARIES were:


       SYS_LIBRARIES = -lXpm -L../Xc -lXc




 Yes! Here were the missing libraries.

 Possibly the linker needed to see the LDLIBS before the LOCAL_LIBS...
 So, the first thing to try was to modify the Makefile by transposing
 the $(LOCAL_LIBS) and $(LDLIBS) on line 495, so it would now read:


              $(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(LDLIBS) $(LOCAL_LIBS)
      $(EXTRA_LOAD_FLAGS)                          ^^^^^^^^^^^^^^^^^^^^^^^




 I tried running _m_a_k_e again with the above change, and lo and behold,
 it worked this time. Of course,  Xscrabble still needed some fine
 tuning and twiddling, such as renaming the dictionary and commenting
 out some assert statements in one of the source files, but since then
 it has provided me with many hours of pleasure.



 [Note that a newer version of Xscrabble is now available in rpm
 format, and this installs without problems.]




 You may e-mail Matt Chapman <mailto:[email protected]>, and
 download _X_s_c_r_a_b_b_l_e from his home page
 <http://www.belgarath.demon.co.uk/programs/index.html>.






             Scrabble is a registered trademark of the Milton Bradley Co., Inc.








 1100..  SSeeccoonndd EExxaammppllee:: XXllooaaddiimmaaggee

 This example poses an easier problem. The _x_l_o_a_d_i_m_a_g_e program seemed a
 useful addition to my set of graphic tools.  I copied the xloadi41.gz
 file directly from the source directory on the CD included with the
 excellent ``X User Tools'' book, by Mui and Quercia. As expected, _t_a_r
 _x_z_v_f unarchives the files.  The _m_a_k_e, however, produces a nasty-
 looking error and terminates.



      gcc -c -O -fstrength-reduce -finline-functions -fforce-mem
      -fforce-addr -DSYSV  -I/usr/X11R6/include
      -DSYSPATHFILE=\"/usr/lib/X11/Xloadimage\" mcidas.c

      In file included from /usr/include/stdlib.h:32,
                       from image.h:23,
                       from xloadimage.h:15,
                       from mcidas.c:7:
      /usr/lib/gcc-lib/i486-linux/2.6.3/include/stddef.h:215:
      conflicting types for `wchar_t'
      /usr/X11R6/include/X11/Xlib.h:74: previous declaration of
      `wchar_t'
      make[1]: *** [mcidas.o] Error 1
      make[1]: Leaving directory
      `/home/thegrendel/tst/xloadimage.4.1'
      make: *** [default] Error 2




 The error message contains the essential clue.

 Looking at the file image.h, line 23...


             #include <stdlib.h>




 Aha, somewhere in the source for _x_l_o_a_d_i_m_a_g_e, _w_c_h_a_r___t has been
 redefined from what was specified in the standard include file,
 stdlib.h. Let us first try commenting out line 23 in image.h, as
 perhaps the _s_t_d_l_i_b_._h _i_n_c_l_u_d_e is not, after all, necessary.

 At this point, the build proceeds without any fatal errors. The
 _x_l_o_a_d_i_m_a_g_e package functions correctly now.






 1111..  TThhiirrdd EExxaammppllee:: FFoorrttuunnee

 This example requires some knowledge of C programming. The majority of
 UNIX/Linux software is written in C, and learning at least a little
 bit of C would certainly be an asset for anyone serious about software
 installation.

 The notorious _f_o_r_t_u_n_e program displays up a humorous saying, a
 "fortune cookie", every time Linux boots up. Unfortunately (pun
 intended), attempting to build fortune on a Red Hat distribution with
 a 2.0.30 kernel generates fatal errors.





 ~/fortune# make all


 gcc -O2 -Wall -fomit-frame-pointer -pipe   -c fortune.c -o
 fortune.o
 fortune.c: In function `add_dir':
 fortune.c:551: structure has no member named `d_namlen'
 fortune.c:553: structure has no member named `d_namlen'
 make[1]: *** [fortune.o] Error 1
 make[1]: Leaving directory `/home/thegrendel/for/fortune/fortune'
 make: *** [fortune-bin] Error 2







 Looking at fortune.c, the pertinent lines are these.



         if (dirent->d_namlen == 0)
                  continue;
              name = copy(dirent->d_name, dirent->d_namlen);




 We need to find the structure dirent, but it is not declared in the
 _f_o_r_t_u_n_e_._c file, nor does a ggrreepp ddiirreenntt show it in any of the other
 source files. However, at the top of _f_o_r_t_u_n_e_._c, there is the following
 line.



      #include <dirent.h>




 This appears to be a system library include file, therefore, the
 logical place to look for _d_i_r_e_n_t_._h is in _/_u_s_r_/_i_n_c_l_u_d_e.  Indeed, there
 does exist a _d_i_r_e_n_t_._h file in _/_u_s_r_/_i_n_c_l_u_d_e, but that file does not
 contain the declaration of the dirent structure.  There is, however, a
 reference to another _d_i_r_e_n_t_._h file.



      #include <linux/dirent.h>





 At last, going to _/_u_s_r_/_i_n_c_l_u_d_e_/_l_i_n_u_x_/_d_i_r_e_n_t_._h, we find the structure
 declaration we need.









 struct dirent {
         long            d_ino;
         __kernel_off_t  d_off;
         unsigned short  d_reclen;
         char            d_name[256]; /* We must not include
 limits.h! */
 };




 Sure enough, the structure declaration contains no _d___n_a_m_e_l_e_n, but
 there are a couple of "candidates" for its equivalent. The most likely
 of these is _d___r_e_c_l_e_n, since this structure member probably represents
 the length of something and it is a short integer.  The other
 possibility, _d___i_n_o, could be an inode number, judging by its name and
 type. As a matter of fact, we are probably dealing with a "directory
 entry" structure, and these elements represent attributes of a file,
 its name, inode, and length (in blocks).  This would seem to validate
 our guess.

 Let us edit the file fortune.c, and change the two _d___n_a_m_e_l_e_n
 references in lines 551 and 553 to _d___r_e_c_l_e_n.  Try a _m_a_k_e _a_l_l again.
 SSuucccceessss.. It builds without errors. We can now get our "cheap thrills"
 from fortune.



 1122..  FFoouurrtthh EExxaammppllee:: HHeeaarrttss


 Here is the hoary old game of Hearts, written for UNIX systems by Bob
 Ankeney sometime in the '80's, revised in 1992 by Mike Yang, and
 currently maintained by Jonathan Badger
 <mailto:[email protected]>. Its predecessor was an even older
 Pascal program by Don Backus of Oregon Software, later updated by Jeff
 Hemmerling. Originally intended as a multiplayer client, it also works
 well in single-player mode against computer opponents. The graphics
 are nice, though the game lacks sophisticated features and the
 computer players are not particularly strong. All the same, it seems
 to be the only decent Hearts game available for UNIX and Linux
 machines even at this late date.

 Due to its age and lineage, this package is particularly difficult to
 build on a Linux system. It requires solving a long and perplexing
 series of puzzles.  It is an exercise in patience and determination.

 _B_e_f_o_r_e _b_e_g_i_n_n_i_n_g_, _m_a_k_e _c_e_r_t_a_i_n _t_h_a_t _y_o_u _h_a_v_e _e_i_t_h_e_r _t_h_e motif or
 lesstif libraries installed.


 +o

 xxmmkkmmff

 mmaakkee










 client.c: In function `read_card':
 client.c:430: `_tty' undeclared (first use in this function)
 client.c:430: (Each undeclared identifier is reported only once
 client.c:430: for each function it appears in.)
 client.c: In function `scan':
 client.c:685: `_tty' undeclared (first use in this function)
 make: *** [client.o] Error 1





 These are the culprits in the file client.c:



      #ifndef SYSV
              (buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) {
       #else
              (buf[2] != CERASE) && (buf[2] != CKILL)) {
      #endif








 +o

 In client.c, add


      #define SYSV




 at line 39. This will bypass the reference to ___t_t_y.

 mmaakkee



      client.c:41: sys/termio.h: No such file or directory
      make: *** [client.o] Error 1






 +o

 The include file termio.h is in the /usr/include directory on a Linux
 system, rather than the /usr/include/sys one, as was the case on older
 UNIX machines.  Therefore, change line 41 of client.c from


      #include <sys/termio.h>




 to
      #include <termio.h>




 mmaakkee



      gcc -o hearts -g      -L/usr/X11R6/lib client.o hearts.o select.o connect.o
      sockio.o start_dist.o  -lcurses -ltermlib
      /usr/bin/ld: cannot open -ltermlib: No such file or directory
      collect2: ld returned 1 exit status
      make: *** [hearts] Error 1







 +o

 Modern Linux distributions use the _t_e_r_m_i_n_f_o and/or _t_e_r_m_c_a_p database,
 rather than the obsolete _t_e_r_m_l_i_b one.

 Edit the Makefile.

 Line 655:


      CURSES_LIBRARIES = -lcurses -ltermlib




 changes to:


      CURSES_LIBRARIES = -lcurses -ltermcap





 mmaakkee



      gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
      connect.o sockio.o start_dist.o gfx.o  -lXm_s -lXt -lSM -lICE -lXext -lX11
      -lPW
      /usr/bin/ld: cannot open -lXm_s: No such file or directory
      collect2: ld returned 1 exit status







 +o

 The main _l_e_s_s_t_i_f library is libXm, rather than libXm_s. Therefore,
 edit the Makefile.

 In line 653:


      XMLIB = -lXm_s $(XTOOLLIB) $(XLIB) -lPW




 changes to:


      XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW





 mmaakkee



      gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
      connect.o sockio.o start_dist.o gfx.o  -lXm -lXt -lSM -lICE -lXext -lX11 -lPW
      /usr/bin/ld: cannot open -lPW: No such file or directory
      collect2: ld returned 1 exit status
      make: *** [xmhearts] Error 1







 +o

 Round up the usual suspects.

 There is no PW library.  Edit the Makefile.

 Line 653:


      XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW




 changes to:


      XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPEX5




 (The PEX5 lib comes closest to PW.)


 mmaakkee







 rm -f xmhearts
 gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
 connect.o sockio.o start_dist.o gfx.o  -lXm -lXt -lSM -lICE -lXext -lX11 -lPEX5




 The make finally works (hurray!).




 +o

 _I_n_s_t_a_l_l_a_t_i_o_n_:

 As root,



      [root@localhost hearts]# make install
      install -c -s  hearts /usr/X11R6/bin/hearts
      install -c -s  xmhearts /usr/X11R6/bin/xmhearts
      install -c -s  xawhearts /usr/X11R6/bin/xawhearts
      install in . done









 +o

 _T_e_s_t _r_u_n_:

 rreehhaasshh

 (We're running the tcsh shell.)

 xxmmhheeaarrttss



      localhost:~/% xmhearts
      Can't invoke distributor!







 +o

 From README file in the hearts package:



           Put heartsd, hearts_dist, and hearts.instr in the HEARTSLIB
           directory defined in local.h and make them world-accessible.



 From the file local.h:



      /* where the distributor, dealer and instructions live */

      #define HEARTSLIB "/usr/local/lib/hearts"




 This is a classic case of RTFM.


 As _r_o_o_t,

 ccdd //uussrr//llooccaall//lliibb

 mmkkddiirr hheeaarrttss

 ccdd !!$$

 Copy the distributor files to this directory.

 ccpp //hhoommee//uusseerrnnaammee//hheeaarrttss//hheeaarrttssdd ..

 ccpp //hhoommee//uusseerrnnaammee//hheeaarrttss//hheeaarrttss__ddiisstt ..

 ccpp //hhoommee//uusseerrnnaammee//hheeaarrttss//hheeaarrttss..iinnssttrr ..




 +o

 _T_r_y _a_n_o_t_h_e_r _t_e_s_t _r_u_n_.

 xxmmhheeaarrttss

 It works some of the time, but more often than not crashes with a
 dealer died! message.




 +o

 The "distributor" and "dealer" scan the hardware ports. We should thus
 suspect that those programs need root user privileges.

 Try, as _r_o_o_t,

 cchhmmoodd uu++ss //uussrr//llooccaall//lliibb//hheeaarrttssdd

 cchhmmoodd uu++ss //uussrr//llooccaall//lliibb//hheeaarrttss__ddiisstt

 (Note that, as previously discussed, _s_u_i_d binaries may create security
 holes.)

 xxmmhheeaarrttss


 _I_t _f_i_n_a_l_l_y _w_o_r_k_s_!



 _H_e_a_r_t_s is available from Sunsite.




 1133..  FFiifftthh EExxaammppllee:: XXmmDDiippmmoonn




      Bullwinkle: Hey Rocky, watch me pull a rabbit out of my hat.
      Rocky:      But that trick never works.
      Bullwinkle: This time for sure.
                  Presto!
                  Well, I'm gettin' close.
      Rocky:      And now it's time for another special feature.
                  --- "Rocky and His Friends"





 XmDipmon is a nifty little application that displays a button showing
 the status of an Internet connection. It flashes and beeps when the
 connection is broken, as is all too often the case in on rural
 telephone systems.  Unfortunately, XmDipmon works only with _d_i_p,
 making it useless for those people, the majority, who use _c_h_a_t to
 connect.

 Building XmDipmon is not a problem.  XmDipmon links to the _M_o_t_i_f
 libraries, but it builds and works fine with _L_e_s_s_t_i_f. The challenge is
 to alter the package to work when using _c_h_a_t. This involves actually
 tinkering with the source code, and necessarily requires some
 programming knowledge.





              "When xmdipmon starts up, it checks for a file called /etc/dip.pid
               (you can let it look at another file by using the -pidfile
               command line option).  This file contains the PID of the dip
               deamon (dip switches itself into deamon mode once it has
               established a connection)."
                             --- from the XmDipmon README file






 Using the _-_p_i_d_f_i_l_e option, the program can be directed to check for a
 different file upon startup, one that exists only during a successful
 _c_h_a_t login.  The obvious candidate is the modem lock file. We could
 therefore try invoking the program with xxmmddiippmmoonn --ppiiddffiillee
 //vvaarr//lloocckk//LLCCKK....ttttyySS33 (this assumes that the modem is on com port #4,
 ttyS3). This only solves part of the problem, however. The program
 continually monitors the _d_i_p _d_a_e_m_o_n, and we need to change this so it
 instead polls a process associated with _c_h_a_t or _p_p_p.

 There is only a single source file, and fortunately it is well-
 commented. Scanning the xmdipmon.c file, we find the _g_e_t_P_r_o_c_F_i_l_e
 function, whose header description reads as follows.



 /*****
 * Name:                 getProcFile
 * Return Type:  Boolean
 * Description:  tries to open the /proc entry as read from the dip pid file.
 <snip>
 *****/




 We are hot on the trail now. Tracing into the body of the function...



                              /* we watch the status of the real dip deamon */
                              sprintf(buf, "/proc/%i/status", pid);
                              procfile = (String)XtMalloc(strlen(buf)*sizeof(char)+1);
                              strcpy(procfile, buf);
                              procfile[strlen(buf)] = '\0';




 The culprit is line 2383:


                              sprintf(buf, "/proc/%i/status", pid);
                                            ^^^^^^^^^^^^^^^^^^^^^




 This checks whether the dip daemon process is running . So, how can we
 change this to monitor the pppd daemon instead?

 Looking at the _p_p_p_d manpage:


      FILES
             /var/run/pppn.pid (BSD or Linux), /etc/ppp/pppn.pid (others)
                           Process-ID for pppd process on ppp interface unit n.





 Change line 2383 in xmdipmon.c to:


                              sprintf(buf, "/var/run/ppp0.pid" );




 Rebuild the revised package. No problems with the build. Now test it
 with the new command line argument. It works like a charm. The little
 blue button indicates when a ppp connection to the ISP has been
 established, and flashes and beeps when the connection is broken.  Now
 we have a fully functional _c_h_a_t monitor.


 XmDipmon can be downloaded from Ripley Linux Tools.




 1144..  WWhheerree ttoo FFiinndd SSoouurrccee AArrcchhiivveess

 Now that you are eager to use your newly acquired knowledge to add
 utilities and other goodies to your system, you may find them online
 at the Linux Applications and Utilities Page
 <http://www.redhat.com/linux-info/linux-app-list/linapps.html>, or on
 one of the very reasonably priced CD ROM archives by Red Hat
 <http://www.redhat.com/>, InfoMagic <http://www.infomagic.com>, Linux
 Systems Labs <http://www.lsl.com>, Cheap Bytes
 <http://www.cheapbytes.com>, and others.

 A comprehensive repository of source code is the comp sources UNIX
 archive.

 Much UNIX source code is posted on the alt.sources newsgroup. If you
 are looking for particular source code packages, you may post on the
 related alt.sources.wanted newsgroup.  Another good place to check is
 the comp.os.linux.announce newsgroup.  To get on the Unix sources
 mailing list, send a _s_u_b_s_c_r_i_b_e message there.

 Archives for the alt.sources newsgroup are at the following ftp sites:


 +o  ftp.sterling.com/usenet/alt.sources/

 +o  wuarchive.wustl.edu/usenet/alt.sources/articles

 +o  src.doc.ic.ac.uk/usenet/alt.sources/articles




 1155..  FFiinnaall WWoorrddss

 To sum up, persistence makes all the difference  (and a high
 frustration threshold certainly helps). As in all endeavors, learning
 from mistakes is critically important.  Each misstep, every failure
 contributes to the body of knowledge that will lead to mastery of tthhee
 aarrtt ooff bbuuiillddiinngg ssooffttwwaarree.



 1166..  RReeffeerreenncceess aanndd FFuurrtthheerr RReeaaddiinngg























 BORLAND C++ TOOLS AND UTILITIES GUIDE, Borland International, 1992,
 pp. 9-42.
 [One of the manuals distributed with Borland C++, ver. 3.1. Gives
 a fairly good intro to make syntax and concepts, using Borland's
 crippled implementation for DOS.]

 DuBois, Paul: SOFTWARE PORTABILITY WITH IMAKE, O'Reilly and Associates,
 1996, ISBN 1-56592-226-3.
 [This is reputed to be the definitive imake reference, though I did not
 have it available when writing this article.]

 Frisch, Aeleen: ESSENTIAL SYSTEM ADMINISTRATION (2nd ed.), O'Reilly and
 Associates, 1995, ISBN 1-56592-127-5.
 [This otherwise excellent sys admin handbook has only sketchy coverage
 of software building.]

 Hekman, Jessica: LINUX IN A NUTSHELL, O'Reilly and Associates, 1997, ISBN
 1-56592-167-4.
 [Good all-around reference to Linux commands.]

 Lehey, Greg: PORTING UNIX SOFTWARE, O'Reilly and Associates, 1995, ISBN
 1-56592-126-7.

 Mayer, Herbert G.: ADVANCED C PROGRAMMING ON THE IBM PC, Windcrest Books,
 1989, ISBN 0-8306-9363-7.
 [An idea-filled book for the intermediate to advanced C programmer.
 Superb coverage of algorithms, quirks of the language, and even
 amusements.  Unfortunately, out of print.]

 Mui, Linda and Valerie Quercia: X USER TOOLS, O'Reilly and Associates,
 1994, ISBN 1-56592-019-8, pp. 734-760.

 Oram, Andrew and Steve Talbott: MANAGING PROJECTS WITH MAKE, O'Reilly
 and Associates, 1991, ISBN 0-937175-90-0.

 Peek, Jerry and Tim O'Reilly and Mike Loukides: UNIX POWER TOOLS,
 O'Reilly and Associates / Random House, 1997, ISBN 1-56592-260-3.
 [A wonderful source of ideas, and tons of utilities you may end up
 building from the source code, using the methods discussed in
 this article.]

 Stallman, Richard M. and Roland McGrath: GNU MAKE, Free Software
 Foundation, 1995, ISBN 1-882114-78-7.
 [Required reading.]

 Waite, Mitchell, Stephen Prata, and Donald Martin: C PRIMER PLUS, Waite Group
 Press, ISBN 0-672-22090-3,.
 [Probably the best of the introductions to C programming.  Extensive
 coverage for a primer.  Newer editions now available.]

 Welsh, Matt and Lar Kaufman: RUNNING LINUX, O'Reilly and Associates,
 1996, ISBN 1-56592-151-8.
 [Still the best overall Linux reference, though lacking in depth
 in some areas.]


 The man pages for dpkg, gcc, gzip, imake, ldconfig, ldd, make, nm, patch,
 rpm, shar, strip, tar, termcap, terminfo, and xmkmf.


 The BZIP2 HOWTO, by David Fetter.

 The Glibc2 HOWTO, by Eric Green

 The LINUX ELF HOWTO, by Daniel Barlow.

 The RPM HOWTO, by Donnie Barnes.

 The StarOffice miniHOWTO, by Matthew Borowski.




 [These HOWTOs should be in the /usr/doc/HOWTO  or /usr/doc/HOWTO/mini
 directory on your system. Updated versions are available in text,
 HTML, and SGML format from the LDP site
 <http://metalab.unc.edu/LDP/HOWTO>, and usually from the respective
 authors' home sites.]



 1177..  CCrreeddiittss


 The author of this HOWTO would like to thank the following persons for
 their helpful suggestions, corrections, and encouragement.


 +o  R. Brock Lynn

 +o  Michael Jenner

 +o  Fabrizio Stefani

 Kudos also go to the fine people who have translated this HOWTO into
 Italian and Japanese.

 And, of course, thanks, praise, benedictions and hosannahs to Greg
 Hankins and Tim Bynum of the Linux Documentation Project
 <http://metalab.unc.edu/LDP/>, which has made all this possible.