Once it hits the fan, the only rational choice is to sweep it up, package it, and sell it as fertilizer. | |
anonymous |
This document tries to cover multiple platforms through conditional compilation. There is a configure.pl that determines the host type and sets up a config.sh containing environment variable definitions. There also are equivalent config.csh, config.h, config.mak, config.sed, and config.xml. The Makefile then uses individual sub-directories for each platform. The name of these directories (and some other platform specific values) is retrieved through environment variables. The directory structure is not without meaning.
src/ is for source code, i.e. text files written and maintained by humans.
pre/sparc-sunos5.7/ is directory src/ pre-processed with config.sed. In pre/ all program names are absolute. Magic numbers and platform specific constants are verbatim.
tmp/sparc-sunos5.7/ is the only place to hold binaries, i.e. executables and .o files.
out/sparc-sunos5.7/ is for the output of executables, hex dumps, disassembly listings, text processing.
The files in src/ are obfuscated with obscene amounts of variable references like ${TEVWH_ELF_BASE} or even ${TEVWH_PATH_LS}. I admit that using variables instead of plain program names makes shell scripts harder to read. But this is necessary to maintain a minimum level of reproducibility on SunOS. Anyway, directory pre/ makes that 10000 and /usr/xpg4/bin/ls, so you will probably never encounter this syntax nightmare. An almost complete list of used variables is given below.
Table 1. Variables prefixed with TEVWH_
Variable name | Value on this platform | Variable name | Value on this platform |
---|---|---|---|
AFLAGS | -I . -D _ASM | ARCH | sparc |
ASM | sparc_SunOS_att | ASM_COMMENT | ! |
ASM_FLAVOR | ASM_RETURN | (restore|unimp) | |
ASM_STYLE | att | BYTE_ORDER | M |
CFLAGS | -Wall -O1 -I . -I out/sparc-sunos5.7 -D NDEBUG | ELF_ADDR | Elf32_Addr |
ELF_ADDR_SIZE | 32 | ELF_ALIGN | 10000 |
ELF_BASE | 10000 | ELF_EHDR | Elf32_Ehdr |
ELF_MAGIC | 10001 | ELF_OFF | Elf32_Off |
ELF_PAGE_SIZE | 1000 | ELF_PHDR | Elf32_Phdr |
ELF_SHDR | Elf32_Shdr | HOSTTYPE | SunOS/sparc |
OS_CODE | sparc-sunos5.7 | OS_NAME | SunOS 5.7 |
OS_PKG_SYS | SunOS | OS_VERSION | 5.7 |
OUT | out/sparc-sunos5.7 | OUT_XML | out/sparc-sunos5.7/xml |
PRE | pre/sparc-sunos5.7 | PROC_EXE | /proc/self/object/a.out |
TMP | tmp/sparc-sunos5.7 | UNAME | SunOS |
Note that hexadecimal shell variables actually miss the leading 0x to simplify calculations with bc. These values are also available to C code through corresponding #define statements after #include <config.h>. Values are not quoted, but hexadecimal values are correctly prefixed by 0x.
Table 2. Variables prefixed with TEVWH_PATH_
Variable name | Value on this platform | Variable name | Value on this platform |
---|---|---|---|
BASH | /usr/bin/bash | BC | /usr/bin/bc |
CAT | /usr/bin/cat | CC | /usr/local/bin/gcc |
CHMOD | /usr/bin/chmod | CSH | /usr/bin/csh |
CUT | /usr/bin/cut | DD | /usr/bin/dd |
DISTID | /etc/release | DU | /usr/xpg4/bin/du |
DUMP | /usr/ccs/bin/dump | ECHO | /usr/bin/echo |
ELFDUMP | /usr/ccs/bin/elfdump | EXPAND | /usr/bin/expand |
FILE | /usr/bin/file | FIND | /usr/bin/find |
FMT | /usr/bin/fmt | GDB | /usr/local/bin/gdb |
GREP | /usr/xpg4/bin/grep | KILL | /usr/bin/kill |
LD | /usr/local/bin/ld | LDD | /usr/bin/ldd |
LS | /usr/xpg4/bin/ls | MAKE | /usr/xpg4/bin/make |
MAN | /usr/bin/man | MT | /usr/bin/mt |
NICE | /usr/xpg4/bin/nice | NM | /usr/xpg4/bin/nm |
OBJDUMP | /usr/local/bin/objdump | OD | /usr/xpg4/bin/od |
PERL | /usr/bin/perl | PKGCHK | /usr/sbin/pkgchk |
PKGINFO | /usr/bin/pkginfo | READELF | /usr/local/bin/readelf |
SED | /usr/xpg4/bin/sed | SH | /usr/xpg4/bin/sh |
SORT | /usr/xpg4/bin/sort | STRACE | /usr/bin/strace |
STRINGS | /usr/bin/strings | STRIP | /usr/local/bin/strip |
TAIL | /usr/xpg4/bin/tail | TEE | /usr/bin/tee |
TR | /usr/xpg4/bin/tr | TRUSS | /usr/bin/truss |
UNIQ | /usr/bin/uniq | WC | /usr/bin/wc |
XARGS | /usr/bin/xargs |
Command: src/packages/uname.sh
#!/bin/sh
uname -mprs
echo "[${HOSTTYPE}]"
echo "[${VENDOR}]"
echo "[${OSTYPE}]"
echo "[${MACHTYPE}]" |
Output: out/sparc-sunos5.7/packages/uname
SunOS 5.7 sun4m sparc
[sparc]
[]
[solaris2.7]
[sparc-sun-solaris2.7] |
While most Linux distributions ship with slightly modified kernels, no vendor has ever dared to mess with the values returned by uname(2). Instead the tradition of distribution dependent text files in directory /etc was established.
Command: pre/sparc-sunos5.7/packages/distid.sh
#!/usr/xpg4/bin/sh
# We need this script to copy the id-file into directory out/.
# I use many machines to test examples, but only one to render the document.
/usr/bin/cat /etc/release |
Output: out/sparc-sunos5.7/packages/distid
Solaris 7 s998s_SunServer_21al2b SPARC
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
Assembled 06 October 1998 |
One of the lesser known features of package management is self-reflection. How do we determine the package owning a file if we have the canonical path name?
The package format used by SunOS 5.7 is called "pkg Datastream (SVR4)" by a recent file(1). Relevant information is stored as a set of text files in directory /var/sadm. For each installed package there is a sub directory in /var/sadm/pkg that includes a description.
Source: pre/sparc-sunos5.7/packages/SunOS/du.sh
#!/usr/xpg4/bin/sh
/usr/bin/file /var/sadm/* | /usr/bin/expand -t 32
/usr/xpg4/bin/ls -l /var/sadm/install/contents
/usr/xpg4/bin/du -s /var/sadm/pkg /var/sadm/install |
Output: out/sparc-sunos5.7/packages/du
/var/sadm/README: English text
/var/sadm/install: directory
/var/sadm/install_data: directory
/var/sadm/patch: directory
/var/sadm/pkg: directory
/var/sadm/softinfo: directory
/var/sadm/system: directory
-rw-r--r-- 1 root other 2993078 Dec 4 19:22 /var/sadm/install/contents
79594 /var/sadm/pkg
5882 /var/sadm/install |
The first half of a query does a linear search trough text file /var/sadm/install/contents. The tricky part is to find the canonical name of a file. A lot of tools are provided in two different variations. The POSIX confirming ones are located in directory /usr/xpg4/bin/, as described by xpg4(5). The classic tools are installed in /usr/bin. But since /bin is a symbolic link to /usr/bin, a naive which(1) can give unexpected results.
Source: pre/sparc-sunos5.7/packages/SunOS/simple.sh
#!/usr/xpg4/bin/sh
query='/bin/sed /usr/bin/sed /usr/xpg4/bin/sed'
/usr/xpg4/bin/ls -li ${query}
/usr/sbin/pkgchk -l -p "${query}" |
Output: out/sparc-sunos5.7/packages/simple
279597 -r-xr-xr-x 1 bin bin 27368 Oct 6 1998 /bin/sed
279597 -r-xr-xr-x 1 bin bin 27368 Oct 6 1998 /usr/bin/sed
317464 -r-xr-xr-x 1 bin bin 28068 Sep 1 1998 /usr/xpg4/bin/sed
Pathname: /usr/bin/sed
Type: regular file
Expected mode: 0555
Expected owner: bin
Expected group: bin
Expected file size (bytes): 27368
Expected sum(1) of contents: 18227
Expected last modification: Oct 06 09:45:42 1998
Referenced by the following packages:
SUNWcsu
Current status: installed
Pathname: /usr/xpg4/bin/sed
Type: regular file
Expected mode: 0555
Expected owner: bin
Expected group: bin
Expected file size (bytes): 28068
Expected sum(1) of contents: 40692
Expected last modification: Sep 01 13:04:13 1998
Referenced by the following packages:
SUNWxcu4
Current status: installed
|
The second part of the query works on a single file, /var/sadm/pkg/*/pkginfo:
Source: pre/sparc-sunos5.7/packages/SunOS/version.sh
#!/usr/xpg4/bin/sh
pkg=$( /usr/sbin/pkgchk -l -p /usr/xpg4/bin/sed \
| /usr/xpg4/bin/grep -v '^[A-Z]' )
/usr/bin/pkginfo -x ${pkg} |
Output: out/sparc-sunos5.7/packages/SunOS/version
SUNWxcu4 XCU4 Utilities
(sparc) 11.7.0,REV=1998.09.01.04.16 |
Option -a of man returns all matching entries, not just the lowest section. This behavior is identical between platforms.
Command: pre/sparc-sunos5.7/packages/man-all/SunOS.sh
#!/usr/xpg4/bin/sh
/usr/bin/man -a -d kill \
| /usr/xpg4/bin/sed -ne 's/.*\<formatted = //p' |
Output: out/sparc-sunos5.7/packages/man-all
/usr/share/man/cat1/kill.1
/usr/share/man/cat2/kill.2 |
Requesting a specific section requires option -s section on SunOS, while Linux and FreeBSD prefer a plain section.
Command: pre/sparc-sunos5.7/packages/man-section/SunOS.sh
#!/usr/xpg4/bin/sh
/usr/bin/man -d -s 2 kill \
| /usr/xpg4/bin/sed -ne 's/.*\<formatted = //p' |
Output: out/sparc-sunos5.7/packages/man-section
/usr/share/man/cat2/kill.2 |
This chapter is not about checking the integrity of package files. See Intrusion detection systems for a general introduction.
SunOS uses checksums based on sum(1). pkgchk(1) lets you verify everything, complete packages or a list of files specified with option -i listfile. Diagnostics are written to stderr and no news is good news.
Command: pre/sparc-sunos5.7/packages/SunOS/verify.sh
#!/usr/xpg4/bin/sh
pkg=$( /usr/sbin/pkgchk -l -p /etc/profile \
| /usr/xpg4/bin/grep -v '^[A-Z]' )
/usr/bin/echo pkg=[${pkg}]
/usr/sbin/pkgchk ${pkg} 2>&1 | /usr/xpg4/bin/sed 11q
/usr/bin/echo status=$? |
Output: out/sparc-sunos5.7/packages/verify
pkg=[ SUNWcsr ]
ERROR: /etc/default/init
file size <219> expected <605> actual
file cksum <18231> expected <48341> actual
ERROR: /etc/device.tab
file size <1207> expected <1998> actual
file cksum <37074> expected <37523> actual
ERROR: /etc/devlink.tab
group name <sys> expected <other> actual
file size <4142> expected <4276> actual
file cksum <38129> expected <50918> actual
ERROR: /etc/dgroup.tab
status=0 |
Option -n is advertised as "Do not check volatile or editable files". With option -d package_file you can verify against the checksums included in a package file, e.g. on the installation CD.