Old version of filePro
Brian K. White
bw.aljex at gmail.com
Tue Dec 21 15:57:26 PST 2021
GUYS... I just discovered something awesome
There is a program called patchelf that can edit the library references
in an ELF executable.
One of the things it can do is edit the RPATH in an executable, and one
of the values you can put in RPATH is a magic value '$ORIGIN'.
RPATH is essentially the same as LD_LIBRARY_PATH, except it's built-in
to the executable. Normally you have to set that at compile-time, but
this util can edit the compiled executable after the fact. It makes the
executable look in the directory you say itself before asking the system
to provide the library.
$ORIGIN is a special value that means "the directory where this
executable is" and it means at run-time. So, if the executable has that
in RPATH, then all you have to do is put a copy of whatever library
files it needs in the directory along side the executable, and then you
never have to worry about it again.
SO, you can patch the rclerk and other fp executables this way, and just
stick any problem libs right in the fp directory with the executables
and forget about them forever after that.
If you re-arrange your system to put the fp binaries in some other
location, it still works. If you move everything to a new system, it
still works, as long as you just copy the entire fp directory together,
which you have to do anyway.
The process goes like this:
Install "patchelf"
debian & derivatives like ubuntu: "apt install patchelf"
redhat & derivatives like centos: "yum install patchelf"
Use "ldd" to list the dependencies of an executable, to find out what
library files we want to bundle:
bkw at fw:~$ cd /opt/fp/fp
bkw at fw:/opt/fp/fp$ ldd rclerk
linux-gate.so.1 (0xf7f6a000)
libtermcap.so.2 => /lib32/libtermcap.so.2 (0xf7f3a000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e35000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c38000)
/lib/ld-linux.so.2 (0xf7f6c000)
bkw at fw:/opt/fp/fp$
Ignore the linux-gate and ld-linux ones, they're special. One way to
recognize what makes them "special" or how you know to ignore them,
notice they don't point to a file, so there is nothing for you to copy
anyway. It IS actually possible with another tool to take this all a
step further and bundle not only the libraries but also the interpreter
or dynamic linker, and pack them all into a new single executable file
with everything built-in, but we don't need to go that far.
Another way to see what files you need is "readelf -d rclerk |grep NEEDED"
bkw at fw:/opt/fp/fp$ readelf -d rclerk |grep NEEDED
0x00000001 (NEEDED) Shared library: [libtermcap.so.2]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libc.so.6]
bkw at fw:/opt/fp/fp$
If you're doing this on a system where the fp binaries currently work,
then ldd will show not only what's needed but also where to find the
actual file to copy from your current system.
If you're doing this on a new system where the fp binaries don't work
yet, then you can get the files from centos or rhel 6.10 i686 rpm
packages like I showed below, and the secret is just knowing that for
the termcap one specifically, the centos 7 and later ones are broken so
get the one from centos 6.10, and, that it needs to be the i686 (32 bit)
one.
The other libraries still have working packages right up to current on
most systems, so they aren't really a problem. You could do this for all
3 library files shown here, but really you don't need to for libc and lbm.
In this case, that just leaves libtermcap as the only annoying problem
library that would be simpler if it were just built-in or at least bundled.
So now, just take libtermcap.so.2 from the ldd output and copy it into
the fp directory:
cp /usr/lib32/libtermcap.so.2 .
And finally use patchelf to patch the executable, so that the executable
looks for libraries in it's own directory first from now on.
patchelf --set-rpath '$ORIGIN' rclerk
Now the point of all this: I'll remove libtermcap from the system
directory and rclerk will still work because now it will find the lib in
the fp directory:
# remove libtermcap from the system into the fp dir
bkw at fw:~$ sudo mv -f /lib32/libtermcap.so.2 /opt/fp/fp
# show that rclerk is now broken
bkw at fw:~$ ldd rclerk
linux-gate.so.1 (0xf7f9b000)
libtermcap.so.2 => not found
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e6a000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c6d000)
/lib/ld-linux.so.2 (0xf7f9d000)
# patch rclerk
# $ORIGIN is single-quoted because we need the literal exact string
$ORIGIN, it's not an environment variable.
bkw at fw:~$ sudo patchelf --set-rpath '$ORIGIN' /opt/fp/fp/rclerk
# show that rclerk is now fixed
bkw at fw:~$ ldd /opt/fp/fp/rclerk
linux-gate.so.1 (0xf7f0d000)
libtermcap.so.2 => /opt/fp/fp/libtermcap.so.2 (0xf7f03000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7dd8000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7bdb000)
/lib/ld-linux.so.2 (0xf7f0f000)
bkw at fw:~$
So now rclerk is finding libtermcap again, only now finding it in the fp
directory. Which is fine, it means that right now a cron job could run
rclerk directly without a script to set LD_LIBRARY_PATH and it would
work, the executable is searching in the right spot all on it's own.
But the real point of all this is this:
# move the entire fp tree somewhere else
bkw at fw:~$ sudo mv /opt/fp/ /opt/fp_moved/
# see that rclerk is still fixed, even though the library file moved,
because the executable is looking in a path relative to itself instead
of an absolute path:
bkw at fw:~$ ldd /opt/fp_moved/fp/rclerk
linux-gate.so.1 (0xf7eef000)
libtermcap.so.2 => /opt/fp_moved/fp/libtermcap.so.2 (0xf7ee5000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7dba000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7bbd000)
/lib/ld-linux.so.2 (0xf7ef1000)
bkw at fw:~$
And this no longer needs any setup in the system. No /usr/lib32, no
ldconfig. Just copy your fp dir somewhere on any new system and resume
using it.
You have to do the same patchelf command for every fp executable. A
little tedious but it's a one-time-for-life thing.
It's slightly more work than installing the library file like below, but
the point is now the file can live in the fp directory, get copied along
with everything else, and everything keeps working wherever you move it
because now it's self-contained. You don't have to remember to set it up
on a new system.
It's not necessarily better than below, just another option.
--
bkw
On 12/20/21 4:44 AM, Brian K. White wrote:
> I don't even bother trying to find a proper package any more. Just get
> compat-libtermcap-2.0.8-49.el6.i686.rpm from any Centos 6.10 repo,
> Doesn't matter if your current distro uses rpm packages, and just use
> the file from that regardless what the current system is.
>
> For reference, I just did this on an ubuntu 20.10 system:
>
> # First, see we have a broken rclerk (see the not found message):
>
> bkw at fw:~/Documents/centos_termcap_32$ ldd /opt/fp/fp/rclerk
> linux-gate.so.1 (0xf7ef5000)
> libtermcap.so.2 => not found
> libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7dc4000)
> libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7bc7000)
> /lib/ld-linux.so.2 (0xf7ef7000)
> bkw at fw:~/Documents/centos_termcap_32$
>
> # Download a centos 6.10 i686 rpm containing the file we need:
>
> bkw at fw:~/Documents/centos_termcap_32$ wget
> https://mirror.chpc.utah.edu/pub/vault.centos.org/6.10/os/i386/Packages/compat-libtermcap-2.0.8-49.el6.i686.rpm
> --2021-12-20 04:00:26--
> https://mirror.chpc.utah.edu/pub/vault.centos.org/6.10/os/i386/Packages/compat-libtermcap-2.0.8-49.el6.i686.rpm
> Resolving mirror.chpc.utah.edu (mirror.chpc.utah.edu)...
> 204.99.128.20, 2001:1948:417:5::20
> Connecting to mirror.chpc.utah.edu
> (mirror.chpc.utah.edu)|204.99.128.20|:443... connected.
> HTTP request sent, awaiting response... 200 OK
> Length: 15840 (15K) [application/x-rpm]
> Saving to: ‘compat-libtermcap-2.0.8-49.el6.i686.rpm’
>
> compat-libtermcap-2.0.8-49.el6.i686.rpm
> 100%[=====================================================================================================>]
> 15.47K --.-KB/s in 0.08s
>
> 2021-12-20 04:00:26 (202 KB/s) -
> ‘compat-libtermcap-2.0.8-49.el6.i686.rpm’ saved [15840/15840]
>
>
> # Extract the contents of the rpm as though it were a tar, using a
> handy command called "unar"
>
> bkw at fw:~/Documents/centos_termcap_32$ unar
> compat-libtermcap-2.0.8-49.el6.i686.rpm
> compat-libtermcap-2.0.8-49.el6.i686.rpm: XZ in RPM
> compat-libtermcap.cpio... OK.
> Successfully extracted to "compat-libtermcap.cpio".
>
> # Use "unar" again to extract the .cpipo
>
> bkw at fw:~/Documents/centos_termcap_32$ unar compat-libtermcap.cpio
> compat-libtermcap.cpio: Cpio
> ./lib/libtermcap.so.2 (link)... OK.
> ./lib/libtermcap.so.2.0.8 (12308 B)... OK.
> Successfully extracted to "./lib".
>
> # Now copy and rename libtermcap.so.2.0.8 to libtermcap.so.2 into some
> lib dir, in my case /usr/lib32 but yours could be different, you can
> see where all the lib dirs are in the *.conf files in /etc/ld.so.conf.d
>
> bkw at fw:~/Documents/centos_termcap_32$ sudo cp -v
> lib/libtermcap.so.2.0.8 /usr/lib32/libtermcap.so.2
> [sudo] password for bkw:
> 'lib/libtermcap.so.2.0.8' -> '/usr/lib32/libtermcap.so.2'
>
> # Now run "ldconfig"
>
> bkw at fw:~/Documents/centos_termcap_32$ sudo ldconfig
>
> # Now we have a working rclerk
>
> bkw at fw:~/Documents/centos_termcap_32$ ldd /opt/fp/fp/rclerk
> linux-gate.so.1 (0xf7f47000)
> libtermcap.so.2 => /lib32/libtermcap.so.2 (0xf7f17000)
> libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e12000)
> libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c15000)
> /lib/ld-linux.so.2 (0xf7f49000)
> bkw at fw:~/Documents/centos_termcap_32$
>
>
> Annoying but at least you can do it any time on any system.
>
> If it wasn't for cron jobs or web apps that may sometimes want to run
> clerk or report without starting from "p" or an environment
> start-script, I wouldn't even bother integrating the library in the
> system like this. I'd just stick it right in the fp directory and put
> "export LD_LIBRARY_PATH=${PFPROG}/fp" into the start script, or into p
> right before the runmenu. Then the library is just part of the filepro
> install and goes wherever it goes from now on.
>
More information about the Filepro-list
mailing list