diff options
author | Jeff Licquia <licquia@debian.org> | 2011-02-20 08:14:47 -0800 |
---|---|---|
committer | Jeff Licquia <licquia@debian.org> | 2011-02-20 08:14:47 -0800 |
commit | ec4609a58eea4f3a1be280f5eebbb98374b8db65 (patch) | |
tree | 565c4ca1ea0ae842bbdd6ec9905f086b2847a0ae |
Import epm_4.2.orig.tar.gz
[dgit import orig epm_4.2.orig.tar.gz]
-rw-r--r-- | CHANGES | 672 | ||||
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | INSTALL | 48 | ||||
-rw-r--r-- | Makefile.in | 421 | ||||
-rw-r--r-- | README | 103 | ||||
-rw-r--r-- | aix.c | 950 | ||||
-rw-r--r-- | bsd.c | 464 | ||||
-rw-r--r-- | config.h.in | 140 | ||||
-rwxr-xr-x | configure | 7431 | ||||
-rw-r--r-- | configure.in | 393 | ||||
-rw-r--r-- | deb.c | 602 | ||||
-rw-r--r-- | default.xpm | 163 | ||||
-rw-r--r-- | dist.c | 2398 | ||||
-rw-r--r-- | doc/1-intro.html | 323 | ||||
-rw-r--r-- | doc/2-building.html | 382 | ||||
-rw-r--r-- | doc/3-packaging.html | 367 | ||||
-rw-r--r-- | doc/4-advanced.html | 615 | ||||
-rw-r--r-- | doc/5-examples.html | 738 | ||||
-rw-r--r-- | doc/Makefile.in | 65 | ||||
-rw-r--r-- | doc/a-license.html | 318 | ||||
-rw-r--r-- | doc/b-manpages.html | 19 | ||||
-rw-r--r-- | doc/c-reference.html | 455 | ||||
-rw-r--r-- | doc/d-relnotes.html | 102 | ||||
-rw-r--r-- | doc/epm-book.book | 12 | ||||
-rw-r--r-- | doc/epm-book.html | 2930 | ||||
-rw-r--r-- | doc/epm.list.man | 372 | ||||
-rw-r--r-- | doc/epm.man | 192 | ||||
-rw-r--r-- | doc/epminstall.man | 97 | ||||
-rw-r--r-- | doc/epmlogo.gif | bin | 0 -> 21303 bytes | |||
-rw-r--r-- | doc/epmlogo.tif | bin | 0 -> 37550 bytes | |||
-rw-r--r-- | doc/gradient.gif | bin | 0 -> 825 bytes | |||
-rw-r--r-- | doc/mantohtml.c | 697 | ||||
-rw-r--r-- | doc/mkepmlist.man | 74 | ||||
-rw-r--r-- | doc/preface.html | 214 | ||||
-rw-r--r-- | doc/setup.man | 59 | ||||
-rw-r--r-- | doc/setup.png | bin | 0 -> 46977 bytes | |||
-rw-r--r-- | doc/setup.types.man | 75 | ||||
-rw-r--r-- | doc/title.html | 76 | ||||
-rw-r--r-- | epm.c | 727 | ||||
-rw-r--r-- | epm.h | 349 | ||||
-rw-r--r-- | epm.list.in | 92 | ||||
-rw-r--r-- | epminstall.c | 415 | ||||
-rw-r--r-- | epmsetup.gif | bin | 0 -> 15317 bytes | |||
-rw-r--r-- | epmstring.h | 90 | ||||
-rw-r--r-- | file.c | 445 | ||||
-rw-r--r-- | gui-common.cxx | 348 | ||||
-rw-r--r-- | gui-common.h | 107 | ||||
-rw-r--r-- | inst.c | 706 | ||||
-rw-r--r-- | macosx/setup.icns | bin | 0 -> 50941 bytes | |||
-rw-r--r-- | macosx/setup.info | 1 | ||||
-rw-r--r-- | macosx/setup.xcf.gz | bin | 0 -> 17969 bytes | |||
-rw-r--r-- | macosx/setup128.png | bin | 0 -> 13331 bytes | |||
-rw-r--r-- | macosx/setup16.png | bin | 0 -> 656 bytes | |||
-rw-r--r-- | macosx/setup32.png | bin | 0 -> 1704 bytes | |||
-rw-r--r-- | macosx/setup48.png | bin | 0 -> 3330 bytes | |||
-rw-r--r-- | macosx/uninst.icns | bin | 0 -> 55620 bytes | |||
-rw-r--r-- | macosx/uninst.info | 1 | ||||
-rw-r--r-- | macosx/uninst.xcf.gz | bin | 0 -> 33090 bytes | |||
-rw-r--r-- | macosx/uninst128.png | bin | 0 -> 16674 bytes | |||
-rw-r--r-- | macosx/uninst16.png | bin | 0 -> 858 bytes | |||
-rw-r--r-- | macosx/uninst32.png | bin | 0 -> 2250 bytes | |||
-rw-r--r-- | macosx/uninst48.png | bin | 0 -> 4279 bytes | |||
-rw-r--r-- | mkepmlist.c | 625 | ||||
-rw-r--r-- | osx.c | 870 | ||||
-rw-r--r-- | pkg.c | 595 | ||||
-rw-r--r-- | portable.c | 2965 | ||||
-rw-r--r-- | qprintf.c | 218 | ||||
-rw-r--r-- | rpm.c | 956 | ||||
-rw-r--r-- | run.c | 182 | ||||
-rw-r--r-- | setld.c | 469 | ||||
-rw-r--r-- | setup.cxx | 553 | ||||
-rw-r--r-- | setup.fl | 199 | ||||
-rw-r--r-- | setup.h | 41 | ||||
-rw-r--r-- | setup2.cxx | 1220 | ||||
-rw-r--r-- | slackware.c | 334 | ||||
-rw-r--r-- | snprintf.c | 276 | ||||
-rw-r--r-- | string.c | 203 | ||||
-rw-r--r-- | support.c | 110 | ||||
-rw-r--r-- | swinstall.c | 753 | ||||
-rw-r--r-- | tar.c | 562 | ||||
-rw-r--r-- | uninst.cxx | 444 | ||||
-rw-r--r-- | uninst.fl | 123 | ||||
-rw-r--r-- | uninst.h | 35 | ||||
-rw-r--r-- | uninst2.cxx | 741 |
84 files changed, 38062 insertions, 0 deletions
@@ -0,0 +1,672 @@ +CHANGES - ESP Package Manager (EPM) 4.2 +--------------------------------------- + +CHANGES IN EPM 4.2 + + - EPM now supports a %arch conditional directive (STR #27) + - EPM now uses hard links whenever possible instead of copying files for + distribution (STR #21) + - EPM no longer puts files in /export in the root file set for AIX + packages (STR #15) + - EPM did not work with newer versions of RPM (STR #23, STR #25) + - EPM did not clean up temporary files from Solaris packages (STR #20) + - Building Solaris gzip'd packages failed if the pkg.gz file already + existed (STR #16) + - Fixed handling of %preremove and %postremove for AIX packages + (STR #22) + - Fixed directory permissions in HP-UX packages (STR #24) + - Removed unnecessary quoting of "!" in filenames (STR #26) + - Added support for signed RPM packages (STR #19) + - Added support for inclusion of format-specific packaging files and + directives via a %literal directive (STR #5) + - *BSD init scripts were not installed properly. + - EPM now displays a warning message when a variable is undefined + (STR #10) + - *BSD dependencies on versioned packages are now specified correctly + (STR #4) + - EPM now uses /usr/sbin/pkg_create on FreeBSD (STR #2) + - FreeBSD packages are now created with a .tbz extension (STR #1) + - FreeBSD packages incorrectly assumed that chown was installed in /bin + (STR #3) + - Added support for an "lsb" package format which uses RPM with the LSB + dependencies (STR #7) + - The configure script now supports a --with-archflags and no longer + automatically builds universal binaries on Mac OS X. + - The epm program now automatically detects when the setup GUI is not + available, displays a warning message, and then creates a non-GUI + package. + - RPM packages did not map %replaces to Obsoletes: + + +CHANGES IN EPM 4.1 + + - Mac OS X portable packages did not create a correct + Uninstall application. + - The temporary package files for portable packages are + now removed after creation of the .tar.gz file unless + the -k (keep files) option is used. + - The RPM summary string for subpackages did not contain + the first line of the package description as for other + package formats. + - The setup and uninst GUIs now support installing and + removing RPM packages. + - The setup GUI now confirms acceptance of all licenses + prior to installing the first package. + - Subpackages are no longer automatically dependent on + the main package. + - Multi-line descriptions were not embedded properly into + portable package install/patch/remove scripts. + - Updated the setup and uninstall GUIs for a nicer + look-n-feel. + - Mac OS X portable packages now show the proper name, + version, and copyright for the packaged software + instead of the EPM version and copyright... + - Fixed a problem with creation of Mac OS X metapackages + with the latest Xcode. + - EPM now removes the individual .rpm and .deb files when + creating a package with subpackages unless the -k + option (keep files) is used. + - EPM now only warns about package names containing + characters other than letters and numbers. + - EPM now generates disk images as well as a .tar.gz + file when creating portable packages on Mac OS X. + + +CHANGES IN EPM 4.0 + + - New subpackage support for creating multiple dependent + packages or a combined package with selectable + subpackages, depending on the package format. + - Added support for compressing the package files in + portable packages (reduces disk space requirements on + platforms that provide gzip...) + - Added support for custom platform names via the new + "-m name" option. + - Added support for non-numeric %release values. + - Added new --depend option to list all of the source + files that a package depends on. + - The setup GUI now sets the EPM_INSTALL_TYPE environment + variable to the value of the selected TYPE line in the + setup.types file. + - Fixed NetBSD and OpenBSD packaging support - no longer + use FreeBSD-specific extensions to pkg_create on those + variants. + - Fixed PowerPC platform support for RPM and Debian + packages. + - Many fixes to AIX package support. + - Tru64 packages with init scripts now work when + installing for the first time. + - RPM file dependencies should now work properly. + - Portable product names containing spaces will now + display properly. + + +CHANGES IN EPM 3.7.1 + + - Solaris packages were not created when the output + directory was absolute. + - EPM no longer tries to strip empty files. + - Solaris 7 and higher no longer have the "2." prefix in + the version number. + - The setup and uninst GUIs now support GIF setup images + (setup.gif) as well as XPM images (setup.xpm) + - Debian packages now properly install init scripts. + - MacOS X packages can now be created when using the + new Xcode developer tools. + - Packages created on MacOS X now use the system name + "macosx" and the MacOS X version number. The old + "darwin" name is still accepted as a synonym. + - EPM now supports version numbers that do not start + with a number (HP-UX workaround for OS + dependencies...) + - EPM now issues an error message if you have identical + destination files that don't match up. + - HP-UX packages now use the %readme file for the readme + info in a package, and the %license file for the + copyright info in a package. + - Added %preremove support for AIX packages and fixed + some AIX packaging issues with patch from David Maltz. + + +CHANGES IN EPM 3.7 + + - Fixed init script support for Tru64 packages. + - AIX output now correctly generates the inventory file + for files in /usr and /opt. + - The Slackware packaging code swapped the output + directory and product name when generating the + post-install script. + - RPM dependencies of the form "%requires package >= + version" are now correctly written in the spec file. + - AIX output now correctly lists file sizes by directory + and handles /opt properly. + - RPM output now correctly handles installing, + upgrading, and removing init scripts. + - RPM output did not work with filenames that contained + a dollar sign ($). + - Added Slackware packager support based upon a patch + contributed by Alec Thomas. + - The file copy code reported write errors for the + source filename and not the (correct) destination + filename. + - Fixed the handling of absolute output directories when + generating RPM packages. + - The configure script did not support the OPTIM + environment variable for custom optimization settings. + - Portable packages updated the permissions of + configuration files before they were copied. + - Portable installations did not remove empty + installation directories when the remove script was + run. + - Portable patch installation did not correctly + determine when root or /usr files were present in the + patch. + - OSX packages incorrectly looked in /System/Library for + the init scripts instead of /Library. + - RPM building did not work properly when --output-dir + was specified using an absolute path. + - Made cosmetic changes to the setup/uninstall GUIs. + - The setup GUI did not support software patches. + - The documentation incorrectly specified runlevels() + instead of runlevel(). + - The portable distributions incorrectly used + /usr/local/src/rc.d as a fallback location for init + scripts. + + +CHANGES IN EPM 3.6 + + - Added a GUI uninstall program to be distributed with + portable distributions with a setup image. + - MacOS X portable packages now support graphical setup + and uninstall using the Apple authorization API. + - Debian packages did not include the (required) + trailing period when running the update-rc.d script. + - BSD packages now create directories using postinstall + commands instead of listing them directly. This + should eliminate errors from the FreeBSD pkg_delete + command. + - File dependencies were incorrectly specified in RPM + spec files. + - IRIX portable distributions didn't write the chkconfig + commands properly. + - The mkepmlist utility didn't support files as well as + directories. + - EPM didn't do variable expansion of imported files + ("<foo.txt") or in-line data ("<<FOO") + - Now build gzip'd depot files as well as the tar.gz + files when creating HP-UX software packages. + - Now correctly use --libdir setting to locate the setup + GUI. + - Now use rpmbuild command, if available, to build RPM + files since newer versions of RPM may not map the + "-bb" option to build a package. + - Now set the RPMDIR environment variable when building + with older versions of RPM that don't understand the + "topdir_" variable. + - Now handle dependencies of the form "package >= + version" in Debian packages. + - Portable distributions that didn't have any files in + /usr or in / would look for a non-existent .sw or .ss + file. + - EPM's sample list file didn't include the man pages + for setup or setup.types, and installed the epm list + file format man page in the wrong directories. + - EPM would quote the ":" character in filenames but + didn't need to. + - EPM tried to move the wrong RPM file on non-intel + systems. + + +CHANGES IN EPM 3.5.1 + + - OSX packages did not set the "install as root" package + type, so package installation usually failed. + - OSX packages installed init scripts in + /System/Library/StartupItems, but non-Apple packages + should be installed in /Library/StartupItems. + - Added support for "requires(foo)", "uses(foo)", + "provides(foo)", and "order(foo)" as options for init + scripts. These options are currently only used when + creating OSX packages. + + +CHANGES IN EPM 3.5 + + - Added support for MacOS X package generation. + - No longer need/use RPMDIR when building RPMs, just + set the "topdir_" variable in the spec file. + - The portable removal scripts didn't correctly write + the list of init scripts to remove. + - Added a new --output-dir option contributed by + Geoffrey Wossum. + - Not all implementations of the "id" command support + the "-u" option, so EPM now looks at the default + output. + - RPM dependencies with a single version number didn't + get written to the spec file properly. + - Added support for file options - nostrip(), + runlevel(12345), start(nn), and stop(nn). + - Filenames can now contain spaces, either by putting + the full name in quotes ("file with spaces") or using + the backslash character (file\ with\ spaces). + - The mkepmlist utility didn't handle symlinks properly. + - BSD packages needed to list the directories to remove + separately and in reverse order. + + +CHANGES IN EPM 3.4 + + - No longer install init scripts in run levels 2 and 5 + under Solaris, which runs all init scripts in each run + level. + - The tar files produced by EPM didn't conform to the + POSIX 1003.1 spec. EPM now puts the POSIX version + number (00) and supports "long" filenames up to + 255 characters in length. + - AIX packages did not use the correct path for files + placed in the root partition. + - Now install init scripts for *BSD in + /usr/local/etc/rc.d. + - Portable installation scripts now issue chown and + chgrp commands for all installed files that are not + owned by user root. + - No longer use or pad empty tar files, which saves 5k + of disk space per distribution. + + +CHANGES IN EPM 3.3 + + - UnixWare 7 needs the absolute path when transferring + an AT&T package directory to a .pkg file. + - Now use the "id" command (POSIX) instead of "whoami" + (BSD) to check that the installing user is root. + - Various fixes for OpenServer. + - Now use the "-ln" option when checking for the size + of the distribution files in portable distributions. + - New C implementation of mkepmlist, based on a + contribution from Andreas Voegele. + - The portable install and patch scripts now change the + permissions of the installed "remove" script to 544. + - The wildcard character * did not match 0 characters if + the pattern and the filename string differed only by + the trailing * (e.g. "Courier" and "Courier*"). + - IRIX pre/postremove scripts are now copied after + installation so that they can be executed when + removing the inst/tardist package. + - HP-UX postinstall/preremove scripts would execute init + scripts from /sbin/init.d/sbin/init.d. + - The copyright string wasn't being quoted in portable + installation scripts. + - EPM now checks to see if an executable file is a shell + script before running the "strip" command. + + +CHANGES IN EPM 3.2.1 + + - The check for Darwin (MacOS X) in the portable + installation scripts was using "==" instead of just + "=". + + +CHANGES IN EPM 3.2 + + - Added "SHELL=/bin/sh" line to portable installation, + patch, and remove scripts in case the root shell is + not /bin/sh or a compatible shell. + - The epminstall utility didn't support the EPMLIST + environment variable as documented. + - The "native" distribution format is now "deb" if + the "dpkg" command is installed in /usr/bin. + - Debian packages did not use the release number in + the Version: keyword. + - Changed the portable installation script support + for init scripts to look for scripts in both rc2.d + and rc3.d, and to check for the existence of all + rc directories before installing into them. + - Changed the portable installation script to prepend + /bin, /usr/bin, and /usr/ucb to the beginning of the + PATH variable so the "tar", "rm", and "mv" commands + can be found in whatever directory the local system + uses. + - AIX packaging now works. + - Added support for the Darwin (MacOS X) tar command + in portable packages (sudo ./foo.install :) + - IRIX inst packages incorrectly had the postinstall commands + in the preinstall and removal scripts. + - The setup GUI now requires FLTK 1.1.x. + + +CHANGES IN EPM 3.1 + + - Added support for "<<end ... end" and "<filename" to + insert descriptions and commands in-line and from a + file. + - Added new --software-dir option which specifies the + location of the EPM software directory (default + /etc/software). + - Added new %if, %ifdef, %elseif, %elseifdef, %else, and + %endif directives for list files (addition contributed + by J. Nordell.) + - The GUI setup program left the "Next" button enabled + after the license check. + - Fixed the dependency strings created for HP-UX + swinstall (fix contributed by R. Begg.) + - Wasn't installing the man pages in section 5. + - When generating Debian packages, the DEBIAN directory + might not have the correct permissions due to a + restrictive umask. EPM now forces the correct + permissions for the package archive. + - HP-UX swinstall packages now use the prerequisites + rule instead of corequisites to ensure that the + %requires dependency is enforced. + - Dependencies for Debian packages are now listed on a + single line per type rather than one line per + dependency. + - EPM now detects RPM 4.0.3, which (mysteriously) now + uses "--target arch" instead of "--target=arch". + + +CHANGES IN EPM 3.0 + + - Added new documentation. + - Added new "-a arch" option to support specific + architectures (e.g. i586, i686, ultrasparc, etc.) + - Added support for the *BSD package format using + pkg_create. + - Added support for the AIX package format using + the backup program. + - Added new epminstall utility to build list files + from "make install" targets. + - Added snprintf/vsnprintf functions for systems that + don't provide them, and use snprintf and vsnprintf + for all formatted strings that aren't just numbers. + - Added new run_command() function to replace use of + system() function. + - Added new %provides directive. + - Revamped the setup GUI, including support for + installation types in the setup GUI, so that you can + select groups of products or choose a custom + installation. + - The mkepmlist utility had a bad regular expression + that thought that any argument (directory names, etc.) + with a dash ("-") in it was an unsupported option. + - Fixed a bug in the removal script: config files were + removed by the remove script... + - Changed the config file install logic to copy the new + config file (instead of moving it), so that an + unchanged config file can be detected and removed. + This provides the best of both worlds: unchanged + config files are update automatically by an + upgrade/install, while changed ones are preserved. + + +CHANGES IN EPM 2.8 + + - The line breaking code did not include an extra + space, so filenames in the portable install/patch/ + remove scripts would be joined instead of separated. + - The setup GUI did not allow the user to toggle a + software product for distribution if the product was + selected (nav box around it). + - The mkepmlist program didn't get the permissions of + each file (just the parent directory.) + - The portable installation scripts used the -L or -h + option to test for symlinks with the test command. The + choice of option was based on the build platform, + making the script non-portable. Now use -h exclusively + since it is supported on all UNIX's we have access to, + even with GNU test even though it isn't documented... + + +CHANGES IN EPM 2.7 + + - Fixed a bug in the configuration script with the + --with-fltk-includes option. + - Tru64 UNIX distributions now use the name "tru64" + instead of "dunix". "dunix" is still supported + in list files for compatibility with old list files. + - Added support for portable scripts under AIX. + - Fixed the space checking code in portable installation + scripts. + - Now break up long lines in the portable install/patch/ + remove scripts. + + +CHANGES IN EPM 2.6 + + - Changed the automatic version number generation code to + properly handle patch, beta, and pre releases. + - Added support for release numbers in RPM files. + - Added support for version number ranges in dependencies, + either as "low-version high-version", "< version", or + "> version". + - Eliminated some GCC warnings about using a char to + index into an array. + - Added a disk space check to the portable installation + scripts. + - Added a new mkepmlist utility, based on a Perl script + by Christian Lademann. + - Added a "keep files" option (-k) to epm to keep the + intermediate (spec, etc.) files around after building + the binary distribution. + - Added support for Tru64 UNIX software packages (setld). + - Patch distributions were incorrectly backing up the + original files, causing the original backup to be lost. + - Pre/post install/remove scripts were not using the + right filename for Solaris PKG distributions. + + +CHANGES IN EPM 2.5 + + - Added support for pre-install, post-install, pre-patch, + post-patch, pre-remove, and post-remove commands. + - There was no way to use a literal $ in scripts or in + filenames. Use $$ to include a single $. + - The config and license file support for AT&T software + packages did not check to see if the source file had + an absolute path. This would produce an invalid + prototype file. + - The RPM --target option was not being called with an + equal sign, which caused problems with RPM 4.0. + - Updated the Debian packager to use the prerm and postrm + script names to match reality. + - Updated the Debian packager to support the Replaces + dependency. + - Updated the portable and RPM distributions to check + for the new SuSE 7.1 init.d directories. + - RPM distributions now use %config(noreplace) for + config files, to duplicate the behavior that is + expected. + - The portable scripts now use the autoconf echo test to + determine the proper options for echo (-n or \c), + rather then hardcoding this based on the build system. + + +CHANGES IN EPM 2.4 + + - The [] wildcard matching did not skip over the + character that was matched. This prevented matches in + most cases... + + +CHANGES IN EPM 2.3 + + - Fix for an incredibly stupid bug in the portable + distribution code - was using ! instead of ~ to mask + off the write permission bits in the distribution + archive. + - Now use getpwuid() instead of getlogin() to get the + username of the packager. + - The RPM distributions now use the same init.d script + logic as portable distributions. This should make them + portable to all known Linux distributions as well as + avoid a *very* nasty installer bug in RedHat 7.0. + - The HP-UX swinstall code did not properly handle + directories or config files. + - The [] wildcard matching rule did not accept ranges + (e.g. "[a-z]", "[0-9]", etc.) + - Added VPATH support and distribution targets to + Makefile. + - Added support for defining variables in list files; + the format is "$name=value". + - The variable expansion code didn't check for ${name}. + + +CHANGES IN EPM 2.2 + + - New HTML documentation files. + - Updated the BuildRoot directive in RPM spec files to + be an absolute path; RedHat 6.2's version of RPM adds + a leading slash otherwise. + - IRIX defaults to run level 2... + - The setup GUI now displays an error message if run by + a non-root user. + - The setup GUI now provides "Install All" and "Install + None" buttons in the software selection pane. + - Added a "native" distribution format to select the + native format for a particular OS (Linux defaults to + RPM format...) + - The tar file generation code now always appends at + least 2 zeroed blocks to the end of the archive. This + eliminates error messages from Solaris tar and seems + to be compatible with all other tar programs. + - Added the SuSE RPM directory to the standard search + path. + - Added support for a new %packager directive. + - The strip command used was redirecting stderr before + redirecting stdout. + - The portable distributions now set the umask to avoid + problems with buggy tar programs and Linux + distributions. + - Added command-line option to specify the location of + the setup program. + - Added support for wildcards in source filenames. + - The OS version number is now truncated to only contain + the major and minor release numbers. + + +CHANGES IN EPM 2.1 + + - Moved setup program to /usr/lib/epm ($prefix/lib/epm) + to avoid name clash with RedHat setup program. + - Added Debian distribution files from Jeff Licquia. + - Configure script changes for GCC 2.95.x and Solaris. + - Portability fixes. + - Now look for RPMS in different "standard" locations + after building them; the RPMDIR environment variable + can be used to override the default locations. + - The sample project list file (epm.list) was missing + from the 2.0 distribution. + - Now check for write permission in /usr by writing a + test file (/usr/.writetest); this should make diskless + client installations more reliable. + - Added support for variables on the command line + (name=value); insert into project filenames using + $name. + - Variable expansion is now done on all lines and fields. + This allows variables to be used in scripts and in the + permissions field, for example. + - Now only specify run levels 0 and 3 for init scripts + (0, 3, and 5 for Linux.) + - Now support init scripts in /sbin/init.d and + /sbin/init.d/rcN.d (SuSE.) + - RPM distributions should now work OK for non-Red Hat + based systems, in particular for init scripts. + - PKG distributions are now also generated in the + "package stream" format as well as the directory and + tar.gz file formats. + + +CHANGES IN EPM 2.0 + + - New "-f" option to generate vendor-specific software + distributions. Now support AT&T, Debian, HP-UX, IRIX, + and Red Hat software distributions. + - New "-s" option to include the ESP Software Wizard (GUI) + with portable distributions. + - The "-t" option (test) is no longer supported. + - New "-v" option to control the amount of information + that is reported. + - New graphical setup program for portable distributions. + - New "description" directive. + - New "format" directive. + - New "include" directive. + - New "replaces" directive. + - Portable distributions should now be more portable. + + +CHANGES IN EPM 1.7 + + - The %requires and %incompat directives now support + specification of files as well as products. + - The init script installation code now creates a link in the + init.d subdirectory to avoid frustrating well-trained + fingers. + - The progress messages for shared and non-shared software were + the same. + + +CHANGES IN EPM 1.6 + + - Installation archives were missing the ".ss" and ".pss" + files that were added to support diskless installations. + - The scripts didn't handle removing distributions that + had no non-shared components. + - The scripts didn't return a non-zero exit status if the + user did not agree with the license or want to install. + + +CHANGES IN EPM 1.5 + + - Now support diskless installations; all files destined for + /usr are put in a separate archive and are installed (or + removed) only if /usr is read+write. + +CHANGES IN EPM 1.4 + + - Now map group "sys" to "system" for Digital UNIX and "root" for + Linux. + - The initialization script installation now checks for the presence + of run levels 4 and 5. + + +CHANGES IN EPM 1.3 + + - Now use the "p" option to tar to ensure that file permissions + are created properly. This is normally the default for the + super-user, but not under Digital UNIX! + - Initialization scripts are now linked to run levels 0, 2, 3, 4, + and 5. + + +CHANGES IN EPM 1.2 + + - Patch distributions were not correctly named. + - Added new "initialization script" file types "i" and "I". The + new file types place the scripts in /etc/software/init.d and + make links to the appropriate system-specific rc.d + directories and run the scripts to start and stop things + accordingly. + + +CHANGES IN EPM 1.1 + + - The "whoami" command isn't always in the user's path, so + scripts now use a hard-coded path (setup by the configure + script) to the program. + - Added a check for IRIX64 (64-bit kernel instead of n32.) + - The %system directive now supports release numbers, e.g. + "irix-6.5". + - The %system directive now supports "!" (not) operator so you + can do things like "%system irix !irix-6.5" to select any + IRIX release except IRIX 6.5. + - Files that already exist on the system are renamed to + "filename.O" on installation and back to "filename" when + removed (except for config files, which don't overwrite and + aren't removed.) + - Prerequisites (%required directive) now look for required + product in the current directory and install it automatically + if it is available and not already installed. + - The copyright notice in the installation script was not + displayed if the user used the "now" option. @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. @@ -0,0 +1,48 @@ +INSTALL - ESP Package Manager (EPM) 4.2 +--------------------------------------- + +Complete installation instructions can be found in the file +"doc/epm-book.html"... + + +WHAT IS REQUIRED FOR EPM? + + On your development system you just need a C compiler, a make + program, the Bourne (or Korn or Bash) shell, and gzip. + + The graphical setup program needs a C++ compiler and the + FLTK library, version 1.1 or higher, available at + "http://www.fltk.org". + + EPM can generate so-called "portable" distributions that are + based on shell scripts and tar files. For these types of + distributions your customers/users will need the Bourne (or + Korn or Bash) shell, a tar program, and GNU zip. The first + two are standard items, and GNU zip is being shipped by most + vendors as well. + + EPM can also generate vendor-specific distributions. These + require the particular vendor tool (rpm, dpkg, etc.) to load + the software. + + +HOW DO I COMPILE EPM? + + EPM uses GNU autoconf to configure itself for your system. + To build it, use: + + ./configure ENTER + make ENTER + + The default installation prefix is /usr; if you want to put + EPM in /usr/local, do: + + ./configure --prefix=/usr/local ENTER + make ENTER + + Once EPM is compiled you can type: + + su ENTER + make install ENTER + + to install the software in /usr/bin. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..7278af7 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,421 @@ +# +# "$Id: Makefile.in 827 2010-12-29 17:32:40Z mike $" +# +# Makefile for the ESP Package Manager (EPM). +# +# Copyright 1999-2010 by Easy Software Products, all rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +# +# Programs... +# + +AR = @AR@ +CC = @CC@ +CHMOD = @CHMOD@ +CP = @CP@ +CXX = @CXX@ +FLTKCONFIG = @FLTKCONFIG@ +MKDIR = @MKDIR@ -p +RANLIB = @RANLIB@ +RM = @RM@ -f +SHELL = /bin/sh +STRIP = @STRIP@ + + +# +# Program options... +# +# OPTIM defines the common compiler optimization/debugging options. +# + +ARFLAGS = @ARFLAGS@ +ARCHFLAGS = @ARCHFLAGS@ +CFLAGS = $(ARCHFLAGS) @CFLAGS@ $(OPTIM) +CXXFLAGS = $(ARCHFLAGS) @CXXFLAGS@ $(OPTIM) +GUILIBS = @GUILIBS@ +LDFLAGS = $(ARCHFLAGS) @LDFLAGS@ $(OPTIM) +LIBS = @LIBS@ +OPTIM = @OPTIM@ + + +# +# Directories... +# + +bindir = @bindir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +exec_prefix = @exec_prefix@ +mandir = @mandir@ +prefix = @prefix@ +libdir = @libdir@ +srcdir = @srcdir@ + +VPATH = $(srcdir) + + +# +# Rules... +# + +.SILENT: + +.SUFFIXES: .c .cxx .h .o +.c.o: + echo Compiling $<... + $(CC) $(CFLAGS) -I. -I$(srcdir) -c $< +.cxx.o: + echo Compiling $<... + $(CXX) $(CXXFLAGS) -I. -I$(srcdir) -c $< + + +# +# Targets... +# + +TARGETS = libepm.a \ + epm \ + epminstall \ + mkepmlist \ + @GUIS@ +EPM_OBJS = aix.o \ + bsd.o \ + deb.o \ + dist.o \ + file.o \ + inst.o \ + osx.o \ + pkg.o \ + portable.o \ + qprintf.o \ + rpm.o \ + run.o \ + setld.o \ + slackware.o \ + snprintf.o \ + string.o \ + support.o \ + swinstall.o \ + tar.o +SETUP_OBJS = setup.o \ + setup2.o \ + gui-common.o +UNINST_OBJS = uninst.o \ + uninst2.o \ + gui-common.o +OBJS = epm.o \ + $(EPM_OBJS) \ + epminstall.o \ + mkepmlist.o \ + $(SETUP_OBJS) \ + $(UNINST_OBJS) + + +# +# Make all targets... +# + +all: $(TARGETS) Makefile config.h + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) + $(RM) $(TARGETS) + + +# +# Clean all object files and generated files... +# + +distclean: + $(RM) $(OBJS) + $(RM) $(TARGETS) + $(RM) config.cache config.h config.log config.status + $(RM) Makefile doc/Makefile macosx/Makefile + $(RM) epm.list + + +# +# Run the clang.llvm.org static code analysis tool on the C sources. +# + +.PHONY: clang clang-changes +clang: + $(RM) -r clang + scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) clean all +clang-changes: + scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) all + + +# +# Install all targets... +# + +install: all @INSTALL_GUIS@ @INSTALL_OSX@ + echo Installing EPM programs in $(bindir) + -$(MKDIR) $(bindir) + $(RM) $(bindir)/epm + $(CP) epm $(bindir) + $(STRIP) $(bindir)/epm + $(RM) $(bindir)/epminstall + $(CP) epminstall $(bindir) + $(STRIP) $(bindir)/epminstall + $(RM) $(bindir)/mkepmlist + $(CP) mkepmlist $(bindir) + echo Installing EPM manpages in $(mandir)/man1 + -$(MKDIR) $(mandir)/man1 + $(RM) $(mandir)/man1/epm.1 + $(CP) $(srcdir)/doc/epm.man $(mandir)/man1/epm.1 + $(RM) $(mandir)/man1/epminstall.1 + $(CP) $(srcdir)/doc/epminstall.man $(mandir)/man1/epminstall.1 + $(RM) $(mandir)/man1/mkepmlist.1 + $(CP) $(srcdir)/doc/mkepmlist.man $(mandir)/man1/mkepmlist.1 + $(RM) $(mandir)/man1/setup.1 + $(CP) $(srcdir)/doc/setup.man $(mandir)/man1/setup.1 + echo Installing EPM manpages in $(mandir)/man5 + -$(MKDIR) $(mandir)/man5 + $(RM) $(mandir)/man5/epm.list.5 + $(CP) $(srcdir)/doc/epm.list.man $(mandir)/man5/epm.list.5 + $(RM) $(mandir)/man5/setup.types.5 + $(CP) $(srcdir)/doc/setup.types.man $(mandir)/man5/setup.types.5 + echo Installing EPM documentation in $(docdir) + -$(MKDIR) $(docdir) + $(RM) $(docdir)/COPYING + $(CP) $(srcdir)/COPYING $(docdir) + $(RM) $(docdir)/README + $(CP) $(srcdir)/README $(docdir) + $(RM) $(docdir)/epm-book.html + $(CP) $(srcdir)/doc/epm-book.html $(docdir) + +install-guis: setup uninst + echo Installing EPM setup/uninst in $(libdir)/epm + $(RM) -r $(libdir)/epm + -$(MKDIR) $(libdir)/epm + $(CP) setup $(libdir)/epm + -$(STRIP) $(libdir)/epm/setup + $(CP) uninst $(libdir)/epm + -$(STRIP) $(libdir)/epm/uninst + +install-osx: + echo Installing EPM OSX data files in $(datadir)/epm + $(RM) -r $(datadir)/epm + -$(MKDIR) $(datadir)/epm + $(CP) macosx/setup.icns $(datadir)/epm + $(CP) macosx/setup.info $(datadir)/epm + $(CP) macosx/uninst.icns $(datadir)/epm + $(CP) macosx/uninst.info $(datadir)/epm + + +# +# Uninstall EPM... +# + +uninstall: + echo Uninstalling EPM programs from $(bindir) + $(RM) $(bindir)/epm + $(RM) $(bindir)/epminstall + $(RM) $(bindir)/mkepmlist + echo Uninstalling EPM manpages from $(mandir)/man1 + $(RM) $(mandir)/man1/epm.1 + $(RM) $(mandir)/man1/epminstall.1 + $(RM) $(mandir)/man1/mkepmlist.1 + $(RM) $(mandir)/man1/setup.1 + echo Uninstalling EPM manpages from $(mandir)/man5 + $(RM) $(mandir)/man5/epm.list.5 + $(RM) $(mandir)/man5/setup.types.5 + echo Uninstalling EPM documentation from $(docdir) + $(RM) -r $(docdir) + echo Uninstalling EPM setup/uninstall from $(libdir)/epm + $(RM) -r $(libdir)/epm + echo Uninstalling EPM OSX data files from $(datadir)/epm + $(RM) -r $(datadir)/epm + + +# +# Makefile +# + +Makefile: Makefile.in configure + if test -f config.status; then \ + ./config.status --recheck; \ + ./config.status; \ + else \ + ./configure; \ + fi + touch config.h + + +# +# config.h +# + +config.h: config.h.in configure + if test -f config.status; then \ + ./config.status --recheck; \ + ./config.status; \ + else \ + ./configure; \ + fi + touch config.h + + +# +# Test EPM... +# + +test: $(TARGETS) + echo Starting portable distribution build test... + if ./epm -vv epm >test.log; then \ + echo Portable distribution build test PASSED.; \ + else \ + echo Portable distribution build test FAILED.; \ + cat test.log; \ + fi + echo Starting native distribution build test... + if ./epm -vv -s doc/epmlogo.tif -f native epm >test.log; then \ + echo Native distribution build test PASSED.; \ + else \ + echo Native distribution build test FAILED.; \ + cat test.log; \ + fi + $(RM) test.log + + +# +# Make distributions using EPM... +# + +aix: $(TARGETS) + ./epm -f aix -v epm + +bsd: $(TARGETS) + ./epm -f bsd -v epm + +slackware: $(TARGETS) + ./epm -f slackware -v epm + +deb: $(TARGETS) + ./epm -f deb -v epm + +gui portable: $(TARGETS) + ./epm -v -s doc/epmlogo.gif --setup-program setup \ + --uninstall-program uninst --data-dir macosx epm + +inst tardist: $(TARGETS) + ./epm -f tardist -v epm + +lsb rpm: $(TARGETS) + ./epm -f $@ -v -s doc/epmlogo.gif --setup-program setup \ + --uninstall-program uninst --data-dir macosx epm + +pkg: $(TARGETS) + ./epm -f pkg -v epm + +native: $(TARGETS) + ./epm -f native -v epm + +osx: $(TARGETS) + ./epm -f osx -v -s doc/epmlogo.tif epm + +swinstall depot: $(TARGETS) + ./epm -f depot -v epm + + +# +# libepm.a +# + +libepm.a: $(EPM_OBJS) + echo Archiving libepm.a... + $(RM) libepm.a + $(AR) $(ARFLAGS) libepm.a $(EPM_OBJS) + $(RANLIB) libepm.a + +$(EPM_OBJS): epm.h epmstring.h + + +# +# epm +# + +epm: epm.o $(EPM_OBJS) + echo Linking epm... + $(CC) $(LDFLAGS) -o epm epm.o libepm.a $(LIBS) + +epm.o: epm.h epmstring.h + + +# +# epminstall +# + +epminstall: epminstall.o libepm.a + echo Linking epminstall... + $(CC) $(LDFLAGS) -o epminstall epminstall.o libepm.a $(LIBS) + +epminstall.o: epm.h epmstring.h + + +# +# mkepmlist +# + +mkepmlist: mkepmlist.o libepm.a + echo Linking mkepmlist... + $(CC) $(LDFLAGS) -o mkepmlist mkepmlist.o libepm.a $(LIBS) + +mkepmlist.o: epm.h epmstring.h + + +# +# setup +# + +setup: $(SETUP_OBJS) libepm.a + echo Linking setup... + $(CXX) $(LDFLAGS) -o setup $(SETUP_OBJS) libepm.a $(GUILIBS) $(LIBS) + +setup.o: setup.h gui-common.h epmstring.h +setup2.o: setup.h gui-common.h epmstring.h +gui-common.o: gui-common.h + + +# +# uninst +# + +uninst: $(UNINST_OBJS) libepm.a + echo Linking uninst... + $(CXX) $(LDFLAGS) -o uninst $(UNINST_OBJS) libepm.a $(GUILIBS) $(LIBS) + +uninst.o: uninst.h epmstring.h gui-common.h +uninst2.o: uninst.h epmstring.h gui-common.h +gui-common.o: gui-common.h + + +# +# Common dependencies... +# + +$(OBJS): Makefile config.h + + +# +# End of "$Id: Makefile.in 827 2010-12-29 17:32:40Z mike $". +# @@ -0,0 +1,103 @@ +README - ESP Package Manager (EPM) 4.2 +-------------------------------------- + +WHAT IS EPM? + + EPM is the software packaging tool that we use at Easy Software + Products. It is a simple tool that generates software and patch + distributions in various formats, including: + + - AIX software packages ("installp") + - AT&T software packages ("pkgadd"), used by Solaris and others + - BSD packages ("pkg_create") + - Compaq Tru64 UNIX ("setld") + - Debian Package Manager ("dpkg") + - HP-UX software packages ("swinstall") + - IRIX software manager ("inst", "swmgr", or "tardist") + - MacOS X software packages ("name.pkg") + - Portable (installation and removal scripts with tar files) + - Red Hat Package Manager ("rpm") + - Slackware software packages ("name.tgz") + + EPM also includes graphical "setup" and "uninstall" programs + that can be provided with your distributions to make + installation and removal of more than one package a snap. + + +WHY ANOTHER SOFTWARE PACKAGING TOOL? + + We developed EPM because we are tired of developing and + testing N different software distributions, each with their + own input files and setup requirements. + + Also, when we looked at software distribution on Linux we + saw that there are at least four different "standard" + distribution formats, and none of them are compatible with + the other. Clearly we needed something that could be used + for all platforms *without* requiring special software + packages on the customer's system! + + +HOW DO I COMPILE EPM? + + See the file "INSTALL" for more info on that. + + +HOW DO I USE EPM? + + Please look at the EPM manual; preformatted copies are + included in the "doc/epm-manual.html" and + "doc/epm-manual.pdf" files. + + An example EPM software list file is provided with this + distribution in the file "epm.list". + + +DO I HAVE TO PAY TO DISTRIBUTE SOFTWARE USING EPM? + + No! EPM is free software and any installations you create are unencumbered + by licensing of any kind, not even the GPL. + + +WHAT'S NEW IN EPM? + + See the file "CHANGES" for change information. + + +REPORTING PROBLEMS + + Report all problems and submit all patches using the bug reporting form at: + + http://www.epmhome.org/str.php + + +OTHER RESOURCES + + The official home page for EPM is here: + + http://www.epmhome.org/ + + Easy Software Products also maintains a news server for the discussion of + ESP and ESP-sponsored software. The news server is: + + news.easysw.com + + If you don't have NNTP access from your systems, point your web browser at + the following URL: + + http://www.epmhome.org/forums.php + + +COPYRIGHT AND LICENSE INFO + + EPM is copyright 1999-2010 by Easy Software Products. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. @@ -0,0 +1,950 @@ +/* + * "$Id: aix.c 839 2010-12-30 18:41:50Z mike $" + * + * AIX package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_aix() - Make an AIX software distribution package. + * aix_addfile() - Add a file to the AIX directory list... + * aix_fileset() - Write a subpackage description... + * aix_version() - Generate an AIX version number. + * write_liblpp() - Create the liblpp.a file for the root or /usr parts. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Directory information... + */ + +typedef struct +{ + char dst[1024]; /* Output directory */ + int blocks; /* Size of files in this directory */ +} aixdir_t; + + +/* + * Local functions... + */ + +static int aix_addfile(int type, const char *src, const char *dst, + int num_dirs, aixdir_t **dirs); +static void aix_fileset(FILE *fp, const char *prodname, dist_t *dist, + const char *subpackage); +static char *aix_version(const char *version); +static int write_liblpp(const char *prodname, + const char *directory, + dist_t *dist, int root, + const char *subpackage); + + +/* + * Local globals... + */ + +static const char *files[] = /* Control files... */ + { + "al", + "cfgfiles", + "copyright", + "inventory", + "post_i", + "pre_i", + "unpost_i", + "unpre_i" + }; + + +/* + * 'make_aix()' - Make an AIX software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_aix(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i; /* Looping var */ + FILE *fp; /* Control file */ + char name[1024], /* Full product name */ + filename[1024], /* Destination filename */ + current[1024]; /* Current directory */ + file_t *file; /* Current distribution file */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + const char *runlevels; /* Run levels */ + + + REF(platform); + + if (Verbosity) + puts("Creating AIX distribution..."); + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodname, dist->version, + dist->release, platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, + dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + getcwd(current, sizeof(current)); + + /* + * Write the lpp_name file for installp... + */ + + if (Verbosity) + puts("Creating lpp_name file..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + make_directory(filename, 0755, 0, 0); + + snprintf(filename, sizeof(filename), "%s/%s/lpp_name", directory, prodname); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create lpp_name file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fprintf(fp, "4 R I %s {\n", prodname); + + aix_fileset(fp, prodname, dist, NULL); + for (i = 0; i < dist->num_subpackages; i ++) + aix_fileset(fp, prodname, dist, dist->subpackages[i]); + + fputs("}\n", fp); + + fclose(fp); + + /* + * Write the root partition liblpp.a file... + */ + + write_liblpp(prodname, directory, dist, 1, NULL); + for (i = 0; i < dist->num_subpackages; i ++) + write_liblpp(prodname, directory, dist, 1, dist->subpackages[i]); + + /* + * Write the usr partition liblpp.a file... + */ + + write_liblpp(prodname, directory, dist, 0, NULL); + for (i = 0; i < dist->num_subpackages; i ++) + write_liblpp(prodname, directory, dist, 0, dist->subpackages[i]); + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + if (!strncmp(file->dst, "/export/", 8) || + !strncmp(file->dst, "/opt/", 5) || + !strncmp(file->dst, "/usr/", 5)) + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodname, + file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/usr/lpp/%s/inst_root%s", + directory, prodname, prodname, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'i' : + for (runlevels = get_runlevels(file, "2"); + isdigit(*runlevels & 255); + runlevels ++) + { + snprintf(filename, sizeof(filename), + "%s/%s/usr/lpp/%s/inst_root/etc/rc.d/rc%c.d/S%02d%s", + directory, prodname, prodname, *runlevels, + get_start(file, 99), file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, + pwd ? pwd->pw_uid : 0, grp ? grp->gr_gid : 0)) + return (1); + + snprintf(filename, sizeof(filename), + "%s/%s/usr/lpp/%s/inst_root/etc/rc.d/rc%c.d/K%02d%s", + directory, prodname, prodname, *runlevels, + get_stop(file, 0), file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, + pwd ? pwd->pw_uid : 0, grp ? grp->gr_gid : 0)) + return (1); + } + break; + case 'd' : + if (!strcmp(file->dst, "/export") || + !strncmp(file->dst, "/export/", 8) || + !strcmp(file->dst, "/opt") || + !strncmp(file->dst, "/opt/", 5) || + !strcmp(file->dst, "/usr") || + !strncmp(file->dst, "/usr/", 5)) + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodname, + file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/usr/lpp/%s/inst_root%s", + directory, prodname, prodname, file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + case 'l' : + if (!strncmp(file->dst, "/export/", 8) || + !strncmp(file->dst, "/opt/", 5) || + !strncmp(file->dst, "/usr/", 5)) + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodname, + file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/usr/lpp/%s/inst_root%s", + directory, prodname, prodname, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution from the spec file... + */ + + if (Verbosity) + puts("Building AIX binary distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + + if (run_command(filename, + "sh -c \'find . -print | backup -i -f ../%s.bff -q %s\'", + prodname, Verbosity ? "-v" : "")) + return (1); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + unlink_directory(filename); + + for (i = 0; i < (sizeof(files) / sizeof(files[0])); i ++) + { + snprintf(filename, sizeof(filename), "%s/%s.%s", directory, prodname, + files[i]); + unlink(filename); + } + + snprintf(filename, sizeof(filename), "%s/lpp.README", directory); + unlink(filename); + } + + return (0); +} + + +/* + * 'aix_addfile()' - Add a file to the AIX directory list... + */ + +static int /* O - New number dirs */ +aix_addfile(int type, /* I - Filetype */ + const char *src, /* I - Source path */ + const char *dst, /* I - Destination path */ + int num_dirs, /* I - Number of directories */ + aixdir_t **dirs) /* IO - Directories */ +{ + int i, j; /* Looping vars */ + int blocks; /* Blocks to add... */ + struct stat fileinfo; /* File information */ + aixdir_t *temp; /* Temporary pointer */ + char dstpath[1024], /* Destination path */ + *dstptr; /* Pointer into destination */ + + + /* + * Determine the destination path and block size... + */ + + strlcpy(dstpath, dst, sizeof(dstpath)); + + if (type == 'd') + { + blocks = 1; + dstptr = dstpath + strlen(dstpath) - 1; + } + else + { + dstptr = strrchr(dstpath, '/'); + + if (type == 'l') + blocks = 1; + else if (!stat(src, &fileinfo)) + blocks = (fileinfo.st_size + 511) / 512; + else + blocks = 0; + } + + if (dstptr && *dstptr == '/' && dstptr > dstpath) + *dstptr = '\0'; + + /* + * Now see if the destination path is in the array... + */ + + temp = *dirs; + + for (i = 0; i < num_dirs; i ++) + if ((j = strcmp(temp[i].dst, dstpath)) == 0) + { + temp[i].blocks += blocks; + return (num_dirs); + } + else if (j > 0) + break; + + /* + * Not in the list; allocate a new one... + */ + + if (num_dirs == 0) + temp = malloc(sizeof(aixdir_t)); + else + temp = realloc(*dirs, (num_dirs + 1) * sizeof(aixdir_t)); + + if (!temp) + return (num_dirs); + + *dirs = temp; + temp += i; + + if (i < num_dirs) + memmove(temp + 1, temp, (num_dirs - i) * sizeof(aixdir_t)); + + strcpy(temp->dst, dstpath); + temp->blocks = blocks; + + return (num_dirs + 1); +} + + +/* + * 'aix_fileset()' - Write a subpackage description... + */ + +static void +aix_fileset(FILE *fp, /* I - File to write to */ + const char *prodname, /* I - Product name */ + dist_t *dist, /* I - Distribution */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + depend_t *d; /* Current dependency */ + file_t *file; /* Current distribution file */ + int num_dirs; /* Number of directories */ + aixdir_t *dirs; /* Directories */ + + + /* + * Start fileset definition... + */ + + if (subpackage) + fprintf(fp, "%s.%s", prodname, subpackage); + else + fprintf(fp, "%s", prodname); + + fprintf(fp, " %s 01 N B x ", aix_version(dist->version)); + + if (subpackage) + { + for (i = 0; i < dist->num_descriptions; i ++) + { + if (dist->descriptions[i].subpackage == subpackage) + { + fprintf(fp, "%s\n", dist->descriptions[i].description); + break; + } + } + } + else + fprintf(fp, "%s\n", dist->product); + + + /* + * Dependencies... + */ + + fputs("[\n", fp); + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REQUIRES && d->subpackage == subpackage && + strcmp(d->product, "_self")) + fprintf(fp, "*prereq %s %s\n", d->product, aix_version(d->version[0])); + + /* + * Installation sizes... + */ + + fputs("%\n", fp); + + num_dirs = 0; + dirs = NULL; + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->subpackage == subpackage) + num_dirs = aix_addfile(tolower(file->type), file->src, file->dst, + num_dirs, &dirs); + + for (i = 0; i < num_dirs; i ++) + fprintf(fp, "%s %d\n", dirs[i].dst, dirs[i].blocks); + + if (num_dirs > 0) + free(dirs); + + /* + * This package supercedes which others? + */ + + fputs("%\n", fp); + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REPLACES && d->subpackage == subpackage && + strcmp(d->product, "_self")) + fprintf(fp, "%s %s", d->product, aix_version(d->version[0])); + + /* + * Fix information is only used for updates (patches)... + */ + + fputs("%\n", fp); + fputs("]\n", fp); +} + + +/* + * 'aix_version()' - Generate an AIX version number. + */ + +static char * /* O - AIX version number */ +aix_version(const char *version) /* I - EPM version number */ +{ + int verparts[4]; /* Version number parts */ + static char aix[255]; /* AIX version number string */ + + + /* + * AIX requires a four-part version number (M.m.p.r)... + */ + + memset(verparts, 0, sizeof(verparts)); + sscanf(version, "%d.%d.%d.%d", verparts + 0, verparts + 1, + verparts + 2, verparts + 3); + sprintf(aix, "%d.%d.%d.%d", verparts[0], verparts[1], + verparts[2], verparts[3]); + + return (aix); +} + + +/* + * 'write_liblpp()' - Create the liblpp.a file for the root or /usr parts. + */ + +static int /* O - 0 = success, 1 = fail */ +write_liblpp(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + dist_t *dist, /* I - Distribution information */ + int root, /* I - Root partition? */ + const char *subpackage)/* I - Subpackage */ +{ + int i; /* Looping var */ + FILE *fp; /* Control file */ + char filename[1024], /* Destination filename */ + prodfull[1024]; /* Full product name */ + struct stat fileinfo; /* File information */ + command_t *c; /* Current command */ + file_t *file; /* Current distribution file */ + int configcount; /* Number of config files */ + int shared_file; /* Shared file? */ + const char *runlevels; /* Run levels */ + + + /* + * Progress info... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s.%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + if (Verbosity) + printf("Updating %s partition liblpp.a file for %s...\n", + root ? "root" : "shared", prodfull); + + /* + * Write the product.al file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .al file..."); + + snprintf(filename, sizeof(filename), "%s/%s.al", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .al file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'i' : + for (runlevels = get_runlevels(file, "2"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (root) + putc('.', fp); + else + qprintf(fp, "./usr/lpp/%s/inst_root", prodfull); + + if (*runlevels == '0') + qprintf(fp, "/etc/rc.d/rc0.d/K%02d%s\n", + get_stop(file, 0), file->dst); + else + qprintf(fp, "/etc/rc.d/rc%c.d/S%02d%s\n", + *runlevels, get_start(file, 99), file->dst); + } + break; + + default : + shared_file = !(strcmp(file->dst, "/usr") && + strncmp(file->dst, "/usr/", 5) && + strcmp(file->dst, "/opt") && + strncmp(file->dst, "/opt/", 5)); + + /* + * Put file in root or share .al file as appropriate + */ + + if ((shared_file && !root) || (!shared_file && root)) + qprintf(fp, ".%s\n", file->dst); + + /* + * Put any root file in the share .al so it will be extracted + * to /usr/lpp/<prodfull>/inst_root directory. I have no + * idea if this is really the way to do it but it seems to + * work... + */ + + if (!shared_file && !root) + qprintf(fp, "./usr/lpp/%s/inst_root%s\n", prodfull, file->dst); + break; + } + + fclose(fp); + + /* + * Write the product.cfgfiles file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .cfgfiles file..."); + + snprintf(filename, sizeof(filename), "%s/%s.cfgfiles", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .cfgfiles file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + configcount = 0; + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage && + (strcmp(file->dst, "/usr") || + strncmp(file->dst, "/usr/", 5) || + strcmp(file->dst, "/opt") || + strncmp(file->dst, "/opt/", 5)) == root) + { + qprintf(fp, ".%s hold_new\n", file->dst); + configcount ++; + } + + fclose(fp); + + /* + * Write the product.copyright file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .copyright file..."); + + snprintf(filename, sizeof(filename), "%s/%s.copyright", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .copyright file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fprintf(fp, "%s, %s\n%s\n%s\n", dist->product, aix_version(dist->version), + dist->vendor, dist->copyright); + + fclose(fp); + + if (root) + { + /* + * Write the product.pre_i file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .pre_i file..."); + + snprintf(filename, sizeof(filename), "%s/%s.pre_i", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .pre_i file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (c = dist->commands, i = dist->num_commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + + /* + * Write the product.post_i file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .post_i file..."); + + snprintf(filename, sizeof(filename), "%s/%s.post_i", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .post_i file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (c = dist->commands, i = dist->num_commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + + /* + * Write the product.unpre_i file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .unpre_i file..."); + + snprintf(filename, sizeof(filename), "%s/%s.unpre_i", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .unpre_i file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (c = dist->commands, i = dist->num_commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + + /* + * Write the product.unpost_i file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .unpost_i file..."); + + snprintf(filename, sizeof(filename), "%s/%s.unpost_i", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .unpost_i file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (c = dist->commands, i = dist->num_commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + + /* + * Write the product.inventory file for installp... + */ + + if (Verbosity > 1) + puts(" Creating .inventory file..."); + + snprintf(filename, sizeof(filename), "%s/%s.inventory", directory, prodfull); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create .inventory file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + if (file->subpackage != subpackage) + continue; + + if (root) + { + if (!strcmp(file->dst, "/usr") || + !strncmp(file->dst, "/usr/", 5) || + !strcmp(file->dst, "/opt") || + !strncmp(file->dst, "/opt/", 5)) + continue; + } + else + { + if (tolower(file->type) == 'c' || + (strcmp(file->dst, "/usr") && + strncmp(file->dst, "/usr/", 5) && + strcmp(file->dst, "/opt") && + strncmp(file->dst, "/opt/", 5))) + continue; + } + + switch (tolower(file->type)) + { + case 'i' : + for (runlevels = get_runlevels(file, "2"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + qprintf(fp, "/etc/rc.d/rc0.d/K%02d%s:\n", + get_stop(file, 0), file->dst); + else + qprintf(fp, "/etc/rc.d/rc%c.d/S%02d%s:\n", + *runlevels, get_start(file, 99), file->dst); + + fprintf(fp, " class=apply,inventory,%s\n", prodfull); + + fputs(" type=FILE\n", fp); + if (!stat(file->src, &fileinfo)) + fprintf(fp, " size=%d\n", (int)fileinfo.st_size); + + fprintf(fp, " owner=%s\n", file->user); + fprintf(fp, " group=%s\n", file->group); + fprintf(fp, " mode=%04o\n", (unsigned)file->mode); + fputs("\n", fp); + } + break; + default : + qprintf(fp, "%s:\n", file->dst); + fprintf(fp, " class=apply,inventory,%s\n", prodfull); + + switch (tolower(file->type)) + { + case 'd' : + fputs(" type=DIRECTORY\n", fp); + break; + case 'l' : + fputs(" type=SYMLINK\n", fp); + qprintf(fp, " target=%s\n", file->src); + break; + case 'c' : + fputs(" type=FILE\n", fp); + fputs(" size=VOLATILE\n", fp); + break; + default : + fputs(" type=FILE\n", fp); + if (!stat(file->src, &fileinfo)) + fprintf(fp, " size=%ld\n", (long)fileinfo.st_size); + break; + } + + fprintf(fp, " owner=%s\n", file->user); + fprintf(fp, " group=%s\n", file->group); + fprintf(fp, " mode=%04o\n", (unsigned)file->mode); + fputs("\n", fp); + break; + } + } + + fclose(fp); + + /* + * Write the lpp.README file... + */ + + snprintf(filename, sizeof(filename), "%s/lpp.README", directory); + + if (dist->license[0]) + copy_file(filename, dist->license, 0644, 0, 0); + else if (dist->readme[0]) + copy_file(filename, dist->readme, 0644, 0, 0); + else if ((fp = fopen(filename, "w")) != NULL) + fclose(fp); + else + { + fprintf(stderr, "epm: Unable to create .README file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + /* + * Create the liblpp.a file... + */ + + if (Verbosity > 1) + puts(" Creating liblpp.a archive..."); + + if (root) + { + snprintf(filename, sizeof(filename), "%s/%s/usr/lpp/%s/inst_root", + directory, prodname, prodname); + make_directory(filename, 0755, 0, 0); + + snprintf(filename, sizeof(filename), "%s/usr/lpp/%s/inst_root/liblpp.a", + prodname, prodname); + } + else + { + snprintf(filename, sizeof(filename), "%s/%s/usr/lpp/%s", + directory, prodname, prodname); + make_directory(filename, 0755, 0, 0); + + snprintf(filename, sizeof(filename), "%s/usr/lpp/%s/liblpp.a", + prodname, prodname); + } + + if (!subpackage) + if (run_command(directory, "ar rc %s lpp.README", filename)) + return (1); + + for (i = 0; i < (sizeof(files) / sizeof(files[0])); i ++) + { + if (i >= 4 && !root) + break; + + if (i == 1 && !configcount) + continue; + + if (run_command(directory, "ar rc %s %s.%s", + filename, prodfull, files[i])) + return (1); + } + + return (0); +} + + +/* + * End of "$Id: aix.c 839 2010-12-30 18:41:50Z mike $". + */ @@ -0,0 +1,464 @@ +/* + * "$Id: bsd.c 833 2010-12-30 00:00:50Z mike $" + * + * Free/Net/OpenBSD package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_bsd() - Make a Free/Net/OpenBSD software distribution package. + * make_subpackage() - Create a subpackage... + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static int make_subpackage(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + const char *subpackage); + + +/* + * 'make_bsd()' - Make a Free/Net/OpenBSD software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_bsd(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i; /* Looping var */ + + + if (make_subpackage(prodname, directory, platname, dist, NULL)) + return (1); + + for (i = 0; i < dist->num_subpackages; i ++) + if (make_subpackage(prodname, directory, platname, dist, + dist->subpackages[i])) + return (1); + + return (0); +} + + +/* + * 'make_subpackage()' - Create a subpackage... + */ + +static int /* O - 0 = success, 1 = fail */ +make_subpackage( + const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + const char *subpackage) /* I - Subpackage name */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec file */ + char prodfull[1024]; /* Full subpackage name */ + char name[1024]; /* Full product name */ + char commentname[1024]; /* pkg comment filename */ + char descrname[1024]; /* pkg descr filename */ + char plistname[1024]; /* pkg plist filename */ + char filename[1024]; /* Destination filename */ + char *old_user, /* Old owner UID */ + *old_group; /* Old group ID */ + int old_mode; /* Old permissions */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + depend_t *d; /* Current dependency */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + char current[1024]; /* Current directory */ + + + getcwd(current, sizeof(current)); + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + if (Verbosity) + printf("Creating %s *BSD pkg distribution...\n", prodfull); + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodfull, dist->version, + dist->release, platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version, + dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodfull, dist->version); + + /* + * Write the descr file for pkg... + */ + + if (Verbosity) + printf("Creating %s.descr file...\n", prodfull); + + snprintf(descrname, sizeof(descrname), "%s/%s.descr", directory, prodfull); + + if ((fp = fopen(descrname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create descr file \"%s\" - %s\n", descrname, + strerror(errno)); + return (1); + } + + fprintf(fp, "%s\n", dist->product); + + fclose(fp); + + /* + * Write the comment file for pkg... + */ + + if (Verbosity) + printf("Creating %s.comment file...\n", prodfull); + + snprintf(commentname, sizeof(commentname), "%s/%s.comment", directory, + prodfull); + + if ((fp = fopen(commentname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create comment file \"%s\" - %s\n", commentname, + strerror(errno)); + return (1); + } + + fprintf(fp, "Summary: %s\n", dist->product); + fprintf(fp, "Name: %s\n", prodfull); + fprintf(fp, "Version: %s\n", dist->version); + fprintf(fp, "Release: %s\n", dist->release); + fprintf(fp, "Copyright: %s\n", dist->copyright); + fprintf(fp, "Packager: %s\n", dist->packager); + fprintf(fp, "Vendor: %s\n", dist->vendor); + fprintf(fp, "BuildRoot: %s/%s/%s.buildroot\n", current, directory, prodfull); + fputs("Group: Applications\n", fp); + + fputs("Description:\n\n", fp); + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + fprintf(fp, "%s\n", dist->descriptions[i].description); + + fclose(fp); + + /* + * Write the plist file for pkg... + */ + + if (Verbosity) + printf("Creating %s.plist file...\n", prodfull); + + snprintf(plistname, sizeof(plistname), "%s/%s.plist", directory, prodfull); + + if ((fp = fopen(plistname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create plist file \"%s\" - %s\n", plistname, + strerror(errno)); + return (1); + } + + /* + * FreeBSD and NetBSD support both "source directory" and "preserve files" + * options, OpenBSD does not... + */ + +#ifdef __FreeBSD__ + fprintf(fp, "@srcdir %s/%s/%s.buildroot\n", current, directory, prodfull); + fputs("@option preserve\n", fp); +#elif defined(__NetBSD__) + fprintf(fp, "@src %s/%s/%s.buildroot\n", current, directory, prodfull); + fputs("@option preserve\n", fp); +#endif /* __FreeBSD__ */ + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + { + if (d->subpackage != subpackage) + continue; + + if (d->type == DEPEND_REQUIRES) +#ifdef __OpenBSD__ + fprintf(fp, "@depend %s", d->product); +#else + fprintf(fp, "@pkgdep %s", d->product); +#endif /* __OpenBSD__ */ + else +#ifdef __FreeBSD__ + /* + * FreeBSD uses @conflicts... + */ + fprintf(fp, "@conflicts %s", d->product); +#elif defined(__OpenBSD__) + fprintf(fp, "@conflict %s", d->product); +#else + fprintf(fp, "@pkgcfl %s", d->product); +#endif /* __FreeBSD__ */ + if (d->vernumber[0] > 0) + fprintf(fp, "-%s\n", d->version[0]); + else + putc('\n', fp); + } + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->subpackage == subpackage) + switch (c->type) + { + case COMMAND_PRE_INSTALL : + fputs("WARNING: Package contains pre-install commands which are not supported\n" + " by the BSD packager.\n", stderr); + break; + case COMMAND_POST_INSTALL : + fprintf(fp, "@exec %s\n", c->command); + break; + case COMMAND_PRE_REMOVE : + fprintf(fp, "@unexec %s\n", c->command); + break; + case COMMAND_POST_REMOVE : + fputs("WARNING: Package contains post-removal commands which are not supported\n" + " by the BSD packager.\n", stderr); + break; + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + { + /* + * We create and update directories as postinstall commands to + * avoid a bug in the FreeBSD pkg_delete command. + */ + + fprintf(fp, "@exec mkdir -p %s\n", file->dst); + fprintf(fp, "@exec chown %s:%s %s\n", file->user, file->group, + file->dst); + fprintf(fp, "@exec chmod %04o %s\n", file->mode, file->dst); + } + + for (i = dist->num_files, file = dist->files, old_mode = 0, old_user = "", + old_group = ""; + i > 0; + i --, file ++) + { + /* + * The FreeBSD pkg_delete command (at least) doesn't like creating + * and deleting directories. I don't know if other BSD's have the + * same problem, but for now just put the directory stuff in a + * postinstall script... + */ + + if (tolower(file->type) == 'd' || file->subpackage != subpackage) + continue; + + if (file->mode != old_mode) + fprintf(fp, "@mode %04o\n", old_mode = file->mode); + if (strcmp(file->user, old_user)) + fprintf(fp, "@owner %s\n", old_user = file->user); + if (strcmp(file->group, old_group)) + fprintf(fp, "@group %s\n", old_group = file->group); + + switch (tolower(file->type)) + { + case 'i' : + qprintf(fp, "usr/local/etc/rc.d/%s\n", file->dst); + break; + case 'c' : + case 'f' : + case 'l' : +#ifdef __OpenBSD__ + qprintf(fp, "@file %s\n", file->dst + 1); + if (tolower(file->type) == 'c') + qprintf(fp, "@sample %s\n", file->dst + 1); +#else + qprintf(fp, "%s\n", file->dst + 1); +#endif /* __OpenBSD__ */ + break; + } + } + + /* + * Need to list directories to remove in reverse order after + * everything else... + */ + + for (i = dist->num_files, file = dist->files + i - 1; + i > 0; + i --, file --) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + qprintf(fp, "@dirrm %s\n", file->dst + 1); + + fclose(fp); + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + if (file->subpackage != subpackage) + continue; + + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + snprintf(filename, sizeof(filename), "%s/%s.buildroot%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'i' : + snprintf(filename, sizeof(filename), + "%s/%s.buildroot/usr/local/etc/rc.d/%s", directory, + prodfull, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'd' : + snprintf(filename, sizeof(filename), "%s/%s.buildroot%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + case 'l' : + snprintf(filename, sizeof(filename), "%s/%s.buildroot%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution... + */ + + if (Verbosity) + printf("Building %s *BSD pkg binary distribution...\n", prodfull); + +#ifdef __OpenBSD__ + if (run_command(NULL, "pkg_create -p / -B %s/%s.buildroot " + "-c %s " + "-d %s " + "-f %s " + "%s.tgz", + directory, prodfull, + commentname, + descrname, + plistname, + name)) + return (1); + + if (run_command(NULL, "mv %s.tgz %s", name, directory)) + return (1); +#elif defined(__FreeBSD__) + if (run_command(NULL, "/usr/sbin/pkg_create -p / " + "-c %s " + "-d %s " + "-f %s " + "%s/%s.tbz", + commentname, + descrname, + plistname, + directory, name)) + return (1); +#else + if (run_command(NULL, "pkg_create -p / " + "-c %s " + "-d %s " + "-f %s " + "%s/%s.tgz", + commentname, + descrname, + plistname, + directory, name)) + return (1); +#endif /* __OpenBSD__ */ + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/%s.buildroot", directory, + prodfull); + unlink_directory(filename); + + unlink(plistname); + unlink(commentname); + unlink(descrname); + } + + return (0); +} + + +/* + * End of "$Id: bsd.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..3f2399f --- /dev/null +++ b/config.h.in @@ -0,0 +1,140 @@ +/* + * "$Id: config.h.in 648 2005-10-19 14:25:05Z mike $" + * + * Configuration file for the ESP Package Manager (EPM). + * + * Copyright 1999-2005 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Version of software... + */ + +#define EPM_VERSION "" + + +/* + * Where are files stored? + */ + +#define EPM_SOFTWARE "/etc/software" + + +/* + * Where are binaries stored? + */ + +#define EPM_BINDIR "/usr/bin" +#define EPM_DATADIR "/usr/share/epm" +#define EPM_LIBDIR "/usr/lib/epm" + + +/* + * What options does the strip command take? + */ + +#define EPM_STRIP "/bin/strip" + + +/* + * What command is used to build RPMs? + */ + +#define EPM_RPMBUILD "rpm" + + +/* + * What option is used to specify the RPM architecture? + */ + +#define EPM_RPMARCH "--target" + + +/* + * Does this version of RPM support the "topdir_" variable? + */ + +#undef EPM_RPMTOPDIR + + +/* + * Compiler stuff... + */ + +#undef const +#undef __CHAR_UNSIGNED__ + + +/* + * Do we have the <strings.h> header file? + */ + +#undef HAVE_STRINGS_H + + +/* + * Which header files do we use for the statfs() function? + */ + +#undef HAVE_SYS_MOUNT_H +#undef HAVE_SYS_STATFS_H +#undef HAVE_SYS_VFS_H +#undef HAVE_SYS_PARAM_H + + +/* + * Do we have the strXXX() functions? + */ + +#undef HAVE_STRCASECMP +#undef HAVE_STRDUP +#undef HAVE_STRLCAT +#undef HAVE_STRLCPY +#undef HAVE_STRNCASECMP + + +/* + * Do we have the (v)snprintf() functions? + */ + +#undef HAVE_SNPRINTF +#undef HAVE_VSNPRINTF + + +/* + * Which directory functions and headers do we use? + */ + +#undef HAVE_DIRENT_H +#undef HAVE_SYS_DIR_H +#undef HAVE_SYS_NDIR_H +#undef HAVE_NDIR_H + + +/* + * Where is the "gzip" executable? + */ + +#define EPM_GZIP "gzip" + + +/* + * Compress files by default? + */ + +#define EPM_COMPRESS 0 + + +/* + * End of "$Id: config.h.in 648 2005-10-19 14:25:05Z mike $". + */ diff --git a/configure b/configure new file mode 100755 index 0000000..c711c93 --- /dev/null +++ b/configure @@ -0,0 +1,7431 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="epm.c" +ac_default_prefix=/usr +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +VERSION +VERNUMBER +LDFLAGS +ARCHFLAGS +OPTIM +CC +CFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CXX +CXXFLAGS +ac_ct_CXX +RANLIB +AR +CHMOD +CP +GZIP +HTMLDOC +MKDIR +NROFF +GROFF +RM +RPM +RPMBUILD +STRIP +CPP +GREP +EGREP +FLTKCONFIG +INSTALL_GUIS +INSTALL_OSX +GUIS +GUILIBS +ARFLAGS +EPM_SOFTWARE +EPM_GZIP +EPM_STRIP +EPM_BINDIR +EPM_LIBDIR +EPM_DATADIR +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-debug turn on debugging [default=no] + --enable-gui turn on GUI utilities [default=auto] + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-archflags=flags specify architecture flags [default=none] + --with-optim=flags specify optimization flags [default=auto] + --with-docdir=/dir set directory for documentation + [default=${datadir}/doc/epm] + --with-softwaredir=/dir set directory for EPM uninstall files and init scripts + [default=/etc/software] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers config.h" + + + + +VERSION=4.2 +VERNUMBER=420 + + +cat >>confdefs.h <<_ACEOF +#define EPM_VERSION "ESP Package Manager v$VERSION" +_ACEOF + + + +uname=`uname` +uversion=`uname -r | sed -e '1,$s/[^0-9]//g'` + +if test "$uname" = "IRIX64"; then + uname="IRIX" +fi + + +CFLAGS="${CFLAGS:=}" +CXXFLAGS="${CXXFLAGS:=}" +LDFLAGS="${LDFLAGS:=}" + + + +# Check whether --with-archflags was given. +if test "${with_archflags+set}" = set; then + withval=$with_archflags; ARCHFLAGS="$withval" +else + ARCHFLAGS="${ARCHFLAGS:=}" +fi + + + + +# Check whether --with-optim was given. +if test "${with_optim+set}" = set; then + withval=$with_optim; OPTIM="$withval" +else + OPTIM="${OPTIM:=}" +fi + + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then + enableval=$enable_debug; if eval "test x$enable_debug = xyes"; then + OPTIM="-g $OPTIM" +else + LDFLAGS="$LDFLAGS -s" +fi +fi + + +# Check whether --enable-gui was given. +if test "${enable_gui+set}" = set; then + enableval=$enable_gui; +fi + + + +# Check whether --with-docdir was given. +if test "${with_docdir+set}" = set; then + withval=$with_docdir; docdir="$withval" +else + docdir="\${datadir}/doc/epm" +fi + + + + + +# Check whether --with-softwaredir was given. +if test "${with_softwaredir+set}" = set; then + withval=$with_softwaredir; softwaredir="$withval" +else + softwaredir="" +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +AR=$ac_cv_path_AR +if test -n "$AR"; then + { echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "chmod", so it can be a program name with args. +set dummy chmod; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_CHMOD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $CHMOD in + [\\/]* | ?:[\\/]*) + ac_cv_path_CHMOD="$CHMOD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_CHMOD="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +CHMOD=$ac_cv_path_CHMOD +if test -n "$CHMOD"; then + { echo "$as_me:$LINENO: result: $CHMOD" >&5 +echo "${ECHO_T}$CHMOD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "cp", so it can be a program name with args. +set dummy cp; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_CP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $CP in + [\\/]* | ?:[\\/]*) + ac_cv_path_CP="$CP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +CP=$ac_cv_path_CP +if test -n "$CP"; then + { echo "$as_me:$LINENO: result: $CP" >&5 +echo "${ECHO_T}$CP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "gzip", so it can be a program name with args. +set dummy gzip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_GZIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GZIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +GZIP=$ac_cv_path_GZIP +if test -n "$GZIP"; then + { echo "$as_me:$LINENO: result: $GZIP" >&5 +echo "${ECHO_T}$GZIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +if test x$GZIP = x; then + { { echo "$as_me:$LINENO: error: GNU zip not found but required!" >&5 +echo "$as_me: error: GNU zip not found but required!" >&2;} + { (exit 1); exit 1; }; } +fi +# Extract the first word of "htmldoc", so it can be a program name with args. +set dummy htmldoc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_HTMLDOC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $HTMLDOC in + [\\/]* | ?:[\\/]*) + ac_cv_path_HTMLDOC="$HTMLDOC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_HTMLDOC="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +HTMLDOC=$ac_cv_path_HTMLDOC +if test -n "$HTMLDOC"; then + { echo "$as_me:$LINENO: result: $HTMLDOC" >&5 +echo "${ECHO_T}$HTMLDOC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_MKDIR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MKDIR in + [\\/]* | ?:[\\/]*) + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { echo "$as_me:$LINENO: result: $MKDIR" >&5 +echo "${ECHO_T}$MKDIR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "nroff", so it can be a program name with args. +set dummy nroff; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_NROFF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $NROFF in + [\\/]* | ?:[\\/]*) + ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +NROFF=$ac_cv_path_NROFF +if test -n "$NROFF"; then + { echo "$as_me:$LINENO: result: $NROFF" >&5 +echo "${ECHO_T}$NROFF" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +if test x$NROFF = x; then + # Extract the first word of "groff", so it can be a program name with args. +set dummy groff; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_GROFF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GROFF in + [\\/]* | ?:[\\/]*) + ac_cv_path_GROFF="$GROFF" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +GROFF=$ac_cv_path_GROFF +if test -n "$GROFF"; then + { echo "$as_me:$LINENO: result: $GROFF" >&5 +echo "${ECHO_T}$GROFF" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + if test x$GROFF = x; then + NROFF="echo" + else + NROFF="$GROFF -T ascii" + fi +fi +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RM in + [\\/]* | ?:[\\/]*) + ac_cv_path_RM="$RM" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +RM=$ac_cv_path_RM +if test -n "$RM"; then + { echo "$as_me:$LINENO: result: $RM" >&5 +echo "${ECHO_T}$RM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "rpm", so it can be a program name with args. +set dummy rpm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RPM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RPM in + [\\/]* | ?:[\\/]*) + ac_cv_path_RPM="$RPM" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RPM="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +RPM=$ac_cv_path_RPM +if test -n "$RPM"; then + { echo "$as_me:$LINENO: result: $RPM" >&5 +echo "${ECHO_T}$RPM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "rpmbuild", so it can be a program name with args. +set dummy rpmbuild; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RPMBUILD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RPMBUILD in + [\\/]* | ?:[\\/]*) + ac_cv_path_RPMBUILD="$RPMBUILD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RPMBUILD="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +RPMBUILD=$ac_cv_path_RPMBUILD +if test -n "$RPMBUILD"; then + { echo "$as_me:$LINENO: result: $RPMBUILD" >&5 +echo "${ECHO_T}$RPMBUILD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $STRIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +STRIP=$ac_cv_path_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +{ echo "$as_me:$LINENO: checking whether char is unsigned" >&5 +echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6; } +if test "${ac_cv_c_char_unsigned+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((char) -1) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_char_unsigned=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_char_unsigned=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5 +echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6; } +if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then + cat >>confdefs.h <<\_ACEOF +#define __CHAR_UNSIGNED__ 1 +_ACEOF + +fi + + +if test "$uname" = "IRIX"; then + if test `uname -r` = 6.5; then + STRIP="$STRIP -f -s -k -l -h" + fi +fi + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +if test "${ac_cv_header_strings_h+set}" = set; then + { echo "$as_me:$LINENO: checking for strings.h" >&5 +echo $ECHO_N "checking for strings.h... $ECHO_C" >&6; } +if test "${ac_cv_header_strings_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_strings_h" >&5 +echo "${ECHO_T}$ac_cv_header_strings_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking strings.h usability" >&5 +echo $ECHO_N "checking strings.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <strings.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking strings.h presence" >&5 +echo $ECHO_N "checking strings.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <strings.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: strings.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: strings.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: strings.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: strings.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: strings.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: strings.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: strings.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: strings.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: strings.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: strings.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: strings.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for strings.h" >&5 +echo $ECHO_N "checking for strings.h... $ECHO_C" >&6; } +if test "${ac_cv_header_strings_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_strings_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_strings_h" >&5 +echo "${ECHO_T}$ac_cv_header_strings_h" >&6; } + +fi +if test $ac_cv_header_strings_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_STRINGS_H 1 +_ACEOF + +fi + + +if test "${ac_cv_header_sys_mount_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/mount.h" >&5 +echo $ECHO_N "checking for sys/mount.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_mount_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_mount_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_mount_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/mount.h usability" >&5 +echo $ECHO_N "checking sys/mount.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <sys/mount.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/mount.h presence" >&5 +echo $ECHO_N "checking sys/mount.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/mount.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/mount.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/mount.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/mount.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/mount.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/mount.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/mount.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/mount.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/mount.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/mount.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/mount.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/mount.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/mount.h" >&5 +echo $ECHO_N "checking for sys/mount.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_mount_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_mount_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_mount_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_mount_h" >&6; } + +fi +if test $ac_cv_header_sys_mount_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_MOUNT_H 1 +_ACEOF + +fi + + +if test "${ac_cv_header_sys_param_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/param.h" >&5 +echo $ECHO_N "checking for sys/param.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_param_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_param_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_param_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/param.h usability" >&5 +echo $ECHO_N "checking sys/param.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <sys/param.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/param.h presence" >&5 +echo $ECHO_N "checking sys/param.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/param.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/param.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/param.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/param.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/param.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/param.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/param.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/param.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/param.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/param.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/param.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/param.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/param.h" >&5 +echo $ECHO_N "checking for sys/param.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_param_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_param_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_param_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_param_h" >&6; } + +fi +if test $ac_cv_header_sys_param_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_PARAM_H 1 +_ACEOF + +fi + + +if test "${ac_cv_header_sys_statfs_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/statfs.h" >&5 +echo $ECHO_N "checking for sys/statfs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_statfs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_statfs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_statfs_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/statfs.h usability" >&5 +echo $ECHO_N "checking sys/statfs.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <sys/statfs.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/statfs.h presence" >&5 +echo $ECHO_N "checking sys/statfs.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/statfs.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/statfs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/statfs.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/statfs.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/statfs.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/statfs.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/statfs.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/statfs.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/statfs.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/statfs.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/statfs.h" >&5 +echo $ECHO_N "checking for sys/statfs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_statfs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_statfs_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_statfs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_statfs_h" >&6; } + +fi +if test $ac_cv_header_sys_statfs_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_STATFS_H 1 +_ACEOF + +fi + + +if test "${ac_cv_header_sys_vfs_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/vfs.h" >&5 +echo $ECHO_N "checking for sys/vfs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_vfs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_vfs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_vfs_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/vfs.h usability" >&5 +echo $ECHO_N "checking sys/vfs.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <sys/vfs.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/vfs.h presence" >&5 +echo $ECHO_N "checking sys/vfs.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/vfs.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/vfs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/vfs.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/vfs.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/vfs.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/vfs.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/vfs.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/vfs.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/vfs.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/vfs.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/vfs.h" >&5 +echo $ECHO_N "checking for sys/vfs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_vfs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_vfs_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_vfs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_vfs_h" >&6; } + +fi +if test $ac_cv_header_sys_vfs_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_VFS_H 1 +_ACEOF + +fi + + + + + + + + +for ac_func in strcasecmp strdup strlcat strlcpy strncasecmp +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "$uname" = "HP-UX" -a "$uversion" = "1020"; then + { echo "$as_me:$LINENO: WARNING: Forcing snprintf emulation for HP-UX." >&5 +echo "$as_me: WARNING: Forcing snprintf emulation for HP-UX." >&2;} +else + + +for ac_func in snprintf vsnprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +fi +{ echo "$as_me:$LINENO: checking for library containing gethostname" >&5 +echo $ECHO_N "checking for library containing gethostname... $ECHO_C" >&6; } +if test "${ac_cv_search_gethostname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostname (); +int +main () +{ +return gethostname (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_gethostname=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_gethostname+set}" = set; then + break +fi +done +if test "${ac_cv_search_gethostname+set}" = set; then + : +else + ac_cv_search_gethostname=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_gethostname" >&5 +echo "${ECHO_T}$ac_cv_search_gethostname" >&6; } +ac_res=$ac_cv_search_gethostname +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +if test "x$enable_gui" != xno; then + # Extract the first word of "fltk-config", so it can be a program name with args. +set dummy fltk-config; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_FLTKCONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $FLTKCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_FLTKCONFIG="$FLTKCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_FLTKCONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +FLTKCONFIG=$ac_cv_path_FLTKCONFIG +if test -n "$FLTKCONFIG"; then + { echo "$as_me:$LINENO: result: $FLTKCONFIG" >&5 +echo "${ECHO_T}$FLTKCONFIG" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +else + FLTKCONFIG="" +fi + +if test "x$FLTKCONFIG" = x; then + GUIS="" + GUILIBS="" + INSTALL_GUIS="" + INSTALL_OSX="" + + { echo "$as_me:$LINENO: WARNING: Sorry, setup GUI requires FLTK 1.1.x." >&5 +echo "$as_me: WARNING: Sorry, setup GUI requires FLTK 1.1.x." >&2;} +else + CXXFLAGS="`$FLTKCONFIG --cflags` ${CXXFLAGS}" + GUIS="setup uninst" + GUILIBS="`$FLTKCONFIG --use-images --ldstaticflags`" + INSTALL_GUIS="install-guis" + + if test "$uname" = Darwin; then + GUILIBS="$GUILIBS -framework Security" + INSTALL_OSX="install-osx" + else + INSTALL_OSX="" + fi +fi + + + + + + +case "$uname" in + Darwin* | *BSD | Linux* | SunOS*) + # MacOS X, *BSD, Linux, and Solaris come with gzip standard + cat >>confdefs.h <<\_ACEOF +#define EPM_COMPRESS 1 +_ACEOF + + ;; + + *) + # All other OS's do not. + cat >>confdefs.h <<\_ACEOF +#define EPM_COMPRESS 0 +_ACEOF + + ;; +esac + +if test -n "$GCC"; then + # Add standard optimization options... + if test -z "$OPTIM"; then + OPTIM="-Os" + fi + + # Add useful warning options... + CFLAGS="-Wall -Wformat -Wno-format-y2k -Wunused $CFLAGS" + CXXFLAGS="-Wall -Wformat -Wno-format-y2k -Wunused $CXXFLAGS" + + # See if GCC supports -fno-rtti... + { echo "$as_me:$LINENO: checking if GCC supports -fno-rtti" >&5 +echo $ECHO_N "checking if GCC supports -fno-rtti... $ECHO_C" >&6; } + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + CXXFLAGS="$CXXFLAGS -fno-rtti" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLDCFLAGS" + + # See if GCC supports -fno-exceptions... + { echo "$as_me:$LINENO: checking if GCC supports -fno-exceptions" >&5 +echo $ECHO_N "checking if GCC supports -fno-exceptions... $ECHO_C" >&6; } + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-exceptions" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + CXXFLAGS="$CXXFLAGS -fno-exceptions" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLDCFLAGS" + + # See if we are running HP-UX or Solaris; if so, try the + # -fpermissive option... + case $uname in + SunOS* | HP-UX*) + { echo "$as_me:$LINENO: checking if GCC supports -fpermissive" >&5 +echo $ECHO_N "checking if GCC supports -fpermissive... $ECHO_C" >&6; } + + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fpermissive" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + CXXFLAGS="$CXXFLAGS -fpermissive" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLDCFLAGS" + ;; + + *) + ;; + esac +else + case $uname in + AIX*) + if test -z "$OPTIM"; then + OPTIM="-O2" + fi + ;; + HP-UX*) + if test -z "$OPTIM"; then + OPTIM="+O2" + fi + OPTIM="$OPTIM +DAportable" + ;; + IRIX*) + if test -z "$OPTIM"; then + OPTIM="-O2" + fi + if test $uversion -ge 62; then + OPTIM="$OPTIM -n32 -mips3" + OPTIM="$OPTIM -OPT:Olimit=3000" + OPTIM="-fullwarn -woff 1209,1506,1692 $OPTIM" + else + OPTIM="-fullwarn $OPTIM" + fi + ;; + SunOS*) + # Solaris + if test -z "$OPTIM"; then + OPTIM="-xO4" + fi + ;; + *) + # Running some other operating system; inform the user they + # should contribute the necessary options to + # epm@easysw.com... + echo "Building EPM with default compiler optimizations; contact" + echo "epm@easysw.com with the uname and compiler options needed for" + echo "your platform, or set the CFLAGS and CXXFLAGS environment" + echo "variable before running configure." + ;; + esac +fi + +case $uname in + Darwin* | *BSD*) + ARFLAGS="-rc" + ;; + *) + ARFLAGS="crs" + ;; +esac + + + +if test "$prefix" = "NONE"; then + prefix="/usr" +fi + +if test "$exec_prefix" = "NONE"; then + exec_prefix="$prefix" +fi + +if test "$libdir" = "\${exec_prefix}/lib"; then + libdir="$exec_prefix/lib" +fi + +if test "$datarootdir" = "\${prefix}/share"; then + if test "$prefix" = "/"; then + datarootdir="/usr/share" + else + datarootdir="$prefix/share" + fi +fi + +if test "$datadir" = "\${prefix}/share"; then + if test "$prefix" = "/"; then + datadir="/usr/share" + else + datadir="$prefix/share" + fi +elif test "$datadir" = "\${datarootdir}"; then + datadir="$datarootdir" +fi + +if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"; then + case "$uname" in + *BSD* | Darwin* | Linux*) + # BSD, Darwin (MacOS X), and Linux + mandir="/usr/share/man" + ;; + IRIX*) + # SGI IRIX + mandir="/usr/share/catman/u_man" + ;; + *) + # All others + mandir="/usr/man" + ;; + esac +fi + +if test x$softwaredir = x; then + EPM_SOFTWARE="/etc/software" +else + EPM_SOFTWARE="$softwaredir" +fi + +cat >>confdefs.h <<_ACEOF +#define EPM_SOFTWARE "$EPM_SOFTWARE" +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define EPM_GZIP "$GZIP" +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define EPM_STRIP "$STRIP" +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define EPM_BINDIR "$exec_prefix/bin" +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define EPM_LIBDIR "$libdir/epm" +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define EPM_DATADIR "$datadir/epm" +_ACEOF + + + +if test "x$RPM" != x; then + # It would be nice if Red Hat could make up its mind... + rpmversion="`$RPM --version | awk '{print $3}' | awk -F. '{print $1 * 10000 + $2 * 100 + $3}'`" + + if test $rpmversion -lt 30000; then + cat >>confdefs.h <<_ACEOF +#define EPM_RPMARCH "--buildarch " +_ACEOF + + else + if test $rpmversion -ge 40003; then + cat >>confdefs.h <<_ACEOF +#define EPM_RPMARCH "--target " +_ACEOF + + else + cat >>confdefs.h <<_ACEOF +#define EPM_RPMARCH "--target=" +_ACEOF + + fi + fi +fi + +if test "x$RPMBUILD" != x; then + cat >>confdefs.h <<_ACEOF +#define EPM_RPMBUILD "$RPMBUILD" +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define EPM_RPMTOPDIR 1 +_ACEOF + +else + if test "x$RPM" != x; then + cat >>confdefs.h <<_ACEOF +#define EPM_RPMBUILD "$RPM" +_ACEOF + + else + cat >>confdefs.h <<_ACEOF +#define EPM_RPMBUILD "rpm" +_ACEOF + + fi +fi + +ac_config_files="$ac_config_files Makefile epm.list doc/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "epm.list") CONFIG_FILES="$CONFIG_FILES epm.list" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +VERSION!$VERSION$ac_delim +VERNUMBER!$VERNUMBER$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +ARCHFLAGS!$ARCHFLAGS$ac_delim +OPTIM!$OPTIM$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +RANLIB!$RANLIB$ac_delim +AR!$AR$ac_delim +CHMOD!$CHMOD$ac_delim +CP!$CP$ac_delim +GZIP!$GZIP$ac_delim +HTMLDOC!$HTMLDOC$ac_delim +MKDIR!$MKDIR$ac_delim +NROFF!$NROFF$ac_delim +GROFF!$GROFF$ac_delim +RM!$RM$ac_delim +RPM!$RPM$ac_delim +RPMBUILD!$RPMBUILD$ac_delim +STRIP!$STRIP$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +FLTKCONFIG!$FLTKCONFIG$ac_delim +INSTALL_GUIS!$INSTALL_GUIS$ac_delim +INSTALL_OSX!$INSTALL_OSX$ac_delim +GUIS!$GUIS$ac_delim +GUILIBS!$GUILIBS$ac_delim +ARFLAGS!$ARFLAGS$ac_delim +EPM_SOFTWARE!$EPM_SOFTWARE$ac_delim +EPM_GZIP!$EPM_GZIP$ac_delim +EPM_STRIP!$EPM_STRIP$ac_delim +EPM_BINDIR!$EPM_BINDIR$ac_delim +EPM_LIBDIR!$EPM_LIBDIR$ac_delim +EPM_DATADIR!$EPM_DATADIR$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 81; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..40d22d1 --- /dev/null +++ b/configure.in @@ -0,0 +1,393 @@ +dnl +dnl "$Id: configure.in 780 2007-12-02 22:41:02Z mike $" +dnl +dnl Configuration script for the ESP Package Manager (EPM). +dnl +dnl Copyright 1999-2007 by Easy Software Products, all rights reserved. +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl + +AC_INIT(epm.c) +AC_CONFIG_HEADER(config.h) +AC_PREFIX_DEFAULT(/usr) + +dnl Version number... + +VERSION=4.2 +VERNUMBER=420 +AC_SUBST(VERSION) +AC_SUBST(VERNUMBER) +AC_DEFINE_UNQUOTED(EPM_VERSION, "ESP Package Manager v$VERSION") + +dnl Get the operating system... + +uname=`uname` +uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'` + +if test "$uname" = "IRIX64"; then + uname="IRIX" +fi + +dnl Clear default debugging options and set normal optimization by +dnl default unless the user asks for debugging specifically. + +CFLAGS="${CFLAGS:=}" +CXXFLAGS="${CXXFLAGS:=}" +LDFLAGS="${LDFLAGS:=}" +AC_SUBST(LDFLAGS) + +AC_ARG_WITH(archflags, [ --with-archflags=flags specify architecture flags [[default=none]]], + ARCHFLAGS="$withval", + ARCHFLAGS="${ARCHFLAGS:=}") +AC_SUBST(ARCHFLAGS) + +AC_ARG_WITH(optim, [ --with-optim=flags specify optimization flags [[default=auto]]], + OPTIM="$withval", + OPTIM="${OPTIM:=}") +AC_SUBST(OPTIM) + +AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [[default=no]]], +if eval "test x$enable_debug = xyes"; then + OPTIM="-g $OPTIM" +else + LDFLAGS="$LDFLAGS -s" +fi) + +AC_ARG_ENABLE(gui, [ --enable-gui turn on GUI utilities [[default=auto]]]) + +AC_ARG_WITH(docdir, [ --with-docdir=/dir set directory for documentation + [[default=${datadir}/doc/epm]]], + docdir="$withval", + docdir="\${datadir}/doc/epm") + +AC_SUBST(docdir) + +AC_ARG_WITH(softwaredir, [ --with-softwaredir=/dir set directory for EPM uninstall files and init scripts + [[default=/etc/software]]], + softwaredir="$withval", + softwaredir="") + +dnl Checks for programs... +AC_PROG_CC +AC_PROG_CXX +AC_PROG_RANLIB +AC_PATH_PROG(AR,ar) +AC_PATH_PROG(CHMOD,chmod) +AC_PATH_PROG(CP,cp) +AC_PATH_PROG(GZIP,gzip) +if test x$GZIP = x; then + AC_MSG_ERROR(GNU zip not found but required!) +fi +AC_PATH_PROG(HTMLDOC,htmldoc) +AC_PATH_PROG(MKDIR,mkdir) +AC_PATH_PROG(NROFF,nroff) +if test x$NROFF = x; then + AC_PATH_PROG(GROFF,groff) + if test x$GROFF = x; then + NROFF="echo" + else + NROFF="$GROFF -T ascii" + fi +fi +AC_PATH_PROG(RM,rm) +AC_PATH_PROG(RPM,rpm) +AC_PATH_PROG(RPMBUILD,rpmbuild) +AC_PATH_PROG(STRIP,strip) + +dnl Architecture checks... +AC_C_CONST +AC_C_CHAR_UNSIGNED + +if test "$uname" = "IRIX"; then + if test `uname -r` = 6.5; then + STRIP="$STRIP -f -s -k -l -h" + fi +fi + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_CHECK_HEADER(strings.h,AC_DEFINE(HAVE_STRINGS_H)) +AC_CHECK_HEADER(sys/mount.h,AC_DEFINE(HAVE_SYS_MOUNT_H)) +AC_CHECK_HEADER(sys/param.h,AC_DEFINE(HAVE_SYS_PARAM_H)) +AC_CHECK_HEADER(sys/statfs.h,AC_DEFINE(HAVE_SYS_STATFS_H)) +AC_CHECK_HEADER(sys/vfs.h,AC_DEFINE(HAVE_SYS_VFS_H)) + +dnl Checks for string functions. +AC_CHECK_FUNCS(strcasecmp strdup strlcat strlcpy strncasecmp) +if test "$uname" = "HP-UX" -a "$uversion" = "1020"; then + AC_MSG_WARN(Forcing snprintf emulation for HP-UX.) +else + AC_CHECK_FUNCS(snprintf vsnprintf) +fi +AC_SEARCH_LIBS(gethostname, socket) + +if test "x$enable_gui" != xno; then + AC_PATH_PROG(FLTKCONFIG,fltk-config) +else + FLTKCONFIG="" +fi + +if test "x$FLTKCONFIG" = x; then + GUIS="" + GUILIBS="" + INSTALL_GUIS="" + INSTALL_OSX="" + + AC_MSG_WARN([Sorry, setup GUI requires FLTK 1.1.x.]) +else + CXXFLAGS="`$FLTKCONFIG --cflags` ${CXXFLAGS}" + GUIS="setup uninst" + GUILIBS="`$FLTKCONFIG --use-images --ldstaticflags`" + INSTALL_GUIS="install-guis" + + if test "$uname" = Darwin; then + GUILIBS="$GUILIBS -framework Security" + INSTALL_OSX="install-osx" + else + INSTALL_OSX="" + fi +fi + +AC_SUBST(INSTALL_GUIS) +AC_SUBST(INSTALL_OSX) +AC_SUBST(GUIS) +AC_SUBST(GUILIBS) + +dnl Set the default compression value... +case "$uname" in + Darwin* | *BSD | Linux* | SunOS*) + # MacOS X, *BSD, Linux, and Solaris come with gzip standard + AC_DEFINE(EPM_COMPRESS, 1) + ;; + + *) + # All other OS's do not. + AC_DEFINE(EPM_COMPRESS, 0) + ;; +esac + +dnl Update compiler options... +if test -n "$GCC"; then + # Add standard optimization options... + if test -z "$OPTIM"; then + OPTIM="-Os" + fi + + # Add useful warning options... + CFLAGS="-Wall -Wformat -Wno-format-y2k -Wunused $CFLAGS" + CXXFLAGS="-Wall -Wformat -Wno-format-y2k -Wunused $CXXFLAGS" + + # See if GCC supports -fno-rtti... + AC_MSG_CHECKING(if GCC supports -fno-rtti) + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti" + AC_TRY_COMPILE(,, + CXXFLAGS="$CXXFLAGS -fno-rtti" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CFLAGS="$OLDCFLAGS" + + # See if GCC supports -fno-exceptions... + AC_MSG_CHECKING(if GCC supports -fno-exceptions) + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-exceptions" + AC_TRY_COMPILE(,, + CXXFLAGS="$CXXFLAGS -fno-exceptions" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CFLAGS="$OLDCFLAGS" + + # See if we are running HP-UX or Solaris; if so, try the + # -fpermissive option... + case $uname in + SunOS* | HP-UX*) + AC_MSG_CHECKING(if GCC supports -fpermissive) + + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fpermissive" + AC_TRY_COMPILE(,, + CXXFLAGS="$CXXFLAGS -fpermissive" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CFLAGS="$OLDCFLAGS" + ;; + + *) + ;; + esac +else + case $uname in + AIX*) + if test -z "$OPTIM"; then + OPTIM="-O2" + fi + ;; + HP-UX*) + if test -z "$OPTIM"; then + OPTIM="+O2" + fi + OPTIM="$OPTIM +DAportable" + ;; + IRIX*) + if test -z "$OPTIM"; then + OPTIM="-O2" + fi + if test $uversion -ge 62; then + OPTIM="$OPTIM -n32 -mips3" + OPTIM="$OPTIM -OPT:Olimit=3000" + OPTIM="-fullwarn -woff 1209,1506,1692 $OPTIM" + else + OPTIM="-fullwarn $OPTIM" + fi + ;; + SunOS*) + # Solaris + if test -z "$OPTIM"; then + OPTIM="-xO4" + fi + ;; + *) + # Running some other operating system; inform the user they + # should contribute the necessary options to + # epm@easysw.com... + echo "Building EPM with default compiler optimizations; contact" + echo "epm@easysw.com with the uname and compiler options needed for" + echo "your platform, or set the CFLAGS and CXXFLAGS environment" + echo "variable before running configure." + ;; + esac +fi + +dnl Flags for "ar" command... +case $uname in + Darwin* | *BSD*) + ARFLAGS="-rc" + ;; + *) + ARFLAGS="crs" + ;; +esac + +AC_SUBST(ARFLAGS) + +dnl Fix "prefix" variable if it hasn't been specified... +if test "$prefix" = "NONE"; then + prefix="/usr" +fi + +dnl Fix "exec_prefix" variable if it hasn't been specified... +if test "$exec_prefix" = "NONE"; then + exec_prefix="$prefix" +fi + +dnl Fix "libdir" variable if it hasn't been specified... +if test "$libdir" = "\${exec_prefix}/lib"; then + libdir="$exec_prefix/lib" +fi + +dnl Fix "datarootdir" variable if it hasn't been specified... +if test "$datarootdir" = "\${prefix}/share"; then + if test "$prefix" = "/"; then + datarootdir="/usr/share" + else + datarootdir="$prefix/share" + fi +fi + +dnl Fix "datadir" variable if it hasn't been specified... +if test "$datadir" = "\${prefix}/share"; then + if test "$prefix" = "/"; then + datadir="/usr/share" + else + datadir="$prefix/share" + fi +elif test "$datadir" = "\${datarootdir}"; then + datadir="$datarootdir" +fi + +dnl Fix "mandir" variable if it hasn't been specified... +if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"; then + case "$uname" in + *BSD* | Darwin* | Linux*) + # BSD, Darwin (MacOS X), and Linux + mandir="/usr/share/man" + ;; + IRIX*) + # SGI IRIX + mandir="/usr/share/catman/u_man" + ;; + *) + # All others + mandir="/usr/man" + ;; + esac +fi + +dnl EPM_SOFTWARE needs special attention for the default location... +if test x$softwaredir = x; then + EPM_SOFTWARE="/etc/software" +else + EPM_SOFTWARE="$softwaredir" +fi + +AC_DEFINE_UNQUOTED(EPM_SOFTWARE, "$EPM_SOFTWARE") +AC_SUBST(EPM_SOFTWARE) + +AC_DEFINE_UNQUOTED(EPM_GZIP, "$GZIP") +AC_SUBST(EPM_GZIP) + +AC_DEFINE_UNQUOTED(EPM_STRIP, "$STRIP") +AC_SUBST(EPM_STRIP) + +AC_DEFINE_UNQUOTED(EPM_BINDIR, "$exec_prefix/bin") +AC_SUBST(EPM_BINDIR) + +AC_DEFINE_UNQUOTED(EPM_LIBDIR, "$libdir/epm") +AC_SUBST(EPM_LIBDIR) + +AC_DEFINE_UNQUOTED(EPM_DATADIR, "$datadir/epm") +AC_SUBST(EPM_DATADIR) + +dnl Figure out the right option to use for the RPM build architecture... +if test "x$RPM" != x; then + # It would be nice if Red Hat could make up its mind... + rpmversion="`$RPM --version | awk '{print $3}' | awk -F. '{print $1 * 10000 + $2 * 100 + $3}'`" + + if test $rpmversion -lt 30000; then + AC_DEFINE_UNQUOTED(EPM_RPMARCH, "--buildarch ") + else + if test $rpmversion -ge 40003; then + AC_DEFINE_UNQUOTED(EPM_RPMARCH, "--target ") + else + AC_DEFINE_UNQUOTED(EPM_RPMARCH, "--target=") + fi + fi +fi + +if test "x$RPMBUILD" != x; then + AC_DEFINE_UNQUOTED(EPM_RPMBUILD, "$RPMBUILD") + AC_DEFINE(EPM_RPMTOPDIR) +else + if test "x$RPM" != x; then + AC_DEFINE_UNQUOTED(EPM_RPMBUILD, "$RPM") + else + AC_DEFINE_UNQUOTED(EPM_RPMBUILD, "rpm") + fi +fi + +dnl Output the makefile, list file, and config header... +AC_OUTPUT(Makefile epm.list doc/Makefile) + +dnl +dnl End of "$Id: configure.in 780 2007-12-02 22:41:02Z mike $". +dnl @@ -0,0 +1,602 @@ +/* + * "$Id: deb.c 833 2010-12-30 00:00:50Z mike $" + * + * Debian package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_deb() - Make a Debian software distribution package. + * make_subpackage() - Make a subpackage... + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static int make_subpackage(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform, + const char *subpackage); + + +/* + * 'make_deb()' - Make a Debian software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_deb(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i; /* Looping var */ + tarf_t *tarfile; /* Distribution tar file */ + char name[1024], /* Full product name */ + filename[1024]; /* File to archive */ + + + if (make_subpackage(prodname, directory, platname, dist, platform, NULL)) + return (1); + + for (i = 0; i < dist->num_subpackages; i ++) + if (make_subpackage(prodname, directory, platname, dist, platform, + dist->subpackages[i])) + return (1); + + /* + * Build a compressed tar file to hold all of the subpackages... + */ + + if (dist->num_subpackages) + { + /* + * Figure out the full name of the distribution... + */ + + if (dist->release[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, + dist->release); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + if (platname[0]) + { + strlcat(name, "-", sizeof(name)); + strlcat(name, platname, sizeof(name)); + } + + /* + * Create a compressed tar file... + */ + + snprintf(filename, sizeof(filename), "%s/%s.deb.tgz", directory, name); + + if ((tarfile = tar_open(filename, 1)) == NULL) + return (1); + + /* + * Archive the main package and subpackages... + */ + + if (tar_package(tarfile, "deb", prodname, directory, platname, dist, NULL)) + { + tar_close(tarfile); + return (1); + } + + for (i = 0; i < dist->num_subpackages; i ++) + { + if (tar_package(tarfile, "deb", prodname, directory, platname, dist, + dist->subpackages[i])) + { + tar_close(tarfile); + return (1); + } + } + + tar_close(tarfile); + } + + /* + * Remove temporary files... + */ + + if (!KeepFiles && dist->num_subpackages) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + /* + * Remove .deb files since they are now in a .tgz file... + */ + + unlink_package("deb", prodname, directory, platname, dist, NULL); + + for (i = 0; i < dist->num_subpackages; i ++) + unlink_package("deb", prodname, directory, platname, dist, + dist->subpackages[i]); + } + + return (0); +} + + +/* + * 'make_subpackage()' - Make a subpackage... + */ + +static int /* O - 0 = success, 1 = fail */ +make_subpackage(const char *prodname, + /* I - Product short name */ + const char *directory, + /* I - Directory for distribution files */ + const char *platname, + /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform, + /* I - Platform information */ + const char *subpackage) + /* I - Subpackage */ +{ + int i, j; /* Looping vars */ + const char *header; /* Dependency header string */ + FILE *fp; /* Control file */ + char prodfull[255], /* Full name of product */ + name[1024], /* Full product name */ + filename[1024]; /* Destination filename */ + command_t *c; /* Current command */ + depend_t *d; /* Current dependency */ + file_t *file; /* Current distribution file */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + const char *runlevels, /* Run levels */ + *rlptr; /* Pointer into runlevels */ + static const char *depends[] = /* Dependency names */ + { + "Depends:", + "Conflicts:", + "Replaces:", + "Provides:" + }; + + + /* + * Figure out the full name of the distribution... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + /* + * Then the subdirectory name... + */ + + if (dist->release[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version, + dist->release); + else + snprintf(name, sizeof(name), "%s-%s", prodfull, dist->version); + + if (platname[0]) + { + strlcat(name, "-", sizeof(name)); + strlcat(name, platname, sizeof(name)); + } + + if (Verbosity) + printf("Creating Debian %s distribution...\n", name); + + /* + * Write the control file for DPKG... + */ + + if (Verbosity) + puts("Creating control file..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, name); + mkdir(filename, 0777); + strlcat(filename, "/DEBIAN", sizeof(filename)); + mkdir(filename, 0777); + chmod(filename, 0755); + + strlcat(filename, "/control", sizeof(filename)); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create control file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fprintf(fp, "Package: %s\n", prodfull); + if (dist->release[0]) + fprintf(fp, "Version: %s-%s\n", dist->version, dist->release); + else + fprintf(fp, "Version: %s\n", dist->version); + fprintf(fp, "Maintainer: %s\n", dist->vendor); + + /* + * The Architecture attribute needs to match the uname info + * (which we change in get_platform to a common name) + */ + + if (!strcmp(platform->machine, "intel")) + fputs("Architecture: i386\n", fp); + else if (!strcmp(platform->machine, "ppc")) + fputs("Architecture: powerpc\n", fp); + else + fprintf(fp, "Architecture: %s\n", platform->machine); + + fprintf(fp, "Description: %s\n", dist->product); + fprintf(fp, " Copyright: %s\n", dist->copyright); + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + fprintf(fp, " %s\n", dist->descriptions[i].description); + + for (j = DEPEND_REQUIRES; j <= DEPEND_PROVIDES; j ++) + { + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == j && d->subpackage == subpackage) + break; + + if (i) + { + for (header = depends[j]; i > 0; i --, d ++, header = ",") + if (d->type == j && d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + fprintf(fp, "%s %s", header, prodname); + else + fprintf(fp, "%s %s", header, d->product); + + if (d->vernumber[0] == 0) + { + if (d->vernumber[1] < INT_MAX) + fprintf(fp, " (<= %s)", d->version[1]); + } + else + { + if (d->vernumber[1] < INT_MAX) + fprintf(fp, " (>= %s, <= %s)", d->version[0], d->version[1]); + else + fprintf(fp, " (>= %s)", d->version[0]); + } + } + + putc('\n', fp); + } + } + + fclose(fp); + + /* + * Write the preinst file for DPKG... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + break; + + if (i) + { + if (Verbosity) + puts("Creating preinst script..."); + + snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/preinst", directory, name); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + + /* + * Write the postinst file for DPKG... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + if (Verbosity) + puts("Creating postinst script..."); + + snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/postinst", directory, name); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + runlevels = get_runlevels(file, "02345"); + + fprintf(fp, "update-rc.d %s start %02d", file->dst, + get_start(file, 99)); + + for (rlptr = runlevels; isdigit(*rlptr & 255); rlptr ++) + if (*rlptr != '0') + fprintf(fp, " %c", *rlptr); + + if (strchr(runlevels, '0') != NULL) + fprintf(fp, " . stop %02d 0", get_stop(file, 0)); + + fputs(" . >/dev/null\n", fp); + fprintf(fp, "/etc/init.d/%s start\n", file->dst); + } + + fclose(fp); + } + + /* + * Write the prerm file for DPKG... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + if (Verbosity) + puts("Creating prerm script..."); + + snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/prerm", directory, name); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + fprintf(fp, "/etc/init.d/%s stop\n", file->dst); + + fclose(fp); + } + + /* + * Write the postrm file for DPKG... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + if (Verbosity) + puts("Creating postrm script..."); + + snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/postrm", directory, name); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fputs("if [ purge = \"$1\" ]; then\n", fp); + fprintf(fp, " update-rc.d %s remove >/dev/null\n", file->dst); + fputs("fi\n", fp); + } + + fclose(fp); + } + + /* + * Write the conffiles file for DPKG... + */ + + if (Verbosity) + puts("Creating conffiles..."); + + snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/conffiles", directory, name); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage) + fprintf(fp, "%s\n", file->dst); + else if (tolower(file->type) == 'i' && file->subpackage == subpackage) + fprintf(fp, "/etc/init.d/%s\n", file->dst); + + fclose(fp); + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + if (file->subpackage != subpackage) + continue; + + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, name, + file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'i' : + snprintf(filename, sizeof(filename), "%s/%s/etc/init.d/%s", + directory, name, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'd' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, name, + file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + case 'l' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, name, + file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution from the spec file... + */ + + if (Verbosity) + printf("Building Debian %s binary distribution...\n", name); + + if (run_command(directory, "dpkg --build %s", name)) + return (1); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + printf("Removing temporary %s distribution files...\n", name); + + snprintf(filename, sizeof(filename), "%s/%s", directory, name); + unlink_directory(filename); + } + + return (0); +} + + +/* + * End of "$Id: deb.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/default.xpm b/default.xpm new file mode 100644 index 0000000..35499c2 --- /dev/null +++ b/default.xpm @@ -0,0 +1,163 @@ +/* XPM */ +static char * default_xpm[] = { +"96 96 64 1", +" c None", +". c #000100", +"+ c #0C0E0A", +"@ c #1C1C19", +"# c #231C0C", +"$ c #312714", +"% c #2C2B27", +"& c #3B2D0F", +"* c #403728", +"= c #393A38", +"- c #534117", +"; c #504430", +"> c #474946", +", c #5B482B", +"' c #634D1C", +") c #704B0B", +"! c #5F523D", +"~ c #555754", +"{ c #7B562C", +"] c #6F5F40", +"^ c #815E18", +"/ c #616260", +"( c #7B6421", +"_ c #816435", +": c #8A6620", +"< c #8E6A1C", +"[ c #8A6B23", +"} c #856E4F", +"| c #727371", +"1 c #946F2F", +"2 c #9C7B29", +"3 c #7F817E", +"4 c #9C824C", +"5 c #A18240", +"6 c #98835F", +"7 c #A9862F", +"8 c #AA8B3C", +"9 c #8E908D", +"0 c #B09241", +"a c #B29451", +"b c #B6994D", +"c c #BB9D52", +"d c #9FA09D", +"e c #B8A173", +"f c #C0A35E", +"g c #BFA56D", +"h c #ABADAA", +"i c #CEB069", +"j c #B8B29F", +"k c #C3B28A", +"l c #B2B4B1", +"m c #CFB681", +"n c #BCBEBB", +"o c #DCBC7C", +"p c #CCBFA3", +"q c #C8CAC6", +"r c #ECCE8C", +"s c #CFD2CE", +"t c #D7D9D6", +"u c #FDDE9B", +"v c #DFE1DE", +"w c #E9EBE7", +"x c #F1F3F0", +"y c #FDFFFC", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" q9~==n ", +" q9~@.....% ", +" q9~@....*}eu#.q ", +" q9~@....*}eurroi].3 t>+/ ", +" q9~@...+;}euuoofffffa.% t%...~ ", +" q9~@...+;6murroffffffffff#.q t%.!m+.~ ", +" q9~@...+;6muromfffffffgfgffff].3 t%.!uum+.~ ", +" q9~@...@;6muroiffff]@#;}afffffgffa.% t%.!uuuum..~ ", +" 9~@...@!6muroifgfffffa......#;_gfffff#.q t%.!uuuuuum+.~ ", +" 3..@!6rurrofffffffgfff}./vd/@+...#;_gf].| t%.!uuuuuuuum..~ ", +" =.euroffffff4;$#$$$%$$#.dyyyyvd/@....#$.@ t%.!uuuuuuuuuum+.~ ", +" |.}offffffff+...........vyyyyyyyyvd/@....%@.!uuuuuuuuuuuum..~ ", +" h.;rffffffff..hhhhhhhd.@yyyyyyyyyyyyyvd/@....%}6upuuuuuuuum+.~ ", +" +.uigfgffgf..wxvxvxvd./yyyyyyyyyyyyyyyyyvd/@....*!epuuuuuum..~ ", +" >.eofffffff..vvxvxvx/.dyyyyyyyyyyyyyyyyyyyyyvd/%....%}kuuuum+.~ ", +" 3.]rfffffff..xvxvxvx%.vyyyyyyyyyyyyyyyyyyyyyyyyyvd|%...uuuuum..~ ", +" q.%rfgfffff..vxvxxxv.@yyxqswyyyyyyyyyyyyyyyyyyyyyyyyx%.euuuuum+.~ ", +" @.riffffff..xxqnnn9./yyxllhlntwyyyyyyyyyyyyyyyyyyyyy+.uuuuuuum..~ ", +" ~.eogfgfff..vxllhl>.dyyyvtnlllhlnswyyyyyyyyyyyyyyyys.=uuuuuuuum+.~ ", +" d.!rffffff..xvvvvv%.vyyyyyyyvtnlllhlntwyyyyyyyyyyyy9.}uuuuuuuuum..~ ", +" t.@uffgfff..xxtssq.@yyxqqtwyyyyyxtnlllhlnswyyyyyyyy~.kuuuuuuuuuum+.~ ", +" %.mifffff..xxhll|./yyxhllllqtwyyyyyvtnlllhlntwyyyy+.uupuuuuuuuuum..9 ", +" thhhhhhhhh~.6offfb0..xxvts/.dyyyxvsnllllhqtwyyyyyxtnlllhnyys.*uuupuuuuuuuuum+.9 ", +" %...........!r88287..xxtss%.tyyyyyyyxvsnlllllqtwyyyyyvtqsyy9.}uuuuuuupuuuuuum..n ", +" h.#,---------{4877<:..xxlld.@yxwlnsvxyyyyxvsnllllhqtwyyyyyyy>.kuuuuuuuuuuuuuuu;.h ", +" q..go077778882{{^)))..xxtt9.~xxxllllllqtxyyyyxvsnlllllqtxyyy+.uuuuuuuuuuuuuuu!..t ", +" 9.+mr788877788_{)))..xxxv/.9xxxxvtqllllllqtxyyyyxvsnlllnyys.*uuuuuuuuupuuuu!.+n ", +" 9.+mr777777782_{')..xxll%.qvxvxxxxxxtqnlllllqtxyyyyxvqvyy9.}uuuuuuuuuuuuu~..n ", +" 9.+mr728872782{{)..xxsl.@vxthhnqtxxxxxxtqllllllqtxyyyyyy~.epuuuxuuuuuuu!..n ", +" 9.+er778787882_{..xxxd.~vvvnlllhhlqtvxxxxxtqnlllllqvyyy+.fouuuuuuuuuu/..q ", +" 9..6r778787778{,.xyl>.9ttvvttqnlllllnqtxxxxxxtqllllyyq.#afguuuuuuuu!.+n ", +" 9..6r777788787{{xxq%.nttttttvvvtqnllllhlqtxxxxxxttxx9.&)afguuuuxu!..n ", +" 9+.6r828777788{}xv.@stshllnqtvvtvvtqnllhhhlqtxxxxxx>.-^)afeuuuu!..n ", +" 9..6r778277888{63.>sstnllllhlnqsttvvvtqnlllhhlsxxx+.)))^afguu!.........+/ ", +" 9.+6r877887778{,.3qqqqssnnllllllnqtvvvvvtqnllhxvn.#)))))afo!............n ", +" 9..6r077778788{{dqqnnqsqssqqnlllhllnqttvvvvttvv3.&))))^5fffffffioru4;@.h ", +" 9..ir772878778{}nnllllnnqqqqssnnllllllnqtvtvvv>.-^1afffffffoour6!@...= ", +" =.)ir877778888{}nnlllllllnnqqssqqqnllllllnvvt$,affffffgouue}%...+>9q ", +" =.^)fu087877778{}lnnnnlllllllnnqqqqsqqnlllpkgfffffioourg;....=|n ", +" =.:^)fu077778788{}llnnnnnnlllllllnnqqqpmgffffffoorumf11{.@/dt ", +" =.<:))fu028778787{}lllnnlnnnnnlllljegfgffffioruoga^1^:^'.| ", +" =.8<1^)fu072777788{}lllnlnnlnnjkgfffffffoouuoa1:::::_::'.| ", +" =.782:^)au087878778{}dlhlhjpefffffffioruog1^^1:1^1:::11^.| ", +" =.088<1^)ai878788788{}npmofooooiooouroa1:1:1_^::1_:2278(.| ", +" =.70802<^)^)))))))))){aooooooomooog1{1:::::[:1[[2772787(.| ", +" =.008082<<<<<<<<1<<1i1<1^^^^1^11^11::::1_[1[25787888782(.| ", +" =.800008222222222222r1:7211::::::::11[[[222877772777777(.| ", +" =.8080b0022222222280r1:8821:1_1:1[[[1182887878777778788(.| ", +" =.08b08b888227277b0cr1<77772[:[[1[587777772787888827877(.| ", +" =.b8b08cb0882728bba0r1<788878[5777787887787777777787728(.| ", +" =.800808b8c888bc8c0cr1<87778777887778772878727777877877(.| ", +" =.5c8cc8c00008bbacaco1<77777877728777787772888287727872(.| ", +" /.#8a08c8bcbcc8c000cr1<82878727877872877877777777887778(.| ", +" ~.#500c8c8abaccccccr1<77827787877877787887778787787878^.| ", +" ~.#5c8cac0c08ca8car1<28777877287787872778287277772787(.| ", +" ~.#5c00cacccccc0ar1<77787787782782777777778788778728(.| ", +" /.#5ccc00aaacaccr1[78872877777777788878787277887877(.| ", +" ~.#5ccc0ccc0ccar1[77777788788778772778727777277878(.| ", +" ~.#5acc0ccfaccr[[77887272872887777287778887777727(.| ", +" ~.#accca0cccar1<27788787787728870728777787827787(.| ", +" ~.#5cccacaccr1[77277777777787787787877728778827(.| ", +" ~.#5ccccffar1[87778788287777728777828778877788^.| ", +" /.#accfcccr[[77887727878728787287777777777[-#..3 ", +" ~.#acaffar1<8727877777887777078288787('$+..../t ", +" ~.#accccr([7778778772772877727022'&+....>3n ", +" ~.#afffr1<877287887770788272(&+....=|h ", +" ~.#aafr[[78787727887722(-#....%/dt ", +" ~.#afr1<2777877728(-#....@~dt ", +" ~.#ar[[787777(-&....+~9q ", +" ~.#m:<78('$+...+>3n ", +" ~.#('&++...=|n ", +" ~.....%/h ", +" |=/dt ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; @@ -0,0 +1,2398 @@ +/* + * "$Id: dist.c 843 2010-12-31 02:18:18Z mike $" + * + * Distribution functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * add_command() - Add a command to the distribution... + * add_depend() - Add a dependency to the distribution... + * add_description() - Add a description to the distribution. + * add_file() - Add a file to the distribution. + * add_subpackage() - Add a subpackage to the distribution. + * find_subpackage() - Find a subpackage in the distribution. + * free_dist() - Free memory used by a distribution. + * getoption() - Get an option from a file. + * get_platform() - Get the operating system information... + * get_runlevels() - Get the run levels for the specified init script. + * get_start() - Get the start number for an init script. + * get_stop() - Get the stop number for an init script. + * new_dist() - Create a new, empty software distribution. + * read_dist() - Read a software distribution. + * sort_dist_files() - Sort the files in the distribution. + * write_dist() - Write a distribution list file... + * compare_files() - Compare the destination filenames. + * expand_name() - Expand a filename with environment variables. + * get_file() - Read a file into a string... + * get_inline() - Read inline lines into a string... + * get_line() - Get a line from a file, filtering for uname + * lines... + * get_string() - Get a delimited string from a line. + * patmatch() - Pattern matching... + * sort_subpackages() - Compare two subpackage names. + * update_architecture() - Normalize the machine architecture name. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" +#include <pwd.h> + + +/* + * Some versions of Solaris don't define gethostname()... + */ + +#ifdef __sun +extern int gethostname(char *, int); +#endif /* __sun */ + + +/* + * Local functions... + */ + +static int compare_files(const file_t *f0, const file_t *f1); +static void expand_name(char *buffer, char *name, size_t bufsize, int warn); +static char *get_file(const char *filename, char *buffer, size_t size); +static char *get_inline(const char *term, FILE *fp, char *buffer, + size_t size); +static char *get_line(char *buffer, int size, FILE *fp, + struct utsname *platform, const char *format, + int *skip); +static char *get_string(char **src, char *dst, size_t dstsize); +static int patmatch(const char *, const char *); +static int sort_subpackages(char **a, char **b); +static void update_architecture(char *buffer, size_t bufsize); + + +/* + * Conditional "skip" bits... + */ + +#define SKIP_SYSTEM 1 /* Not the right system */ +#define SKIP_FORMAT 2 /* Not the right format */ +#define SKIP_ARCH 4 /* Not the right architecture */ +#define SKIP_IF 8 /* Set if the current #if was not satisfied */ +#define SKIP_IFACTIVE 16 /* Set if we're in an #if */ +#define SKIP_IFSAT 32 /* Set if an #if statement has been satisfied */ +#define SKIP_MASK 15 /* Bits to look at */ + + +/* + * 'add_command()' - Add a command to the distribution... + */ + +void +add_command(dist_t *dist, /* I - Distribution */ + FILE *fp, /* I - Distribution file */ + int type, /* I - Command type */ + const char *command, /* I - Command string */ + const char *subpkg, /* I - Subpackage */ + const char *section) /* I - Literal text section */ +{ + command_t *temp; /* New command */ + char buf[16384]; /* File import buffer */ + + + if (!strncmp(command, "<<", 2)) + { + for (command += 2; isspace(*command & 255); command ++); + + command = get_inline(command, fp, buf, sizeof(buf)); + } + else if (command[0] == '<' && command[1]) + { + for (command ++; isspace(*command & 255); command ++); + + command = get_file(command, buf, sizeof(buf)); + } + + if (!command) + return; + + if (dist->num_commands == 0) + temp = malloc(sizeof(command_t)); + else + temp = realloc(dist->commands, (dist->num_commands + 1) * sizeof(command_t)); + + if (!temp) + { + perror("epm: Out of memory allocating a command"); + return; + } + + dist->commands = temp; + temp += dist->num_commands; + temp->type = type; + temp->command = strdup(command); + if (!temp->command) + { + perror("epm: Out of memory duplicating a command string"); + return; + } + temp->subpackage = subpkg; + if (section && *section) + { + temp->section = strdup(section); + if (!temp->section) + { + perror("epm: Out of memory duplicating a literal section"); + free(temp->command); + return; + } + } + else + temp->section = NULL; + + dist->num_commands ++; +} + + +/* + * 'add_depend()' - Add a dependency to the distribution... + */ + +void +add_depend(dist_t *dist, /* I - Distribution */ + int type, /* I - Type of dependency */ + const char *line, /* I - Line from file */ + const char *subpkg) /* I - Subpackage */ +{ + int i; /* Looping var */ + depend_t *temp; /* New dependency */ + char *ptr; /* Pointer into string */ + const char *lineptr; /* Temporary pointer into line */ + + + /* + * Allocate memory for the dependency... + */ + + if (dist->num_depends == 0) + temp = malloc(sizeof(depend_t)); + else + temp = realloc(dist->depends, (dist->num_depends + 1) * sizeof(depend_t)); + + if (temp == NULL) + { + perror("epm: Out of memory allocating a dependency"); + return; + } + + dist->depends = temp; + temp += dist->num_depends; + dist->num_depends ++; + + /* + * Initialize the dependency record... + */ + + memset(temp, 0, sizeof(depend_t)); + + temp->type = type; + temp->subpackage = subpkg; + + /* + * Get the product name string... + */ + + for (ptr = temp->product; *line && !isspace(*line & 255); line ++) + if (ptr < (temp->product + sizeof(temp->product) - 1)) + *ptr++ = *line; + + while (isspace(*line & 255)) + line ++; + + /* + * Get the version strings, if any... + */ + + for (i = 0; *line && i < 2; i ++) + { + /* + * Handle <version, >version, etc. + */ + + if (!isalnum(*line & 255)) + { + if (*line == '<' && i == 0) + { + strcpy(temp->version[0], "0.0"); + i ++; + } + + while (!isdigit(*line & 255) && *line) + line ++; + } + + if (!*line) + break; + + /* + * Grab the version string... + */ + + for (ptr = temp->version[i]; *line && !isspace(*line & 255); line ++) + if (ptr < (temp->version[i] + sizeof(temp->version[i]) - 1)) + *ptr++ = *line; + + while (isspace(*line & 255)) + line ++; + + /* + * Get the version number, if any... + */ + + for (lineptr = line; isdigit(*lineptr & 255); lineptr ++); + + if (!*line || (!isspace(*lineptr & 255) && *lineptr)) + { + /* + * No version number specified, or the next number is a version + * string... + */ + + temp->vernumber[i] = get_vernumber(temp->version[i]); + } + else + { + /* + * Grab the version number directly from the line... + */ + + temp->vernumber[i] = atoi(line); + + for (line = lineptr; isspace(*line & 255); line ++); + } + } + + /* + * Handle assigning default values based on the number of version numbers... + */ + + switch (i) + { + case 0 : + strcpy(temp->version[0], "0.0"); + /* fall through to set max version number */ + case 1 : + strcpy(temp->version[1], "999.99.99p99"); + temp->vernumber[1] = INT_MAX; + break; + } +} + + +/* + * 'add_description()' - Add a description to the distribution. + */ + +void +add_description(dist_t *dist, /* I - Distribution */ + FILE *fp, /* I - Source file */ + const char *description,/* I - Description string */ + const char *subpkg) /* I - Subpackage name */ +{ + description_t *temp; /* Temporary description array */ + char buf[16384]; /* File import buffer */ + + + if (!strncmp(description, "<<", 2)) + { + for (description += 2; isspace(*description & 255); description ++); + + description = get_inline(description, fp, buf, sizeof(buf)); + } + else if (description[0] == '<' && description[1]) + { + for (description ++; isspace(*description & 255); description ++); + + description = get_file(description, buf, sizeof(buf)); + } + + if (description == NULL) + return; + + if (dist->num_descriptions == 0) + temp = malloc(sizeof(description_t)); + else + temp = realloc(dist->descriptions, + (dist->num_descriptions + 1) * sizeof(description_t)); + + if (temp == NULL) + { + perror("epm: Out of memory adding description"); + return; + } + + dist->descriptions = temp; + temp += dist->num_descriptions; + dist->num_descriptions ++; + + temp->subpackage = subpkg; + + if ((temp->description = strdup(description)) == NULL) + perror("epm: Out of memory duplicating description"); +} + + +/* + * 'add_file()' - Add a file to the distribution. + */ + +file_t * /* O - New file */ +add_file(dist_t *dist, /* I - Distribution */ + const char *subpkg) /* I - Subpackage name */ +{ + file_t *file; /* New file */ + + + if (dist->num_files == 0) + dist->files = (file_t *)malloc(sizeof(file_t)); + else + dist->files = (file_t *)realloc(dist->files, sizeof(file_t) * + (dist->num_files + 1)); + + file = dist->files + dist->num_files; + dist->num_files ++; + + file->subpackage = subpkg; + + return (file); +} + + +/* + * 'add_subpackage()' - Add a subpackage to the distribution. + */ + +char * /* O - Subpackage pointer */ +add_subpackage(dist_t *dist, /* I - Distribution */ + const char *subpkg) /* I - Subpackage name */ +{ + char **temp, /* Temporary array pointer */ + *s; /* Subpackage pointer */ + + + if (dist->num_subpackages == 0) + temp = malloc(sizeof(char *)); + else + temp = realloc(dist->subpackages, + (dist->num_subpackages + 1) * sizeof(char *)); + + if (temp == NULL) + return (NULL); + + dist->subpackages = temp; + temp += dist->num_subpackages; + dist->num_subpackages ++; + + *temp = s = strdup(subpkg); + + if (dist->num_subpackages > 1) + qsort(dist->subpackages, (size_t)dist->num_subpackages, sizeof(char *), + (int (*)(const void *, const void *))sort_subpackages); + + /* + * Return the new string... + */ + + return (s); +} + + +/* + * 'find_subpackage()' - Find a subpackage in the distribution. + */ + +char * /* O - Subpackage pointer */ +find_subpackage(dist_t *dist, /* I - Distribution */ + const char *subpkg) /* I - Subpackage name */ +{ + char **match; /* Matching subpackage */ + + + if (!subpkg || !*subpkg) + return (NULL); + + if (dist->num_subpackages > 0) + match = bsearch(&subpkg, dist->subpackages, (size_t)dist->num_subpackages, + sizeof(char *), + (int (*)(const void *, const void *))sort_subpackages); + else + match = NULL; + + if (match != NULL) + return (*match); + else + return (add_subpackage(dist, subpkg)); +} + + +/* + * 'free_dist()' - Free memory used by a distribution. + */ + +void +free_dist(dist_t *dist) /* I - Distribution to free */ +{ + int i; /* Looping var */ + + + if (dist->num_files > 0) + free(dist->files); + + for (i = 0; i < dist->num_descriptions; i ++) + free(dist->descriptions[i].description); + + if (dist->num_descriptions) + free(dist->descriptions); + + for (i = 0; i < dist->num_subpackages; i ++) + free(dist->subpackages[i]); + + if (dist->num_subpackages) + free(dist->subpackages); + + for (i = 0; i < dist->num_commands; i ++) + { + free(dist->commands[i].command); + if (dist->commands[i].section) + free(dist->commands[i].section); + } + + if (dist->num_commands) + free(dist->commands); + + if (dist->num_depends) + free(dist->depends); + + free(dist); +} + + + +/* + * 'getoption()' - Get an option from a file. + */ + +const char * /* O - Value */ +get_option(file_t *file, /* I - File */ + const char *name, /* I - Name of option */ + const char *defval) /* I - Default value of option */ +{ + char *ptr; /* Pointer to option */ + static char option[256]; /* Copy of file option */ + + + /* + * See if the option exists... + */ + + snprintf(option, sizeof(option), "%s(", name); + + if ((ptr = strstr(file->options, option)) == NULL) + return (defval); + + /* + * Yes, copy the value and truncate at the first ")"... + */ + + ptr += strlen(option); + strcpy(option, ptr); /* option and file->options are of equal size */ + + if ((ptr = strchr(option, ')')) != NULL) + { + *ptr = '\0'; + return (option); + } + else + return (defval); +} + + + + +/* + * 'get_platform()' - Get the operating system information... + */ + +void +get_platform(struct utsname *platform) /* O - Platform info */ +{ + char *temp; /* Temporary pointer */ +#ifdef __APPLE__ + FILE *fp; /* SystemVersion.plist file */ + char line[1024], /* Line from file */ + *ptr; /* Pointer into line */ + int major, minor; /* Major and minor release numbers */ +#endif /* __APPLE__ */ + + + /* + * Get the system identification information... + */ + + uname(platform); + +#ifdef __APPLE__ + /* + * Try to get the OS version number from the SystemVersion.plist file. + * If not present, use the uname() results for Darwin... + */ + + if ((fp = fopen("/System/Library/CoreServices/SystemVersion.plist", "r")) != NULL) + { + ptr = NULL; + + while (fgets(line, sizeof(line), fp) != NULL) + if ((ptr = strstr(line, "ProductUserVisibleVersion")) != NULL) + break; + else if ((ptr = strstr(line, "ProductVersion")) != NULL) + break; + + if (ptr && fgets(line, sizeof(line), fp) != NULL) + { + major = 10; + minor = 2; + + if ((ptr = strstr(line, "<string>")) != NULL) + sscanf(ptr + 8, "%d.%d", &major, &minor); + + sprintf(platform->release, "%d.%d", major, minor); + } + else + { + /* + * Couldn't find the version number, so assume it is 10.1... + */ + + strcpy(platform->release, "10.1"); + } + + fclose(fp); + + strcpy(platform->sysname, "macosx"); + } +#endif /* __APPLE__ */ + + /* + * Adjust the CPU type accordingly... + */ + +#ifdef __sgi + strcpy(platform->machine, "mips"); +#elif defined(__hpux) + strcpy(platform->machine, "hppa"); +#elif defined(_AIX) + strcpy(platform->machine, "powerpc"); +#else + update_architecture(platform->machine, sizeof(platform->machine)); +#endif /* __sgi */ + +#ifdef _AIX + /* + * AIX stores the major and minor version numbers separately; + * combine them... + */ + + sprintf(platform->release, "%d.%d", atoi(platform->version), + atoi(platform->release)); +#else + /* + * Remove any extra junk from the release number - we just want the + * major and minor numbers... + */ + + while (!isdigit((int)platform->release[0]) && platform->release[0]) + strcpy(platform->release, platform->release + 1); + + if (platform->release[0] == '.') + strcpy(platform->release, platform->release + 1); + + for (temp = platform->release; *temp && isdigit(*temp & 255); temp ++); + + if (*temp == '.') + for (temp ++; *temp && isdigit(*temp & 255); temp ++); + + *temp = '\0'; +#endif /* _AIX */ + + /* + * Convert the operating system name to lowercase, and strip out + * hyphens and underscores... + */ + + for (temp = platform->sysname; *temp != '\0'; temp ++) + if (*temp == '-' || *temp == '_') + { + strcpy(temp, temp + 1); + temp --; + } + else + *temp = tolower(*temp); + + /* + * SunOS 5.x is really Solaris 2.x or Solaris X, and OSF1 is really + * Digital UNIX a.k.a. Compaq Tru64 UNIX... + */ + + if (!strcmp(platform->sysname, "sunos") && platform->release[0] >= '5') + { + strcpy(platform->sysname, "solaris"); + + if (atoi(platform->release + 2) < 7) + platform->release[0] -= 3; + else + { + /* + * Strip 5. from the front of the version number... + */ + + for (temp = platform->release; temp[2]; temp ++) + *temp = temp[2]; + + *temp = '\0'; + } + } + else if (!strcmp(platform->sysname, "osf1")) + strcpy(platform->sysname, "tru64"); /* AKA Digital UNIX */ + else if (!strcmp(platform->sysname, "irix64")) + strcpy(platform->sysname, "irix"); /* IRIX */ + +#ifdef DEBUG + printf("sysname = %s\n", platform->sysname); + printf("release = %s\n", platform->release); + printf("machine = %s\n", platform->machine); +#endif /* DEBUG */ +} + + +/* + * 'get_runlevels()' - Get the run levels for the specified init script. + */ + +const char * /* O - Run levels */ +get_runlevels(file_t *file, /* I - File */ + const char *deflevels) /* I - Default run levels */ +{ + const char *runlevels; /* Pointer to runlevels option */ + + + if ((runlevels = strstr(file->options, "runlevel(")) != NULL) + runlevels += 9; + else if ((runlevels = strstr(file->options, "runlevels(")) != NULL) + runlevels += 10; /* Compatible mis-spelling... */ + else + runlevels = deflevels; + + return (runlevels); +} + + +/* + * 'get_start()' - Get the start number for an init script. + */ + +int /* O - Start number */ +get_start(file_t *file, /* I - File */ + int defstart) /* I - Default start number */ +{ + const char *start; /* Pointer to start option */ + + + if ((start = strstr(file->options, "start(")) != NULL) + return (atoi(start + 6)); + else + return (defstart); +} + + +/* + * 'get_stop()' - Get the stop number for an init script. + */ + +int /* O - Start number */ +get_stop(file_t *file, /* I - File */ + int defstop) /* I - Default stop number */ +{ + const char *stop; /* Pointer to stop option */ + + + if ((stop = strstr(file->options, "stop(")) != NULL) + return (atoi(stop + 5)); + else + return (defstop); +} + + +/* + * 'new_dist()' - Create a new, empty software distribution. + */ + +dist_t * /* O - New distribution */ +new_dist(void) +{ + /* + * Create a new, blank distribution... + */ + + return ((dist_t *)calloc(sizeof(dist_t), 1)); +} + + +/* + * 'read_dist()' - Read a software distribution. + */ + +dist_t * /* O - New distribution */ +read_dist(const char *filename, /* I - Main distribution list file */ + struct utsname *platform, /* I - Platform information */ + const char *format) /* I - Format of distribution */ +{ + FILE *listfiles[10]; /* File lists */ + int listlevel; /* Level in file list */ + char line[2048], /* Expanded line from list file */ + buf[1024]; /* Original line from list file */ + int type; /* File type */ + char dst[256], /* Destination path */ + src[256], /* Source path */ + pattern[256], /* Pattern for source files */ + user[32], /* User */ + group[32], /* Group */ + *temp, /* Temporary pointer */ + options[256]; /* File options */ + mode_t mode; /* File permissions */ + int skip; /* 1 = skip files, 0 = archive files */ + dist_t *dist; /* Distribution data */ + file_t *file; /* Distribution file */ + struct stat fileinfo; /* File information */ + DIR *dir; /* Directory */ + DIRENT *dent; /* Directory entry */ + struct passwd *pwd; /* Password entry */ + const char *subpkg; /* Subpackage */ + + + /* + * Create a new, blank distribution... + */ + + dist = new_dist(); + + /* + * Open the main list file... + */ + + if ((listfiles[0] = fopen(filename, "r")) == NULL) + { + fprintf(stderr, "epm: Unable to open list file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (NULL); + } + + /* + * Find any product descriptions, etc. in the list file... + */ + + if (Verbosity) + puts("Searching for product information..."); + + skip = 0; + listlevel = 0; + subpkg = NULL; + + do + { + while (get_line(buf, sizeof(buf), listfiles[listlevel], platform, format, + &skip) != NULL) + { + /* + * Do variable substitution... + */ + + line[0] = buf[0]; /* Don't expand initial $ */ + expand_name(line + 1, buf + 1, sizeof(line) - 1, + strncmp(buf, "%if", 3) || strncmp(buf, "%elseif", 7)); + + /* + * Check line for config stuff... + */ + + if (line[0] == '%') + { + /* + * Find whitespace... + */ + + for (temp = line; !isspace(*temp & 255) && *temp; temp ++); + for (; isspace(*temp & 255); *temp++ = '\0'); + + /* + * Process directive... + */ + + if (!strcmp(line, "%include")) + { + listlevel ++; + + if ((listfiles[listlevel] = fopen(temp, "r")) == NULL) + { + fprintf(stderr, "epm: Unable to include \"%s\" -\n %s\n", temp, + strerror(errno)); + listlevel --; + } + } + else if (!strcmp(line, "%description")) + add_description(dist, listfiles[listlevel], temp, subpkg); + else if (!strcmp(line, "%preinstall")) + add_command(dist, listfiles[listlevel], COMMAND_PRE_INSTALL, temp, + subpkg, NULL); + else if (!strcmp(line, "%install") || !strcmp(line, "%postinstall")) + add_command(dist, listfiles[listlevel], COMMAND_POST_INSTALL, temp, + subpkg, NULL); + else if (!strcmp(line, "%remove") || !strcmp(line, "%preremove")) + add_command(dist, listfiles[listlevel], COMMAND_PRE_REMOVE, temp, + subpkg, NULL); + else if (!strcmp(line, "%postremove")) + add_command(dist, listfiles[listlevel], COMMAND_POST_REMOVE, temp, + subpkg, NULL); + else if (!strcmp(line, "%prepatch")) + add_command(dist, listfiles[listlevel], COMMAND_PRE_PATCH, temp, + subpkg, NULL); + else if (!strcmp(line, "%patch") || !strcmp(line, "%postpatch")) + add_command(dist, listfiles[listlevel], COMMAND_POST_PATCH, temp, + subpkg, NULL); + else if (!strncmp(line, "%literal(", 9)) + { + char *ptr, /* Pointer to parenthesis */ + *section; /* Section for literal text */ + + + section = line + 9; + if ((ptr = strchr(section, ')')) != NULL) + { + *ptr = '\0'; + + add_command(dist, listfiles[listlevel], COMMAND_LITERAL, temp, + subpkg, section); + } + else + fputs("epm: Ignoring bad %literal(section) line in list file.\n", + stderr); + } + else if (!strcmp(line, "%product")) + { + if (!dist->product[0]) + strcpy(dist->product, temp); + else + fputs("epm: Ignoring %product line in list file.\n", stderr); + } + else if (!strcmp(line, "%copyright")) + { + if (!dist->copyright[0]) + strcpy(dist->copyright, temp); + else + fputs("epm: Ignoring %copyright line in list file.\n", stderr); + } + else if (!strcmp(line, "%vendor")) + { + if (!dist->vendor[0]) + strcpy(dist->vendor, temp); + else + fputs("epm: Ignoring %vendor line in list file.\n", stderr); + } + else if (!strcmp(line, "%packager")) + { + if (!dist->packager[0]) + strcpy(dist->packager, temp); + else + fputs("epm: Ignoring %packager line in list file.\n", stderr); + } + else if (!strcmp(line, "%license")) + { + if (!dist->license[0]) + strcpy(dist->license, temp); + else + fputs("epm: Ignoring %license line in list file.\n", stderr); + } + else if (!strcmp(line, "%readme")) + { + if (!dist->readme[0]) + strcpy(dist->readme, temp); + else + fputs("epm: Ignoring %readme line in list file.\n", stderr); + } + else if (!strcmp(line, "%subpackage")) + { + subpkg = find_subpackage(dist, temp); + } + else if (!strcmp(line, "%version")) + { + if (!dist->version[0]) + { + if (strchr(temp, ':')) + { + /* + * Grab the epoch... + */ + + dist->epoch = strtol(temp, &temp, 10); + + if (*temp == ':') + temp ++; + } + + strlcpy(dist->version, temp, sizeof(dist->version)); + if ((temp = strchr(dist->version, ' ')) != NULL) + { + *temp++ = '\0'; + dist->vernumber = atoi(temp); + } + else + dist->vernumber = get_vernumber(dist->version); + + if ((temp = strrchr(dist->version, '-')) != NULL) + { + *temp++ = '\0'; + strlcpy(dist->release, temp, sizeof(dist->release)); + } + } + } + else if (!strcmp(line, "%release")) + { + strlcpy(dist->release, temp, sizeof(dist->release)); + dist->vernumber += atoi(temp); + } + else if (!strcmp(line, "%incompat")) + add_depend(dist, DEPEND_INCOMPAT, temp, subpkg); + else if (!strcmp(line, "%provides")) + add_depend(dist, DEPEND_PROVIDES, temp, subpkg); + else if (!strcmp(line, "%replaces")) + add_depend(dist, DEPEND_REPLACES, temp, subpkg); + else if (!strcmp(line, "%requires")) + add_depend(dist, DEPEND_REQUIRES, temp, subpkg); + else + { + fprintf(stderr, "epm: Unknown directive \"%s\" ignored!\n", line); + fprintf(stderr, " %s %s\n", line, temp); + } + } + else if (line[0] == '$') + { + /* + * Define a variable... + */ + + if (line[1] == '{' && (temp = strchr(line + 2, '}')) != NULL) + { + /* + * Remove {} from name... + */ + + strcpy(temp, temp + 1); + strcpy(line + 1, line + 2); + } + else if (line[1] == '(' && (temp = strchr(line + 2, ')')) != NULL) + { + /* + * Remove () from name... + */ + + strcpy(temp, temp + 1); + strcpy(line + 1, line + 2); + } + + if ((temp = strchr(line + 1, '=')) != NULL) + { + /* + * Only define the variable if it is not in the environment + * or on the command-line. + */ + + *temp = '\0'; + + if (getenv(line + 1) == NULL) + { + *temp = '='; + if ((temp = strdup(line + 1)) != NULL) + putenv(temp); + } + } + } + else + { + type = line[0]; + if (!isspace(line[1] & 255)) + { + fprintf(stderr, "epm: Expected whitespace after file type - %s\n", + line); + continue; + } + + temp = line + 2; + mode = strtol(temp, &temp, 8); + if (temp == (line + 2)) + { + fprintf(stderr, "epm: Expected file permissions after file type - %s\n", + line); + continue; + } + + if (get_string(&temp, user, sizeof(user)) == NULL) + { + fprintf(stderr, "epm: Expected user after file permissions - %s\n", + line); + continue; + } + + if (get_string(&temp, group, sizeof(group)) == NULL) + { + fprintf(stderr, "epm: Expected group after user - %s\n", + line); + continue; + } + + if (get_string(&temp, dst, sizeof(dst)) == NULL) + { + fprintf(stderr, "epm: Expected destination after group - %s\n", + line); + continue; + } + + get_string(&temp, src, sizeof(src)); + + get_string(&temp, options, sizeof(options)); + + if (tolower(type) == 'd' || type == 'R') + { + strcpy(options, src); + src[0] = '\0'; + } + +#ifdef __osf__ /* Remap group "sys" to "system" */ + if (!strcmp(group, "sys")) + strcpy(group, "system"); +#elif defined(__linux) /* Remap group "sys" to "root" */ + if (!strcmp(group, "sys")) + strcpy(group, "root"); +#endif /* __osf__ */ + + if ((temp = strrchr(src, '/')) == NULL) + temp = src; + else + temp ++; + + for (; *temp; temp ++) + if (strchr("*?[", *temp)) + break; + + if (*temp) + { + /* + * Add using wildcards... + */ + + if ((temp = strrchr(src, '/')) == NULL) + temp = src; + else + *temp++ = '\0'; + + strlcpy(pattern, temp, sizeof(pattern)); + + if (dst[strlen(dst) - 1] != '/') + strncat(dst, "/", sizeof(dst) - 1); + + if (temp == src) + dir = opendir("."); + else + dir = opendir(src); + + if (dir == NULL) + fprintf(stderr, "epm: Unable to open directory \"%s\" - %s\n", + src, strerror(errno)); + else + { + /* + * Make sure we have a directory separator... + */ + + if (temp > src) + temp[-1] = '/'; + + while ((dent = readdir(dir)) != NULL) + { + strcpy(temp, dent->d_name); + if (stat(src, &fileinfo)) + continue; /* Skip files we can't read */ + + if (S_ISDIR(fileinfo.st_mode)) + continue; /* Skip directories */ + + if (!patmatch(dent->d_name, pattern)) + continue; + + file = add_file(dist, subpkg); + + file->type = type; + file->mode = mode; + strcpy(file->src, src); + strcpy(file->dst, dst); + strncat(file->dst, dent->d_name, sizeof(file->dst) - 1); + strcpy(file->user, user); + strcpy(file->group, group); + strcpy(file->options, options); + } + + closedir(dir); + } + } + else + { + /* + * Add single file... + */ + + file = add_file(dist, subpkg); + + file->type = type; + file->mode = mode; + strcpy(file->src, src); + strcpy(file->dst, dst); + strcpy(file->user, user); + strcpy(file->group, group); + strcpy(file->options, options); + } + } + } + + fclose(listfiles[listlevel]); + listlevel --; + } + while (listlevel >= 0); + + if (!dist->packager[0]) + { + /* + * Assign a default packager name... + */ + + gethostname(buf, sizeof(buf)); + + setpwent(); + if ((pwd = getpwuid(getuid())) != NULL) + snprintf(dist->packager, sizeof(dist->packager), "%s@%s", pwd->pw_name, + buf); + else + snprintf(dist->packager, sizeof(dist->packager), "unknown@%s", buf); + } + + sort_dist_files(dist); + + return (dist); +} + + +/* + * 'sort_dist_files()' - Sort the files in the distribution. + */ + +void +sort_dist_files(dist_t *dist) /* I - Distribution to sort */ +{ + int i; /* Looping var */ + file_t *file; /* File in distribution */ + + + /* + * Sort the files... + */ + + if (dist->num_files > 1) + qsort(dist->files, (size_t)dist->num_files, sizeof(file_t), + (int (*)(const void *, const void *))compare_files); + + /* + * Remove duplicates... + */ + + for (i = dist->num_files - 1, file = dist->files; i > 0; i --, file ++) + if (!strcmp(file[0].dst, file[1].dst)) + { + if (file[0].type == file[1].type && file[0].mode == file[1].mode && + !strcmp(file[0].src, file[1].src) && + !strcmp(file[0].user, file[1].user) && + !strcmp(file[0].group, file[1].group) && + !strcmp(file[0].options, file[1].options)) + { + /* + * Ignore exact duplicates... + */ + + memcpy(file, file + 1, i * sizeof(file_t)); + dist->num_files --; + file --; + } + else + fprintf(stderr, "epm: Duplicate destination path \"%s\" with different info!\n" + " \"%c %04o %s %s\" from source \"%s\"\n" + " \"%c %04o %s %s\" from source \"%s\"\n", + file[0].dst, + file[0].type, file[0].mode, file[0].user, file[0].group, file[0].src, + file[1].type, file[1].mode, file[1].user, file[1].group, file[1].src); + } +} + + +/* + * 'write_dist()' - Write a distribution list file... + */ + +int /* O - 0 on success, -1 on failure */ +write_dist(const char *listname, /* I - File to write to */ + dist_t *dist) /* I - Distribution to write */ +{ + int i; /* Looping var */ + int is_inline; /* Inline text? */ + char listbck[1024], /* Backup filename */ + *ptr; /* Pointer into command string */ + FILE *listfile; /* Output file */ + file_t *file; /* Current file entry */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + char curstring[256]; /* Current date/time string */ + const char *subpkg; /* Current subpackage */ + static const char *commands[] = /* Command strings */ + { + "%preinstall", + "%postinstall", + "%prepatch", + "%postpatch", + "%preremove", + "%postremove" + }, + *depends[] = /* Dependency strings */ + { + "%requires", + "%incompat", + "%replaces", + "%provides" + }; + + + /* + * Make a backup of the list file... + */ + + snprintf(listbck, sizeof(listbck), "%s.O", listname); + + rename(listname, listbck); + + /* + * Open the list file... + */ + + if ((listfile = fopen(listname, "w")) == NULL) + { + rename(listbck, listname); + return (-1); + } + + /* + * Write the list file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + + strftime(curstring, sizeof(curstring), "# List file created on %c by " + EPM_VERSION "\n", curdate); + fputs(curstring, listfile); + + if (dist->product[0]) + fprintf(listfile, "%%product %s\n", dist->product); + if (dist->version[0]) + fprintf(listfile, "%%version %s %d\n", dist->version, dist->vernumber); + if (dist->release[0]) + fprintf(listfile, "%%release %s\n", dist->release); + if (dist->copyright[0]) + fprintf(listfile, "%%copyright %s\n", dist->copyright); + if (dist->vendor[0]) + fprintf(listfile, "%%vendor %s\n", dist->vendor); + if (dist->packager[0]) + fprintf(listfile, "%%packager %s\n", dist->packager); + if (dist->license[0]) + fprintf(listfile, "%%license %s\n", dist->license); + if (dist->readme[0]) + fprintf(listfile, "%%readme %s\n", dist->readme); + + subpkg = NULL; + for (i = 0; i < dist->num_descriptions; i ++) + { + if (dist->descriptions[i].subpackage != subpkg) + { + subpkg = dist->descriptions[i].subpackage; + fprintf(listfile, "%%subpackage %s\n", subpkg ? subpkg : ""); + } + + if (strchr(dist->descriptions[i].description, '\n') != NULL) + fprintf(listfile, "%%description <<EPM-END-INLINE\n%s\nEPM-END-INLINE\n", + dist->descriptions[i].description); + else + fprintf(listfile, "%%description %s\n", + dist->descriptions[i].description); + } + + for (i = 0; i < dist->num_depends; i ++) + { + if (dist->depends[i].subpackage != subpkg) + { + subpkg = dist->depends[i].subpackage; + fprintf(listfile, "%%subpackage %s\n", subpkg ? subpkg : ""); + } + + fprintf(listfile, "%s %s", depends[(int)dist->depends[i].type], + dist->depends[i].product); + + if (dist->depends[i].version[0][0] || + dist->depends[i].version[1][0]) + { + fprintf(listfile, " %s %d %s %d\n", + dist->depends[i].version[0], + dist->depends[i].vernumber[0], + dist->depends[i].version[1], + dist->depends[i].vernumber[1]); + } + else + putc('\n', listfile); + } + + for (i = 0; i < dist->num_commands; i ++) + { + if (dist->commands[i].subpackage != subpkg) + { + subpkg = dist->commands[i].subpackage; + fprintf(listfile, "%%subpackage %s\n", subpkg ? subpkg : ""); + } + + fputs(commands[(int)dist->commands[i].type], listfile); + + is_inline = strchr(dist->commands[i].command, '\n') != NULL; + + if (is_inline) + fputs(" <<EPM-END-INLINE\n", listfile); + else + putc(' ', listfile); + + for (ptr = dist->commands[i].command; *ptr; ptr ++) + { + if (*ptr == '$' && !is_inline) + putc(*ptr, listfile); + + putc(*ptr, listfile); + } + putc('\n', listfile); + + if (is_inline) + fputs("EPM-END-INLINE\n", listfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + if (file->subpackage != subpkg) + { + subpkg = file->subpackage; + fprintf(listfile, "%%subpackage %s\n", subpkg ? subpkg : ""); + } + + fprintf(listfile, "%c %04o %s %s %s %s", + file->type, file->mode, file->user, file->group, + file->dst, file->src); + + if (file->options[0]) + fprintf(listfile, "%s\n", file->options); + else + putc('\n', listfile); + } + + return (fclose(listfile)); +} + + +/* + * 'compare_files()' - Compare the destination filenames. + */ + +static int /* O - Result of comparison */ +compare_files(const file_t *f0, /* I - First file */ + const file_t *f1) /* I - Second file */ +{ + return (strcmp(f0->dst, f1->dst)); +} + + +/* + * 'expand_name()' - Expand a filename with environment variables. + */ + +static void +expand_name(char *buffer, /* O - Output string */ + char *name, /* I - Input string */ + size_t bufsize, /* I - Size of output string */ + int warn) /* I - Warn when not set? */ +{ + char var[255], /* Environment variable name */ + *varptr, /* Current position in name */ + delim; /* Delimiter character */ + + + bufsize --; + while (*name != '\0' && bufsize > 0) + { + if (*name == '$') + { + name ++; + if (*name == '$') + { + /* + * Insert a lone $... + */ + + *buffer++ = *name++; + bufsize --; + continue; + } + else if (*name == '{' || *name == '(') + { + /* + * Bracketed variable name... + */ + + delim = *name == '{' ? '}' : ')'; + + for (varptr = var, name ++; *name != delim && *name; name ++) + if (varptr < (var + sizeof(var) - 1)) + *varptr++ = *name; + + if (*name == delim) + name ++; + } + else + { + /* + * Unbracketed variable name... + */ + + for (varptr = var; !strchr("/ \t\r\n-", *name) && *name; name ++) + if (varptr < (var + sizeof(var) - 1)) + *varptr++ = *name; + } + + *varptr = '\0'; + + if ((varptr = getenv(var)) != NULL) + { + strlcpy(buffer, varptr, bufsize + 1); + bufsize -= strlen(buffer); + buffer += strlen(buffer); + } + else if (warn) + fprintf(stderr, "epm: Variable \"%s\" undefined!\n", var); + } + else + { + *buffer++ = *name++; + bufsize --; + } + } + + *buffer = '\0'; +} + + +/* + * 'get_file()' - Read a file into a string... + */ + +static char * /* O - Pointer to string or NULL on EOF */ +get_file(const char *filename, /* I - File to read from */ + char *buffer, /* IO - String buffer */ + size_t size) /* I - Size of string buffer */ +{ + FILE *fp; /* File buffer */ + struct stat info; /* File information */ + char *expand; /* Expansion buffer */ + + + if (stat(filename, &info)) + { + fprintf(stderr, "epm: Unable to stat \"%s\" - %s\n", filename, + strerror(errno)); + return (NULL); + } + + if (info.st_size > (size - 1)) + { + fprintf(stderr, + "epm: File \"%s\" is too large (%d bytes) for buffer (%d bytes)\n", + filename, (int)info.st_size, (int)size - 1); + return (NULL); + } + + if ((fp = fopen(filename, "r")) == NULL) + { + fprintf(stderr, "epm: Unable to open \"%s\" - %s\n", filename, + strerror(errno)); + return (NULL); + } + + if ((fread(buffer, 1, (size_t)info.st_size, fp)) < info.st_size) + { + fprintf(stderr, "epm: Unable to read \"%s\" - %s\n", filename, + strerror(errno)); + fclose(fp); + return (NULL); + } + + fclose(fp); + + if (buffer[info.st_size - 1] == '\n') + buffer[info.st_size - 1] = '\0'; + else + buffer[info.st_size] = '\0'; + + if (strchr(buffer, '$') != NULL) + { + /* + * Do variable expansion before returning... + */ + + expand = strdup(buffer); + + expand_name(buffer, expand, size, 1); + + free(expand); + } + + return (buffer); +} + + +/* + * 'get_inline()' - Read inline lines into a string... + */ + +static char * /* O - Pointer to string or NULL on EOF */ +get_inline(const char *term, /* I - Termination string */ + FILE *fp, /* I - File to read from */ + char *buffer, /* IO - String buffer */ + size_t size) /* I - Size of string buffer */ +{ + char *bufptr; /* Pointer into buffer */ + int left; /* Remaining bytes in buffer */ + int termlen; /* Length of termination string */ + int linelen; /* Length of line */ + char *expand; /* Expansion buffer */ + + + bufptr = buffer; + left = size; + termlen = strlen(term); + + if (termlen == 0) + return (NULL); + + while (fgets(bufptr, left, fp) != NULL) + { + if (!strncmp(bufptr, term, (size_t)termlen) && bufptr[termlen] == '\n') + { + *bufptr = '\0'; + break; + } + + linelen = strlen(bufptr); + left -= linelen; + bufptr += linelen; + + if (left < 2) + { + fputs("epm: Inline script too long!\n", stderr); + break; + } + } + + if (bufptr > buffer) + { + bufptr --; + if (*bufptr == '\n') + *bufptr = '\0'; + + if (strchr(buffer, '$') != NULL) + { + /* + * Do variable expansion before returning... + */ + + expand = strdup(buffer); + + expand_name(buffer, expand, size, 1); + + free(expand); + } + + return (buffer); + } + else + return (NULL); +} + + +/* + * 'get_line()' - Get a line from a file, filtering for uname lines... + */ + +static char * /* O - String read or NULL at EOF */ +get_line(char *buffer, /* I - Buffer to read into */ + int size, /* I - Size of buffer */ + FILE *fp, /* I - File to read from */ + struct utsname *platform, /* I - Platform information */ + const char *format, /* I - Distribution format */ + int *skip) /* IO - Skip lines? */ +{ + int op, /* Operation (0 = OR, 1 = AND) */ + namelen, /* Length of system name + version */ + len, /* Length of string */ + match; /* 1 = match, 0 = not */ + char *ptr, /* Pointer into value */ + *bufptr, /* Pointer into buffer */ + namever[255], /* Name + version */ + value[255]; /* Value string */ + const char *var; /* Variable value */ + + + while (fgets(buffer, size, fp) != NULL) + { + /* + * Skip comment and blank lines... + */ + + if (buffer[0] == '#' || buffer[0] == '\n') + continue; + + /* + * See if this is a %system, %format, or conditional line... + */ + + if (!strncmp(buffer, "%system ", 8)) + { + /* + * Yes, do filtering based on the OS (+version)... + */ + + *skip &= ~SKIP_SYSTEM; + + if (strcmp(buffer + 8, "all\n")) + { + namelen = strlen(platform->sysname); + bufptr = buffer + 8; + snprintf(namever, sizeof(namever), "%s-%s", platform->sysname, + platform->release); + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr != '!') + *skip |= SKIP_SYSTEM; + + while (*bufptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (!*bufptr) + break; + + if (*bufptr == '!') + { + op = 1; + bufptr ++; + } + else + op = 0; + + for (ptr = value; + *bufptr && !isspace(*bufptr & 255) && + ptr < (value + sizeof(value) - 1); + *ptr++ = *bufptr++); + + *ptr = '\0'; + + if (!strncmp(value, "dunix", 5)) + memcpy(value, "tru64", 5); /* Keep existing nul/version */ + else if (!strncmp(value, "darwin", 6) && + !strcmp(platform->sysname, "macosx")) + memcpy(value, "macosx", 6); /* Keep existing nul/version */ + + if ((ptr = strchr(value, '-')) != NULL) + len = ptr - value; + else + len = strlen(value); + + if (len < namelen) + match = 0; + else + match = !strncasecmp(value, namever, strlen(value)) ? + SKIP_SYSTEM : 0; + + if (op) + *skip |= match; + else + *skip &= ~match; + } + } + } + else if (!strncmp(buffer, "%format ", 8)) + { + /* + * Yes, do filtering based on the distribution format... + */ + + *skip &= ~SKIP_FORMAT; + + if (strcmp(buffer + 8, "all\n")) + { + bufptr = buffer + 8; + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr != '!') + *skip |= SKIP_FORMAT; + + while (*bufptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (!*bufptr) + break; + + if (*bufptr == '!') + { + op = 1; + bufptr ++; + } + else + op = 0; + + for (ptr = value; + *bufptr && !isspace(*bufptr & 255) && + ptr < (value + sizeof(value) - 1); + *ptr++ = *bufptr++); + + *ptr = '\0'; + + match = !strcasecmp(value, format) ? SKIP_FORMAT : 0; + + if (op) + *skip |= match; + else + *skip &= ~match; + } + } + } + else if (!strncmp(buffer, "%arch ", 6)) + { + /* + * Yes, do filtering based on the current architecture... + */ + + *skip &= ~SKIP_ARCH; + + if (strcmp(buffer + 6, "all\n")) + { + bufptr = buffer + 8; + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr != '!') + *skip |= SKIP_ARCH; + + while (*bufptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (!*bufptr) + break; + + if (*bufptr == '!') + { + op = 1; + bufptr ++; + } + else + op = 0; + + for (ptr = value; + *bufptr && !isspace(*bufptr & 255) && + ptr < (value + sizeof(value) - 1); + *ptr++ = *bufptr++); + + *ptr = '\0'; + + update_architecture(value, sizeof(value)); + + match = !strcasecmp(value, platform->machine) ? SKIP_ARCH : 0; + + if (op) + *skip |= match; + else + *skip &= ~match; + } + } + } + else if (!strncmp(buffer, "%ifdef ", 7) || + !strncmp(buffer, "%elseifdef ", 11)) + { + /* + * Yes, do filtering based on the presence of variables... + */ + + if ((*skip & SKIP_IFACTIVE) && buffer[1] != 'e') + { + /* + * Nested %if... + */ + + fputs("epm: Warning, nested %ifdef's are not supported!\n", stderr); + continue; + } + + if (buffer[1] == 'e') + bufptr = buffer + 11; + else + bufptr = buffer + 7; + + *skip |= SKIP_IF | SKIP_IFACTIVE; + + if (*skip & SKIP_IFSAT) + continue; + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr == '!') + *skip &= ~SKIP_IF; + + while (*bufptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (!*bufptr) + break; + + /* + * Get the variable name... + */ + + if (*bufptr == '!') + { + op = 1; + bufptr ++; + } + else + op = 0; + + for (ptr = value; + *bufptr && !isspace(*bufptr & 255) && + ptr < (value + sizeof(value) - 1); + *ptr++ = *bufptr++); + + *ptr = '\0'; + + match = (getenv(value) != NULL) ? SKIP_IF : 0; + + if (op) + *skip |= match; + else + *skip &= ~match; + + if (match) + *skip |= SKIP_IFSAT; + } + } + else if (!strncmp(buffer, "%if ", 4) || !strncmp(buffer, "%elseif ", 8)) + { + /* + * Yes, do filtering based on the value of variables... + */ + + if ((*skip & SKIP_IFACTIVE) && buffer[1] != 'e') + { + /* + * Nested %if... + */ + + fputs("epm: Warning, nested %if's are not supported!\n", stderr); + continue; + } + + if (buffer[1] == 'e') + bufptr = buffer + 8; + else + bufptr = buffer + 4; + + *skip |= SKIP_IF | SKIP_IFACTIVE; + + if (*skip & SKIP_IFSAT) + continue; + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr == '!') + *skip &= ~SKIP_IF; + + while (*bufptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*bufptr & 255)) + bufptr ++; + + if (!*bufptr) + break; + + /* + * Get the variable name... + */ + + if (*bufptr == '!') + { + op = 1; + bufptr ++; + } + else + op = 0; + + for (ptr = value; + *bufptr && !isspace(*bufptr & 255) && + ptr < (value + sizeof(value) - 1); + *ptr++ = *bufptr++); + + *ptr = '\0'; + + match = ((var = getenv(value)) != NULL && *var) ? SKIP_IF : 0; + + if (op) + *skip |= match; + else + *skip &= ~match; + + if (match) + *skip |= SKIP_IFSAT; + } + } + else if (!strcmp(buffer, "%else\n")) + { + /* + * Handle "else" condition of %ifdef statement... + */ + + if (!(*skip & SKIP_IFACTIVE)) + { + /* + * No matching %if/%ifdef statement... + */ + + fputs("epm: Warning, no matching %if or %ifdef for %else!\n", stderr); + break; + } + + if (*skip & SKIP_IFSAT) + *skip |= SKIP_IF; + else + { + *skip &= ~SKIP_IF; + *skip |= SKIP_IFSAT; + } + } + else if (!strcmp(buffer, "%endif\n")) + { + /* + * Cancel any filtering based on environment variables. + */ + + if (!(*skip & SKIP_IFACTIVE)) + { + /* + * No matching %if/%ifdef statement... + */ + + fputs("epm: Warning, no matching %if or %ifdef for %endif!\n", stderr); + break; + } + + *skip &= ~(SKIP_IF | SKIP_IFACTIVE | SKIP_IFSAT); + } + else if (!(*skip & SKIP_MASK)) + { + /* + * Otherwise strip any trailing newlines and return the string! + */ + + if (buffer[strlen(buffer) - 1] == '\n') + buffer[strlen(buffer) - 1] = '\0'; + + return (buffer); + } + } + + return (NULL); +} + + +/* + * 'get_string()' - Get a delimited string from a line. + */ + +static char * /* O - String or NULL */ +get_string(char **src, /* IO - Source string */ + char *dst, /* O - Destination string */ + size_t dstsize) /* I - Size of destination string */ +{ + char *srcptr, /* Current source pointer */ + *dstptr, /* Current destination pointer */ + *dstend, /* End of destination string */ + quote; /* Quoting char */ + + + /* + * Initialize things... + */ + + srcptr = *src; + dstptr = dst; + dstend = dst + dstsize - 1; + + *dstptr = '\0'; + + /* + * Skip leading whitespace... + */ + + while (isspace(*srcptr & 255)) + srcptr ++; + + if (!*srcptr) + { + *src = srcptr; + + return (NULL); + } + + /* + * Grab the next string... + */ + + while (*srcptr && !isspace(*srcptr & 255)) + { + if (*srcptr == '\\') + { + srcptr ++; + + if (!*srcptr) + { + fputs("epm: Expected character after backslash!\n", stderr); + + *src = srcptr; + *dst = '\0'; + + return (NULL); + } + } + else if (*srcptr == '\'' || *srcptr == '\"') + { + /* + * Read a quoted string... + */ + + quote = *srcptr++; + + while (*srcptr != quote && *srcptr) + { + if (*srcptr == '\\') + { + srcptr ++; + + if (!*srcptr) + { + fputs("epm: Expected character after backslash!\n", stderr); + + *src = srcptr; + *dst = '\0'; + + return (NULL); + } + } + + if (dstptr < dstend) + *dstptr++ = *srcptr; + + srcptr ++; + } + + if (!*srcptr) + { + fprintf(stderr, "epm: Expected end quote %c!\n", quote); + + *src = srcptr; + *dst = '\0'; + + return (NULL); + } + + srcptr ++; + continue; + } + + if (dstptr < dstend) + *dstptr++ = *srcptr; + + srcptr ++; + } + + *dstptr = '\0'; + + /* + * Skip leading whitespace... + */ + + while (isspace(*srcptr & 255)) + srcptr ++; + + /* + * Return the string and string pointer... + */ + + *src = srcptr; + + return (dst); +} + + +/* + * 'patmatch()' - Pattern matching... + */ + +static int /* O - 1 if match, 0 if no match */ +patmatch(const char *s, /* I - String to match against */ + const char *pat) /* I - Pattern to match against */ +{ + /* + * Range check the input... + */ + + if (s == NULL || pat == NULL) + return (0); + + /* + * Loop through the pattern and match strings, and stop if we come to a + * point where the strings don't match or we find a complete match. + */ + + while (*s != '\0' && *pat != '\0') + { + if (*pat == '*') + { + /* + * Wildcard - 0 or more characters... + */ + + pat ++; + if (*pat == '\0') + return (1); /* Last pattern char is *, so everything matches now... */ + + /* + * Test all remaining combinations until we get to the end of the string. + */ + + while (*s != '\0') + { + if (patmatch(s, pat)) + return (1); + + s ++; + } + } + else if (*pat == '?') + { + /* + * Wildcard - 1 character... + */ + + pat ++; + s ++; + continue; + } + else if (*pat == '[') + { + /* + * Match a character from the input set [chars]... + */ + + pat ++; + while (*pat != ']' && *pat != '\0') + if (*s == *pat) + break; + else if (pat[1] == '-' && *s >= pat[0] && *s <= pat[2]) + break; + else + pat ++; + + if (*pat == ']' || *pat == '\0') + return (0); + + while (*pat != ']' && *pat != '\0') + pat ++; + + if (*pat == ']') + pat ++; + + s ++; + + continue; + } + else if (*pat == '\\') + { + /* + * Handle quoted characters... + */ + + pat ++; + } + + /* + * Stop if the pattern and string don't match... + */ + + if (*pat++ != *s++) + return (0); + } + + /* + * If we are at the end of the string, see if the pattern remaining is + * "*"... + */ + + while (*pat == '*') + pat ++; + + /* + * Done parsing the pattern and string; return 1 if the last character matches + * and 0 otherwise... + */ + + return (*s == *pat); +} + + +/* + * 'sort_subpackages()' - Compare two subpackage names. + */ + +static int /* O - Result of comparison */ +sort_subpackages(char **a, /* I - First subpackage */ + char **b) /* I - Second subpackage */ +{ + return (strcmp(*a, *b)); +} + + +/* + * 'update_architecture()' - Normalize the machine architecture name. + */ + +static void +update_architecture(char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of string buffer */ +{ + char *temp; /* Pointer into string buffer */ + + + /* + * Convert the name to lowercase with no underscores or dashes. + */ + + for (temp = buffer; *temp != '\0'; temp ++) + if (*temp == '-' || *temp == '_') + { + char *ptr; /* Pointer into string */ + + for (ptr = temp; ptr[1]; ptr ++) + *ptr = ptr[1]; + *ptr = '\0'; + + temp --; + } + else + *temp = tolower(*temp); + + /* + * Convert common synonyms to generic names... + */ + + if (strstr(buffer, "86")) + { + if (strstr(buffer, "64")) + strlcpy(buffer, "x86_64", bufsize); + else + strlcpy(buffer, "intel", bufsize); + } + else if (!strncmp(buffer, "arm", 3)) + strlcpy(buffer, "arm", bufsize); + else if (!strncmp(buffer, "ppc", 3)) + strlcpy(buffer, "powerpc", bufsize); + else if (!strncmp(buffer, "sun", 3)) + strlcpy(buffer, "sparc", bufsize); +} + + +/* + * End of "$Id: dist.c 843 2010-12-31 02:18:18Z mike $". + */ diff --git a/doc/1-intro.html b/doc/1-intro.html new file mode 100644 index 0000000..f5b6097 --- /dev/null +++ b/doc/1-intro.html @@ -0,0 +1,323 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="INTRO">1 - Introduction to EPM</A></H1> + +<P>This chapter provides an introduction to the ESP Package Manager ("EPM"). + +<H2>What is EPM?</H2> + +<P>Software distribution under UNIX/Linux can be a challenge, +especially if you ship software for more than one operating +system. Every operating system provides its own software +packaging tools and each has unique requirements or implications +for the software development environment.</P> + +<P>The ESP Package Manager ("EPM") is one solution to this +problem. Besides its own "portable" distribution format, EPM +also supports the generation of several vendor-specific formats. +This allows you to build software distribution files for almost +any operating system from the same sources.</P> + +<H2>History and Evolution</H2> + +<P>When Easy Software Products was founded in 1993, we +originally shipped software only for the SGI IRIX operating +system. In 1997 we added support for Solaris, which was quickly +followed by HP-UX support in 1998.</P> + +<P>Each new operating system and supported processor required a +new set of packaging files. While this worked, it also meant +that we had to keep all of the packaging files synchronized +manually. Needless to say, this process was far from perfect and +we had more than one distribution that was not identical on all +operating systems.</P> + +<P>As we began developing CUPS +(<A HREF="http://www.cups.org/">http://www.cups.org/</A>) in +1997, our initial goal was to add support for two additional +operating systems: Linux and Compaq Tru64 UNIX. If we wanted to +avoid the mistakes of the past, we clearly had to change how we +produced software distributions.</P> + +<P>The first version of EPM was released in 1999 and supported +so-called "portable" software distributions that were not tied +to any particular operating system or packaging software. Due to +popular demand, we added support for vendor-specific packaging +formats in the second major release of EPM, allowing the +generation of portable or "native" distributions from one +program and one set of software distribution files. + +<H2>Existing Software Packaging Systems</H2> + +<P>As we looked for a solution to our problem, we naturally +investigated the existing open-source packaging systems. Under +Linux, we looked at the Red Hat Package Manager ("RPM") and +Debian packaging software ("dpkg" and "dselect"). For the +commercial UNIX's we looked at the vendor-supplied packaging +systems. <A HREF="#TABLE_1_1">Table 1.1</A> shows the results of +our investigation.</P> + +<!-- NEED 5in --> +<TABLE ALIGN="CENTER" BORDER="1"> +<CAPTION><A NAME="TABLE_1_1">Table 1.1: Software Packaging Formats</A></CAPTION> +<TR> + <TH><FONT SIZE="-4">Format</FONT></TH> + <TH><FONT SIZE="-4">Operating Systems<SUP>1</SUP></FONT></TH> + <TH><FONT SIZE="-4">Binaries</FONT></TH> + <TH><FONT SIZE="-4">Cross- Platform</FONT></TH> + <TH><FONT SIZE="-4">Patches</FONT></TH> + <TH><FONT SIZE="-4">Up- grades</FONT></TH> + <TH><FONT SIZE="-4">Con- flicts</FONT></TH> + <TH><FONT SIZE="-4">Re- quires</FONT></TH> + <TH><FONT SIZE="-4">Re- places</FONT></TH> + <TH><FONT SIZE="-4">Config Files</FONT></TH> + <TH><FONT SIZE="-4">Map Files</FONT></TH> + <TH><FONT SIZE="-4">Un- install</FONT></TH> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>installp</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>AIX</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>pkg_add</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>FreeBSD</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>pkg_add</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>NetBSD<BR> + OpenBSD</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>dpkg</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Corel Linux<BR> + Debian GNU/Linux</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>depot</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>HP-UX</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>inst</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>IRIX</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>Install.app</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>MacOS X</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>pkgadd</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Solaris</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>rpm</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Mandrake<BR> + Red Hat<BR> + SuSE<BR> + TurboLinux</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>setld</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Tru64 UNIX</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +<TR> + <TD ALIGN="CENTER"><SMALL>slackware</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Slackware Linux</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>No</SMALL></TD> + <TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD> +</TR> +</TABLE> + +<OL> + + <LI>Standard packaging system for named operating systems.</LI> + + <LI>These packaging systems are cross-platform but require + the package management utilities to be installed on the + platform before installing the package.</LI> + +</OL> + +<P> </P> + +<P>As you can see, none of the formats supported every feature we +were looking for. One common fault of all these formats is that +they do not support a common software specification file format. +That is, making a Debian software distribution requires +significantly different support files than required for a Solaris +pkg distribution. This makes it extremely difficult to manage +distributions for multiple operating systems.</P> + +<P>All of the package formats support binary distributions. The +RPM and Debian formats also support source distributions that +specifically allow for recompilation and installation. Only the +commercial UNIX formats support patch distributions - you have +to completely upgrade a software package with RPM and Debian. +All but the Solaris <CODE>pkg</CODE> format allow you to upgrade +a package without removing the old version first.</P> + +<P>When building the software packages, RPM and Debian force you +to create the actual directories, copy the files to those +directories, and set the ownerships and permissions. You +essentially are creating a directory for your software that can +be archived in the corresponding package format. To ensure that +all file permissions and ownerships are correct, you must build +the distribution as the root user or use the +<CODE>fakeroot</CODE> software, introducing potential security +risks and violating many corporate security policies. It can also +make building distributions difficult when dynamic data such as +changing data files or databases is involved.</P> + +<P>The commercial UNIX formats use software list files that map +source files to the correct directories and permissions. +This allows for easier delivery of dynamic data, configuration +management of what each distribution actually contains, and +eliminates security issues with special permissions and building +distributions as the root user. Using the proprietary format +also has the added benefit of allowing for software patches and +using the familiar software installation tools for that +operating system. The primary disadvantage is that the same +distributions and packaging software cannot be used on other +operating systems.</P> + +<H2>Design Goals of EPM</H2> + +<P>EPM was designed from the beginning to build binary software +distributions using a common software specification format. The +same distribution files work for all operating systems and all +distribution formats. Supporting source code distributions was +not a goal since most RPM and Debian source distributions are +little more than wrapping around a compressed tar file +containing the source files and a configure script.</P> + +<P>Over the years, additional features have made their way into +EPM to support more advanced software packages. Whenever +possible, EPM emulates a feature if the vendor package format +does not support it natively.</P> + +<H2>Resources</H2> + +<P>The EPM web site provides access to the current software, documentation, +and discussion forums for EPM:</P> + +<PRE> + <A HREF="http://www.epmhome.org/">http://www.epmhome.org/</A> +</PRE> + +<P>The EPM source code can be downloaded in compressed tar files or +via the popular Subversion software. Please see the EPM web site for +complete instructions.</P> + +<P>Send book feedback to +"<A HREF="mailto:epm-book@easysw.com">epm-book@easysw.com</A>".</P> + +</BODY> +</HTML> diff --git a/doc/2-building.html b/doc/2-building.html new file mode 100644 index 0000000..983c246 --- /dev/null +++ b/doc/2-building.html @@ -0,0 +1,382 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="BUILDING">2 - Building EPM</A></H1> + +<P>This chapter shows how to configure, build, and install the +ESP Package Manager.</P> + +<H2>Requirements</H2> + +<P>EPM requires very little pre-installed software to work. Most +items will likely be provided as part of your OS. Your +development system will need a C compiler, the +<CODE>make(1)</CODE> program (GNU, BSD, and most vendor +<CODE>make</CODE> programs should work), the Bourne (or Korn or +Bash) shell (<CODE>sh(1)</CODE>), and <CODE>gzip(1)</CODE>.</P> + +<P>The optional graphical setup program requires a C++ compiler, +the FLTK library, version 1.1.x, and (for UNIX/Linux) the X11 +libraries. FLTK is available at the following URL:</P> + +<PRE> + <A HREF="http://www.fltk.org/">http://www.fltk.org/</A> +</PRE> + +<P>Your end-user systems will require the Bourne (or Korn or +Bash) shell (<CODE>sh</CODE>), the <CODE>df(1)</CODE> program, +the <CODE>tar(1)</CODE> program, and the <CODE>gzip(1)</CODE> +program to install portable distributions. All but the last are +standard items, and most vendors include <CODE>gzip</CODE> as +well.</P> + +<P>EPM can also generate vendor-specific distributions. These +require the particular vendor tool, such as <CODE>rpm(8)</CODE> +and <CODE>dpkg(8)</CODE>, to generate the software distribution +on the development system and load the software distribution on +the end-user system.</P> + +<H2>Configuring the Software</H2> + +<P>EPM uses GNU <CODE>autoconf(1)</CODE> to configure itself for +your system. The <CODE>configure</CODE> script is used to +configure the EPM software, as follows:</P> + +<PRE> + <KBD>./configure ENTER</KBD> +</PRE> + +<H3>Choosing Compilers</H3> + +<P>If the <CODE>configure</CODE> script is unable to determine +the name of your C or C++ compiler, set the <CODE>CC</CODE> and +<CODE>CXX</CODE> environment variables to point to the C and C++ +compiler programs, respectively. You can set these variables +using the following commands in the Bourne, Korn, or Bash +shells:</P> + +<PRE> + <KBD>export CC=/foo/bar/gcc ENTER + export CXX=/foo/bar/gcc ENTER</KBD> +</PRE> + +<P>If you are using C shell or tcsh, use the following commands +instead:</P> + +<PRE> + <KBD>setenv CC /foo/bar/gcc ENTER + setenv CXX /foo/bar/gcc ENTER</KBD> +</PRE> + +<P>Run the <CODE>configure</CODE> script again to use the new +commands.</P> + +<H3>Choosing Installation Directories</H3> + +<P>The default installation prefix is <VAR>/usr</VAR>, which +will place the EPM programs in <VAR>/usr/bin</VAR>, the setup +GUI in <VAR>/usr/lib/epm</VAR>, and the man pages in +<VAR>/usr/man</VAR>. Use the <CODE>--prefix</CODE> option to +relocate these files</P> + +<P>to another directory:</P> + +<PRE> + <KBD>./configure --prefix=/usr/local ENTER</KBD> +</PRE> + +<P>The <CODE>configure</CODE> script also accepts the +<CODE>--bindir</CODE>, <CODE>--libdir</CODE>, and +<CODE>--mandir</CODE> options to relocate each directory +separately, as follows: + +<PRE> + <KBD>./configure --bindir=/usr/local/bin --libdir=/usr/local/lib \ + --mandir=/usr/local/share/man ENTER</KBD> +</PRE> + +<H3>Options for the Setup GUI</H3> + +<P>The setup GUI requires the FLTK library. The configure script +will look for the <CODE>fltk-config</CODE> utility that comes +with FLTK 1.1.x. Set the FLTKCONFIG environment variable to the +full path of this utility if it cannot be found in the current +path:</P> + +<PRE> + <KBD>setenv FLTKCONFIG /foo/bar/bin/fltk-config ENTER</KBD> +</PRE> + +<P>or:</P> + +<PRE> + <KBD>FLTKCONFIG=/foo/bar/bin/fltk-config ENTER + export FLTKCONFIG</KBD> +</PRE> + +<H2>Building the Software</H2> + +<P>Once you have configured the software, type the following +command to compile it:</P> + +<PRE> + <KBD>make ENTER</KBD> +</PRE> + +<P>Compilation should take a few minutes at most. Then type the +following command to determine if the software</P> + +<P>compiled successfully:</P> + +<PRE> + <KBD>make test ENTER</KBD> + Portable distribution build test PASSED. + Native distribution build test PASSED. +</PRE> + +<P>The <CODE>test</CODE> target builds a portable and native +distribution of EPM and reports if the two distributions were +generated successfully.</P> + +<H2>Installing the Software</H2> + +<P>Now that you have compiled and tested the software, you can +install it using the <CODE>make</CODE> command or one of the +distributions that was created. You should be logged in as the +super-user unless you specified installation directories for +which you have write permission. The <CODE>su(8)</CODE> command +is usually sufficient to install software:</P> + +<PRE> + <KBD>su ENTER</KBD> +</PRE> + +<P>Operating systems such as MacOS X do not enable the root +account by default. The <CODE>sudo(8)</CODE> command is used +instead:</P> + +<PRE> + <KBD>sudo <I>installation command</I> ENTER</KBD> +</PRE> + +<!-- NEED 2in --> +<H3>Installing Using the <CODE>make</CODE> Command</H3> + +<P>Type the following command to install the EPM software using the +<CODE>make</CODE> command:</P> + +<PRE> + <KBD>make install ENTER</KBD> + Installing EPM setup in /usr/lib/epm + Installing EPM programs in /usr/bin + Installing EPM manpages in /usr/man/man1 + Installing EPM documentation in /usr/share/doc/epm +</PRE> + +<P>Use the <CODE>sudo</CODE> command to install on MacOS X:</P> + +<PRE> + <KBD>sudo make install ENTER</KBD> + Installing EPM setup in /usr/lib/epm + Installing EPM programs in /usr/bin + Installing EPM manpages in /usr/man/man1 + Installing EPM documentation in /usr/share/doc/epm +</PRE> + +<H3><A NAME="INSTALL_PORTABLE">Installing Using the Portable +Distribution</A></H3> + +<P>The portable distribution can be found in a subdirectory +named using the operating system, version, and architecture. For +example, the subdirectory for a Linux 2.4.x system on an +Intel-based system would be <VAR>linux-2.4-intel</VAR>. The +subdirectory name is built from the following template:</P> + +<PRE> + <I>os-major.minor-architecture</I> +</PRE> + +<P>The <CODE>os</CODE> name is the common name for the operating +system. <A HREF="#TABLE_2_1">Table 2.1</A> lists the +abbreviations for most operating systems.</P> + +<P>The <CODE>major.minor</CODE> string is the operating system +version number. Any patch revision information is stripped from +the version number, as are leading characters before the major +version number. For example, HP-UX version B.11.11 will result +in a version number string of <CODE>11.11</CODE>.</P> + +<P> </P> + +<CENTER><TABLE BORDER CELLPADDING="2"> +<CAPTION><A NAME="TABLE_2_1">Table 2.1: Operating System Name Abbreviations</A></CAPTION> +<TR> + <TH>Operating System</TH> + <TH>Name</TH> +</TR> +<TR> + <TD>AIX</TD> + <TD><CODE>aix</CODE></TD> +</TR> +<TR> + <TD>Compaq Tru64 UNIX<BR> + Digital UNIX<BR> + OSF/1</TD> + <TD><CODE>tru64</CODE></TD> +</TR> +<TR> + <TD>FreeBSD</TD> + <TD><CODE>freebsd</CODE></TD> +</TR> +<TR> + <TD>HP-UX</TD> + <TD><CODE>hpux</CODE></TD> +</TR> +<TR> + <TD>IRIX</TD> + <TD><CODE>irix</CODE></TD> +</TR> +<TR> + <TD>Linux</TD> + <TD><CODE>linux</CODE></TD> +</TR> +<TR> + <TD>MacOS X</TD> + <TD><CODE>macosx</CODE></TD> +</TR> +<TR> + <TD>NetBSD</TD> + <TD><CODE>netbsd</CODE></TD> +</TR> +<TR> + <TD>OpenBSD</TD> + <TD><CODE>openbsd</CODE></TD> +</TR> +<TR> + <TD>Solaris</TD> + <TD><CODE>solaris</CODE></TD> +</TR> +</TABLE></CENTER> + +<!-- NEED 3in --> +<CENTER><TABLE BORDER CELLPADDING="2"> +<CAPTION><A NAME="TABLE_2_2">Table 2.2: Processor Architecture Abbreviations</A></CAPTION> +<TR> + <TH>Processor(s)</TH> + <TH>Abbreviation</TH> +</TR> +<TR> + <TD>Compaq Alpha</TD> + <TD><CODE>alpha</CODE></TD> +</TR> +<TR> + <TD>HP Precision Architecture</TD> + <TD><CODE>hppa</CODE></TD> +</TR> +<TR> + <TD>INTEL 80x86</TD> + <TD><CODE>intel</CODE></TD> +</TR> +<TR> + <TD>INTEL 80x86 w/64bit Extensions</TD> + <TD><CODE>x86_64</CODE></TD> +</TR> +<TR> + <TD>MIPS RISC</TD> + <TD><CODE>mips</CODE></TD> +</TR> +<TR> + <TD>IBM Power PC</TD> + <TD><CODE>powerpc</CODE></TD> +</TR> +<TR> + <TD>SPARC<BR> + MicroSPARC<BR> + UltraSPARC</TD> + <TD><CODE>sparc</CODE></TD> +</TR> +</TABLE></CENTER> + +<P> </P> + +<P>The <CODE>architecture</CODE> string identifies the target +processor. <A HREF="#TABLE_2_2">Table 2.2</A> lists the supported +processors.</P> + +<P>Once you have determined the subdirectory containing the +distribution, type the following commands to install EPM from +the portable distribution:</P> + +<PRE> + <KBD>cd <I>os-major.minor-architecture<I> ENTER + ./epm.install ENTER</KBD> +</PRE> + +<P>The software will be installed after answering a few yes/no +questions.</P> + +<H3>Installing Using the Native Distribution</H3> + +<P>The <CODE>test</CODE> target also builds a distribution in the +native operating system format, if supported. <A +HREF="#TABLE_2_3">Table 2.3</A> lists the native formats for each +supported operating system and the command to run to install the +software.</P> + +<!-- NEED 5in --> +<CENTER><TABLE BORDER CELLPADDING="2"> +<CAPTION><A NAME="TABLE_2_3">Table 2.3: Native Operating System Formats</A></CAPTION> +<TR> + <TH>Operating System</TH> + <TH>Format</TH> + <TH>Command</TH> +</TR> +<TR> + <TD>AIX</TD> + <TD><CODE>aix</CODE></TD> + <TD NOWRAP><CODE>installp -d<I>directory</I> epm</CODE></TD> +</TR> +<TR> + <TD>Compaq Tru64 UNIX<BR> + Digital UNIX<BR> + OSF/1</TD> + <TD><CODE>setld</CODE></TD> + <TD NOWRAP><CODE>setld -a <I>directory</I></CODE></TD> +</TR> +<TR> + <TD>FreeBSD<BR> + NetBSD<BR> + OpenBSD</TD> + <TD><CODE>bsd</CODE></TD> + <TD NOWRAP><CODE>cd <I>directory</I><BR> + pkg_add epm</CODE></TD> +</TR> +<TR> + <TD>HP-UX</TD> + <TD><CODE>depot</CODE></TD> + <TD NOWRAP><CODE>swinstall -f <I>directory</I></CODE></TD> +</TR> +<TR> + <TD>IRIX</TD> + <TD><CODE>inst</CODE></TD> + <TD NOWRAP><CODE>swmgr -f <I>directory</I></CODE></TD> +</TR> +<TR> + <TD>Linux</TD> + <TD><CODE>rpm</CODE></TD> + <TD NOWRAP><CODE>rpm -i <I>directory</I>/epm-4.1.rpm</CODE></TD> +</TR> +<TR> + <TD>MacOS X</TD> + <TD><CODE>osx</CODE></TD> + <TD NOWRAP><CODE>open <I>directory</I>/<CODE>epm-4.1.pkg</CODE></TD> +</TR> +<TR> + <TD>Solaris</TD> + <TD><CODE>pkg</CODE></TD> + <TD NOWRAP><CODE>pkgadd -d <I>directory</I> epm</CODE></TD> +</TR> +</TABLE></CENTER> + +</BODY> +</HTML> diff --git a/doc/3-packaging.html b/doc/3-packaging.html new file mode 100644 index 0000000..092ad0b --- /dev/null +++ b/doc/3-packaging.html @@ -0,0 +1,367 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="PACKAGING">3 - Packaging Your Software with EPM</A></H1> + +<P>This chapter describes how to use EPM to package your own software +packages.</P> + +<H2>The Basics</H2> + +<P>EPM reads one or more software "list" files that describe a +single software package. Each list file contains one or more +lines of ASCII text containing product or file information.</P> + +<P>Comments lines start with the <CODE>#</CODE> character, +directive lines start with the <CODE>%</CODE> character, +variables lines start with the <CODE>$</CODE> character, and +file, directory, init script, and symlink lines start with a +letter.</P> + +<!-- NEED 3in --> +<H3>Product Information</H3> + +<P>Every list file needs to define the product name, copyright, description, +license, README file, vendor, and version:</P> + +<PRE> + %product Kung Foo Firewall + %copyright 1999-2005 by Foo Industries, All Rights Reserved. + %vendor Foo Industries + %license COPYING + %readme README + %description Kung Foo firewall software for your firewall. + %version 1.2.3p4 1020304 +</PRE> + +<P>The <CODE>%license</CODE> and <CODE>%readme</CODE> directives +specify files for the license agreement and README files for the +package, respectively.</P> + +<P>The <CODE>%product</CODE>, <CODE>%copyright</CODE>, +<CODE>%vendor</CODE>, and <CODE>%description</CODE> directives +take text directly from the line. + +<P>The <CODE>%version</CODE> directive specifies the version +numbers of the package. The first number is the human-readable +version number, while the second number is the integer version +number. If you omit the integer version number, EPM will +calculate one for you.</P> + +<H3>Files, Directories, and Symlinks</H3> + +<P>Each file in the distribution is listed on a line starting +with a letter. The format of all lines is: + +<PRE> + type mode owner group destination source <I>options</I> +</PRE> + +<P>Regular files use the letter <CODE>f</CODE> for the type +field:</P> + +<PRE> + f 755 root sys /usr/bin/foo foo +</PRE> + +<P>Configuration files use the letter <CODE>c</CODE> for the +type field:</P> + +<PRE> + c 644 root sys /etc/foo.conf foo.conf +</PRE> + +<!-- NEED 2in --> +<P>Directories use the letter <CODE>d</CODE> for the type field +and use a source path of "-":</P> + +<PRE> + d 755 root sys /var/spool/foo - +</PRE> + +<P>Finally, symbolic links use the letter <CODE>l</CODE> (lowercase L) for the type field:</P> + +<PRE> + l 000 root sys /usr/bin/foobar foo +</PRE> + +<P>The source field specifies the file to link to and can be a +relative path.</P> + +<H3>Wildcards</H3> + +<P>Wildcard patterns can be used in the source field to include multiple +files on a single line: + +<PRE> + f 0444 root sys /usr/share/doc/foo *.html +</PRE> + +<!-- NEED 3in --> +<H3>Subpackages</H3> + +<P>Subpackages are optional parts of your software package. For +example, if your package includes developer files, you might +provide them as a subpackage so that users that will not be +developing add-ons to your software can omit them from the +installation.</P> + +<CENTER><TABLE BORDER WIDTH="80%" BGCOLOR="#cccccc" CELLPADDING="5"> +<TR><TD><B>Note:</B><BR> +Subpackages are implemented as native subsets of the main package +for the AIX, HPUX, IRIX, Solaris, and Tru64 formats and as +separate packages that depend on the main (parent) package for +all other formats.</TD></TR> +</TABLE></CENTER> + +<P>To define a subpackage, use the <CODE>%subpackage</CODE> +directive followed by a <CODE>%description</CODE> directive:</P> + +<PRE> + %subpackage foo + %description One-Line Description of Foo +</PRE> + +<P>Files, scripts, and dependencies that follow the +<CODE>%subpackage</CODE> directive are treated as part of that +subpackage. Specifying the <CODE>%subpackage</CODE> directive +with no name returns processing to the main (parent) package.</P> + +<!-- NEED 2in --> +<P>You can alternate between subpackages as many times as you +like:</P> + +<PRE> + %description Main package description + f 0755 /usr/bin/bar bar + + %subpackage foo + %description Foo programs + f 0755 /usr/bin/foo foo + %requires bla + + %subpackage + f 0644 /usr/share/man/man1/bar.1 + + %subpackage foo + f 0644 /usr/share/man/man1/foo.1 +</PRE> + +<P>The above example creates a package containing the "bar" +program and man page with a subpackage containing the "foo" +program and man page. The "foo" subpackage depends both on the +main package (implicit <CODE>%requires</CODE>) and another +package called "bla".</P> + +<!-- NEED 2in --> +<H2>Building a Software Package</H2> + +<P>The <CODE>epm(1)</CODE> program is used to build software +package from list files. To build a portable software package for +an application called "foo", type the following command:</P> + +<PRE> + <KBD>epm foo ENTER</KBD> +</PRE> + +<P>If your application uses a different base name than the list +file, you can specify the list filename on the command-line as +well:</P> + +<PRE> + <KBD>epm foo bar.list ENTER</KBD> +</PRE> + + +<CENTER><TABLE> +<CAPTION ALIGN="BOTTOM"><A NAME="FIGURE_3_1">Figure 3.1: The EPM +Setup GUI</A></CAPTION> +<TR><TD><IMG SRC="setup.png"></TD></TR> +</TABLE></CENTER> + +<P> </P> + +<H3>Installing the Software Package</H3> + +<P>Once you have created the software package, you can install +it. Portable packages include an installation script called +<VAR>product.install</VAR>, where "product" is the name of the +package:</P> + +<PRE> + <KBD>cd os-release-arch ENTER + ./product.install ENTER</KBD> +</PRE> + +<P>After answering a few yes/no questions, the software will be +installed. To bypass the questions, run the script with the +<CODE>now</CODE> argument:</P> + +<PRE> + <KBD>cd os-release-arch ENTER + ./product.install now ENTER</KBD> + +</PRE> + +<H3>Including the Setup GUI</H3> + +<P>EPM also provides an optional graphical setup program (<A +HREF="#FIGURE_3_1">Figure 3.1</A>). To include the setup program +in your distributions, create a product logo image in GIF or XPM +format and use the <CODE>--setup-image</CODE> option when +creating your distribution:</P> + +<PRE> + <KBD>epm --setup-image foo.xpm foo ENTER</KBD> +</PRE> + +<P>This option is only supported when creating for portable and +MacOS X software packages.</P> + +<!-- NEED 5in --> +<H3>Creating Vendor Package Files</H3> + +<P>EPM can also produce vendor-specific packages using the +<CODE>-f</CODE> option: + +<PRE> + <KBD>epm -f format foo bar.list ENTER</KBD> +</PRE> + +<P>The <I>format</I> option can be one of the following keywords: + +<UL> + + <LI><CODE>aix</CODE> - AIX software packages. + + <LI><CODE>bsd</CODE> - FreeBSD, NetBSD, or OpenBSD + software packages. + + <LI><CODE>depot</CODE> or <CODE>swinstall</CODE> - HP-UX + software packages. + + <LI><CODE>dpkg</CODE> - Debian software packages. + + <LI><CODE>inst</CODE> or <CODE>tardist</CODE> - IRIX + software packages. + + <LI><CODE>native</CODE> - "Native" software packages + (RPM, INST, DEPOT, PKG, etc.) for the platform. + + <LI><CODE>osx</CODE> - MacOS X software packages. + + <LI><CODE>pkg</CODE> - Solaris software packages. + + <LI><CODE>portable</CODE> - Portable software + packages (default). + + <LI><CODE>rpm</CODE> - Red Hat software packages. + + <LI><CODE>setld</CODE> - Tru64 (setld) software + packages. + + <LI><CODE>slackware</CODE> - Slackware software + packages. + +</UL> + +<P>Everything in the software list file stays the same - you just +use the <CODE>-f</CODE> option to select the format. For +example, to build an RPM distribution of EPM, type:</P> + +<PRE> + epm -f rpm epm +</PRE> + +<P>The result will be one or more RPM package files instead of +the portable package files.</P> + +<H2>Package Files</H2> + +<P>EPM creates the package files in the output directory. As +mentioned in <A HREF="#INSTALL_PORTABLE">Chapter 1, "Installing +Using the Portable Distribution"</A>, the default output +directory is based on the operating system name, version, and +architecture. Each package format will leave different files in +the output directory.</P> + +<H3>AIX Package Files</H3> + +<P>AIX packages are contained in a file called +<VAR>name.bff</VAR>, where "name" is the product/package name you +supplied on the command-line.</P> + +<H3>BSD Package Files</H3> + +<P>BSD packages are contained in a file called +<VAR>name.tgz</VAR>, where "name" is the product/package name you +supplied on the command-line.</P> + +<H3>HP-UX Package Files</H3> + +<P>HP-UX packages are contained in two files called +<VAR>name.depot.gz</VAR> and <VAR>name.depot.tgz</VAR>, where +"name" is the product/package name you supplied on the +command-line. The <VAR>name.depot.gz</VAR> file can be supplied +directly to the <CODE>swinstall(1m)</CODE> command, while the +<VAR>name.depot.tgz</VAR> file contains a compressed +<CODE>tar(1)</CODE> archive that can be used to install the +software from CD-ROM or network filesystem.</P> + +<H3>Debian Package Files</H3> + +<P>Debian packages are contained in a file called +<VAR>name.deb</VAR> or <VAR>name.deb.tgz</VAR> when there are +subpackages, where "name" is the product/package name you +supplied on the command-line. The <VAR>name.deb.tgz</VAR> file +contains a compressed <CODE>tar</CODE> archive containing +<VAR>name.deb</VAR> and <VAR>name-subpackage.deb</VAR> files that +can be installed from CD-ROM, disk, or network filesystem.</P> + +<H3>IRIX Package Files</H3> + +<P>IRIX packages are contained in a file called +<VAR>name.tardist</VAR>, where "name" is the product/package name +you supplied on the command-line.</P> + +<H3>MacOS X Package Files</H3> + +<P>MacOS X packages are contained in a file called +<VAR>name.dmg</VAR>, where "name" is the product/package name you +supplied on the command-line.</P> + +<H3>RPM Package Files</H3> + +<P>RPM packages are contained in a file called +<VAR>name.rpm</VAR> or <VAR>name.rpm.tgz</VAR> when there are +subpackages, where "name" is the product/package name you +supplied on the command-line. The <VAR>name.rpm.tgz</VAR> file +contains a compressed <CODE>tar</CODE> archive containing +<VAR>name.rpm</VAR> and <VAR>name-subpackage.rpm</VAR> files that +can be installed from CD-ROM, disk, or network filesystem.</P> + +<H3>Slackware Package Files</H3> + +<P>Slackware packages are contained in a file called +<VAR>name.tgz</VAR>, where "name" is the product/package name you +supplied on the command-line.</P> + +<H3>Solaris Package Files</H3> + +<P>Solaris packages are contained in two files called +<VAR>name.pkg.gz</VAR> and <VAR>name.pkg.tgz</VAR>, where "name" +is the product/package name you supplied on the command-line. The +<VAR>name.pkg.gz</VAR> file is a compressed package file that can +be used directly with the <CODE>pkgadd(1m)</CODE> command, while +the <VAR>name.pkg.tgz</VAR> file is a compressed <CODE>tar</CODE> +archive that can be used to install the software from CD-ROM, +disk, or network filesystem.</P> + +<H3>Tru64 Package Files</H3> + +<P>Tru64 packages are contained in a file called +<VAR>name.tar.gz</VAR>, where "name" is the product/package name +you supplied on the command-line.</P> + +</BODY> +</HTML> diff --git a/doc/4-advanced.html b/doc/4-advanced.html new file mode 100644 index 0000000..128794d --- /dev/null +++ b/doc/4-advanced.html @@ -0,0 +1,615 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="ADVANCED">4 - Advanced Packaging with EPM</A></H1> + +<P>This chapter describes the advanced packaging features of EPM.</P> + +<H2>Including Other List Files</H2> + +<P>The <CODE>%include</CODE> directive includes another list +file:</P> + +<PRE> + %include filename +</PRE> + +<P>Includes can usually be nested up to 250 levels depending on +the host operating system and libraries.</P> + +<H2>Dependencies</H2> + +<P>EPM supports four types of dependencies in list files: +<CODE>%incompat</CODE>, <CODE>%provides</CODE>, +<CODE>%replaces</CODE>, and <CODE>%requires</CODE>. <A +HREF="#TABLE_4_1">Table 4.1</A> shows the level of support for +each package format.</P> + +<!-- NEED 5in --> +<CENTER><TABLE BORDER CELLPADDING="2"> +<CAPTION><A NAME="TABLE_4_1">Table 4.1: Dependency Support</A></CAPTION> +<TR> + <TH>Format</TH> + <TH>%incompat</TH> + <TH>%provides</TH> + <TH>%replaces</TH> + <TH>%requires</TH> +</TR> +<TR> + <TD ALIGN="CENTER">aix</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">bsd</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">deb</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes<SUP>1</SUP></TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">inst</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">osx</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">pkg</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">portable</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">rpm</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">setld</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">slackware</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">swinstall</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +</TABLE></CENTER> + +<OL> + + <LI>Debian's package format does not currently support + version numbers for <CODE>%provides</CODE> + dependencies.</LI> + +</OL> + +<P> </P> + +<P>Software conflicts and requirements are specified using the +<CODE>%incompat</CODE> and <CODE>%requires</CODE> directives.</P> + +<P>If your software replaces another package, you can specify +that using the <CODE>%replaces</CODE> directive. +<CODE>%replaces</CODE> is silently mapped to +<CODE>%incompat</CODE> when the package format does not support +package replacement.</P> + +<P>If your package provides certain functionality associated with +a standard name, the <CODE>%provides</CODE> directive can be +used.</P> + +<!-- NEED 1in --> +<P>Dependencies are specified using the package name and optionally the +lower and upper version numbers: + +<PRE> + %requires foobar + %requires foobar 1.0 + %incompat foobar 0.9 + %replaces foobar + %replaces foobar 1.2 3.4 + %provides foobar +</PRE> + +<P>or the filename:</P> + +<PRE> + %requires /usr/lib/libfoobar.so + %incompat /usr/lib/libfoobar.so.1.2 +</PRE> + +<P>Package dependencies are currently enforced only for the same +package format, so a portable distribution that requires package +"foobar" will only look for an installed "foobar" package in +portable format.</P> + + +<P>Filename dependencies are only supported by the Debian, +portable, and RPM distribution formats. + +<H2>Scripts</H2> + +<P>Bourne shell script commands can be executed before or after +installation, patching, or removal of the software. <A +HREF="#TABLE_4_2">Table 4.2</A> shows the support for scripts in +each package format.</P> + +<P>The <CODE>%preinstall</CODE> and <CODE>%postinstall</CODE> +directives specify commands to be run before and after +installation, respectively:</P> + +<PRE> + %preinstall echo Command before installing + %postinstall echo Command after installing +</PRE> + +<P>Similarly, the <CODE>%prepatch</CODE> and <CODE>%postpatch</CODE> +directives specify commands to be executed before and after patching +the software:</P> + +<PRE> + %prepatch echo Command before patching + %postpatch echo Command after patching +</PRE> + +<P>Finally, the <CODE>%preremove</CODE> and <CODE>%postremove</CODE> +directives specify commands that are run before and after removal +of the software:</P> + +<PRE> + %preremove echo Command before removing + %postremove echo Command after removing +</PRE> + +<!-- NEED 3in --> +<CENTER><TABLE ALIGN="CENTER" BORDER="1"> +<CAPTION><A NAME="TABLE_4_2">Table 4.2: Scripts Support</A></CAPTION> +<TR> + <TH><SMALL>Format</SMALL></TH> + <TH><SMALL>%preinstall</SMALL></TH> + <TH><SMALL>%postinstall</SMALL></TH> + <TH><SMALL>%prepatch</SMALL></TH> + <TH><SMALL>%postpatch</SMALL></TH> + <TH><SMALL>%preremove</SMALL></TH> + <TH><SMALL>%postremove</SMALL></TH> +</TR> +<TR> + <TD ALIGN="CENTER">aix</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">bsd</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">deb</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">inst</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">osx</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">pkg</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">portable</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">rpm</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">setld</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +<TR> + <TD ALIGN="CENTER">slackware</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> +</TR> +<TR> + <TD ALIGN="CENTER">swinstall</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">No</TD> + <TD ALIGN="CENTER">Yes</TD> + <TD ALIGN="CENTER">Yes</TD> +</TR> +</TABLE></CENTER> + +<P> </P> + +<P>To include an external script file, use the +<CODE><filename</CODE> notation:</P> + +<PRE> + %postinstall <filename +</PRE> + +<P>To include multiple lines directly, use the +<CODE><<string</CODE> notation (a.k.a. a "here" document):</P> + +<PRE> + %postinstall <<EOF + echo Command before installing + /usr/bin/foo + EOF +</PRE> + +<P>Note that all commands specified in the list file will use +the variable expansion provided by EPM, so be sure to quote any +dollar sign (<CODE>$</CODE>) characters in your commands. For +example, "$foo" is replaced by the value of "foo", but "$$foo" +becomes "$foo".</P> + +<!-- NEED 4in --> +<H2>Conditional Directives</H2> + +<P>The <CODE>%system</CODE> directive can match or not match +specific operating system names or versions. The operating +system name is the name reported by <CODE>uname</CODE> in +lowercase, while the operating system version is the major and +minor version number reported by <CODE>uname -r</CODE>: + +<DL><DD><DL> + + <DT><CODE>%system irix</CODE> + <BR> </DT> + + <DD>Only include the following files when building a distribution + for the IRIX operating system. + <BR> </DD> + + <DT><CODE>%system linux-2.0</CODE> + <BR> </DT> + + <DD>Only include the following files when building a distribution + for Linux 2.0.x. + <BR> </DD> + + <DT><CODE>%system !irix !linux-2.0</CODE> + <BR> </DT> + + <DD>Only include the following files when building a distribution + for operating systems other than IRIX and Linux 2.0.x. + <BR> </DD> + +</DL></DD></DL> + +<P>The special name <CODE>all</CODE> is used to match all +operating systems:</P> + +<PRE> + %system all +</PRE> + +<P>For format-specific files, the <CODE>%format</CODE> directive +can be used:</P> + +<DL><DD><DL> + + <DT><CODE>%format rpm</CODE> + <BR> </DT> + + <DD>Only include the following files when building an RPM distribution. + <BR> </DD> + + <DT><CODE>%format !rpm</CODE> + <BR> </DT> + + <DD>Only include the following files when not building an RPM + distribution.x. + <BR> </DD> + + <DT><CODE>%format all</CODE> + <BR> </DT> + + <DD>Include the following files for all types of distributions. + <BR> </DD> + +</DL></DD></DL> + +<P>The <CODE>%arch</CODE> directive can match or not match specific +architectures. The architecture name is the name reported by +<CODE>uname -m</CODE>; "arm" is a synonym for "armv6", "armv7", and "armv8", +"intel" is a synonym for "i386", "i486", "i586", and "i686", and "powerpc" is a +synonym for "ppc":</P> + +<DL><DD><DL> + + <DT><CODE>%arch intel</CODE> + <BR> </DT> + + <DD>Only include the following files when building a package for 32-bit + Intel processors. + <BR> </DD> + + <DT><CODE>%arch armv6</CODE> + <BR> </DT> + + <DD>Only include the following files when building a package for ARMv6 + processors. + <BR> </DD> + + <DT><CODE>%system !powerpc</CODE> + <BR> </DT> + + <DD>Only include the following files when building a package for + processors other than PowerPC. + <BR> </DD> + +</DL></DD></DL> + +<P>The special name <CODE>all</CODE> is used to match all architectures:</P> + +<PRE> + %arch all +</PRE> + +<P>Finally, EPM can conditionally include lines using the +<CODE>%if</CODE>, <CODE>%elseif</CODE>, <CODE>%ifdef</CODE>, +<CODE>%elseifdef</CODE>, <CODE>%else</CODE>, and +<CODE>%endif</CODE> directives.</P> + +<P><CODE>%if</CODE> directives include the text that follows if +the named variable(s) are defined to a non-empty string:</P> + +<PRE> + %if FOO + f 755 root sys /usr/bin/foo foo + %elseif BAR + f 755 root sys /usr/bin/bar bar + %endif +</PRE> + +<P><CODE>%ifdef</CODE> directives only include the text if the +named variable(s) are defined to any value:</P> + +<PRE> + %ifdef OSTYPE + f 755 root sys /usr/bin/program program-$OSTYPE + %else + f 755 root sys /usr/bin/program program.sh + %endif +</PRE> + +<H2>Protecting Object Files from Stripping</H2> + +<P>The <CODE>nostrip()</CODE> option can be included at the end +of a file line to prevent EPM from stripping the symbols and +debugging information from a file:</P> + +<PRE> + f 755 root sys /usr/lib/libfoo.so libfoo.so nostrip() +</PRE> + +<H2>Software Patches</H2> + +<P>EPM supports portable software patch distributions which +contain only the differences between the original and patch +release. Patch files are specified using uppercase letters for +the affected files. In the following example, the files +<VAR>/usr/bin/bar</VAR> and <VAR>/etc/foo.conf</VAR> are +marked</P> + +<!-- NEED 2in --> +<P>as changed since the original release:</P> + +<PRE> + f 755 root sys /usr/bin/foo foo + F 755 root sys /usr/bin/bar bar + f 755 root sys /usr/share/man/man1/foo.1 foo.man + f 755 root sys /usr/share/man/man1/bar.1 bar.man + C 644 root sys /etc/foo.conf foo.conf +</PRE> + +<H2>Variables</H2> + +<P>EPM imports the current environment variables for use in your +list file. You can also define new variable in the list file or +on the command-line when running EPM.</P> + +<P>Variables are defined by starting the line with the dollar +sign (<CODE>$</CODE>) followed by the name and value:</P> + +<PRE> + $name=value + $prefix=/usr + $exec_prefix=${prefix} + $bindir=$exec_prefix/bin +</PRE> + +<P>Variable substitution is performed when the variable is +defined, so be careful with the ordering of your variable +definitions.</P> + +<P>Also, any variables you specify in your list file will be +overridden by variables defined on the command-line or in your +environment, just like with <CODE>make</CODE>. This can be a +useful feature or a curse, depending on your choice of variable +names.</P> + +<P>As you can see, variables are referenced using the dollar +sign (<CODE>$</CODE>). As with most shells, variable names can +be surrounded by curly braces (<CODE>${variable}</CODE>) to +explicitly delimit the name.</P> + +<!-- NEED 1in --> +<P>If you need to insert a <CODE>$</CODE> in a filename or a +script, use <CODE>$$</CODE>:</P> + +<PRE> + %install echo Enter your name: + %install read $$name + %install echo Your name is $$name. +</PRE> + +<H2>Init Scripts</H2> + +<P>Initialization scripts are generally portable between +platforms, however the location of initialization scripts varies +greatly.</P> + +<P>The <CODE>i</CODE> file type can be used to specify and init +script that is to be installed on the system. EPM will then +determine the appropriate init file directories to use and create +any required symbolic links to support the init script:</P> + +<PRE> + i 755 root sys foo foo.sh +</PRE> + +<P>The previous example creates an init script named +<VAR>foo</VAR> on the end-user system and will create symbolic +links to run levels 0, 2, 3, and 5 as needed, using a sequence +number of 00 (or 000) for the shutdown script and 99 (or 999) for +the startup script.</P> + +<P>To specify run levels and sequence numbers, use the +<CODE>runlevel()</CODE>, <CODE>start()</CODE>, and +<CODE>stop()</CODE> options:</P> + +<PRE> + i 755 root sys foo foo.sh "runlevel(02) start(50) stop(30)" +</PRE> + +<H2>Literal Package Data</H2> + +<P>Sometimes you need to include format-specific package data such as +keywords, signing keys, and response data. The <CODE>%literal(section)</CODE> +directive adds format-specific data to the packages you create. Literal +data is currently only supported for RPM and PKG packages.</P> + +<H3>PKG Literal Data</H3> + +<P>PKG packages support request files that are used to do batch +installations when installation commands require user input. The +<CODE>%literal(request)</CODE> directive can be used to provide this user +input:</P> + +<PRE> + %literal(request) <<EOF + John Doe + 1 Any Lane + Forest Lawn, OH 12345 + EOF +</PRE> + +<H3>RPM Literal Data</H3> + +<P>RPM packages support numerous attributes in the "spec" file that control +how the package is created and what metadata is included with the package. The +<CODE>%literal(spec)</CODE> directive can be used to provide attributes for +the spec file:</P> + +<PRE> + %literal(spec) <<EOF + %changelog + * Tue Aug 26 2008 John Doe <johndoe@domain.com> + + - Added new feature "bar" + + * Fri Aug 1 2008 John Doe <johndoe@domain.com> + + - Added new feature "foo" + EOF +</PRE> + +</BODY> +</HTML> diff --git a/doc/5-examples.html b/doc/5-examples.html new file mode 100644 index 0000000..6db2df7 --- /dev/null +++ b/doc/5-examples.html @@ -0,0 +1,738 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="EXAMPLES">5 - EPM Packaging Examples</A></H1> + +<P>This chapter shows how the EPM and CUPS software is packaged using +EPM list files. The EPM list file example highlights the basic features +of EPM, while the CUPS list file example shows the more advanced features +of EPM.</P> + +<H2>Packaging the EPM Software</H2> + +<P>The EPM software comes with its own autoconf-generated +<VAR>epm.list</VAR> file that is used to package and test EPM. +The EPM package consists of the main package plus a +"documentation" subpackage for the documentation files and a +"man" subpackage for the man pages.</P> + +<P>We start by defining variables for each of the autoconf directory +variables:</P> + +<PRE><FONT SIZE="1"> + $prefix=/usr + $exec_prefix=/usr + $bindir=${exec_prefix}/bin + $datadir=/usr/share + $docdir=${datadir}/doc/epm + $libdir=/usr/lib + $mandir=/usr/share/man + $srcdir=. +</FONT></PRE> + +<P>Then we provide the general product information that is +required for all packages; notice the use of +<CODE>${srcdir}</CODE> to reference the COPYING and README +files:</P> + +<PRE><FONT SIZE="1"> + %product ESP Package Manager + %copyright 1999-2006 by Easy Software Products, All Rights Reserved. + %vendor Easy Software Products + %license ${srcdir}/COPYING + %readme ${srcdir}/README + %description Universal software packaging tool for UNIX. + %version 4.0 400 +</FONT></PRE> + +<P>After the product information, we include all of the non-GUI +files that are part of EPM:</P> + +<PRE><FONT SIZE="1"> + # Executables + %system all + f 0555 root sys ${bindir}/epm epm + f 0555 root sys ${bindir}/epminstall epminstall + f 0555 root sys ${bindir}/mkepmlist mkepmlist + + # Documentation + %subpackage documentation + %description Documentation for EPM + f 0444 root sys ${docdir}/README $srcdir/README + f 0444 root sys ${docdir}/COPYING $srcdir/COPYING + f 0444 root sys ${docdir}/epm-book.html $srcdir/doc/epm-book.html + + # Man pages + %subpackage man + %description Man pages for EPM + f 0444 root sys ${mandir}/man1/epm.1 $srcdir/doc/epm.man + f 0444 root sys ${mandir}/man1/epminstall.1 $srcdir/doc/epminstall.man + f 0444 root sys ${mandir}/man1/mkepmlist.1 $srcdir/doc/mkepmlist.man + f 0444 root sys ${mandir}/man5/epm.list.5 $srcdir/doc/epm.list.man +</FONT></PRE> + +<P>Finally, we conditionally include the GUI files depending on +the state of a variable called <CODE>GUIS</CODE>:</P> + +<PRE><FONT SIZE="1"> + # GUI files... + $GUIS=setup uninst + + %if GUIS + %subpackage + f 0555 root sys ${libdir}/epm/setup setup + f 0555 root sys ${libdir}/epm/uninst uninst + + %system darwin + f 0444 root sys ${datadir}/epm/setup.icns macosx/setup.icns + f 0444 root sys ${datadir}/epm/setup.info macosx/setup.info + f 0444 root sys ${datadir}/epm/setup.plist macosx/setup.plist + + f 0444 root sys ${datadir}/epm/uninst.icns macosx/uninst.icns + f 0444 root sys ${datadir}/epm/uninst.info macosx/uninst.info + f 0444 root sys ${datadir}/epm/uninst.plist macosx/uninst.plist + %system all + + %subpackage man + f 0444 root sys ${mandir}/man1/setup.1 $srcdir/doc/setup.man + f 0444 root sys ${mandir}/man5/setup.types.5 $srcdir/doc/setup.types.man + + %endif +</FONT></PRE> + + +<H2>Packaging the CUPS Software</H2> + +<P>The Common UNIX Printing System provides an EPM list file to +generate software distributions for most UNIX operating systems. +This list file is more complex than the EPM example and contains +several subpackages:</P> + +<UL> + + <LI>"devel"; Developer header, library, and documentation files</LI> + + <LI>"es"; Spanish localization files</LI> + + <LI>"ja"; Japanese localization files</LI> + + <LI>"libs"; Shared libraries</LI> + + <LI>"lpd"; LPD client support</LI> + +</UL> + +<H3>Variables Used for the Distribution</H3> + +<P>In addition to the autoconf variables defined in the EPM list +file, the CUPS list file defines the following autoconf-derived +variables for the distribution:</P> + +<UL> + + <LI><CODE>AMANDIR</CODE>; + The directory for administrative manual pages. + + <LI><CODE>BINDIR</CODE>; + The directory for user programs. + + <LI><CODE>CACHEDIR</CODE>; + The directory for cache files. + + <LI><CODE>DATADIR</CODE>; + The directory for data files. + + <LI><CODE>DOCDIR</CODE>; + The directory for documentation files. + + <LI><CODE>INCLUDEDIR</CODE>; + The directory for header files. + + <LI><CODE>INITDIR</CODE>; + The directory for startup scripts. + + <LI><CODE>INITDDIR</CODE>; + The directory to reference from run-level scripts. + + <LI><CODE>LIBDIR</CODE>; + The directory for library files. + + <LI><CODE>LIB32DIR</CODE>; + The directory for 32-bit library files. + + <LI><CODE>LIB64DIR</CODE>; + The directory for 64-bit library files. + + <LI><CODE>LOCALEDIR</CODE>; + The directory for message (localization) files. + + <LI><CODE>LOGDIR</CODE>; + The directory for log files. + + <LI><CODE>MANDIR</CODE>; + The directory for man pages. + + <LI><CODE>PAMDIR</CODE>; + The directory for PAM configuration files. + + <LI><CODE>REQUESTS</CODE>; + The directory for request files. + + <LI><CODE>SBINDIR</CODE>; + The directory for administration programs. + + <LI><CODE>SERVERBIN</CODE>; + The directory for server programs. + + <LI><CODE>SERVERROOT</CODE>; + The directory for server configuration files. + + <LI><CODE>STATEDIR</CODE>; + The directory for server state files. + +</UL> + +<H3>Product Information</H3> + +<P>The list file starts with the standard product information:</P> + +<PRE><FONT SIZE="1"> + %product Common UNIX Printing System + %copyright 1993-2006 by Easy Software Products, All Rights Reserved. + %vendor Easy Software Products + %license LICENSE.txt + %readme packaging/cups.license + %version 1.2.0 + %description The Common UNIX Printing System provides a portable + %description printing layer for UNIX(r) operating systems. It + %description has been developed by Easy Software Products to + %description promote a standard printing solution for all UNIX + %description vendors and users. CUPS provides the System V and + %description Berkeley command-line interfaces. +</FONT></PRE> + +<P>We then list different dependencies depending on the package +format:</P> + +<PRE><FONT SIZE="1"> + %format rpm + %provides cups 1:1.2.0 + %provides lpd, lpr, LPRng + %replaces lpd, lpr, LPRng + + %format deb + %provides cupsys + %provides cupsys-client + %provides cupsys-bsd + + %format pkg + %replaces SUNWlpmsg LP Alerts + %replaces SUNWlpr LP Print Service, (Root) + %replaces SUNWlps LP Print Service - Server, (Usr) + %replaces SUNWlpu LP Print Service - Client, (Usr) + %replaces SUNWpsu LP Print Server, (Usr) + %replaces SUNWpsr LP Print Server, (Root) + %replaces SUNWpcu LP Print Client, (Usr) + %replaces SUNWpcr LP Print Client, (Root) + %replaces SUNWppm + %replaces SUNWmp + %replaces SUNWscplp SunOS Print Compatibility + + %format inst + %replaces patch*.print_*.* 0 0 1289999999 1289999999 + %replaces maint*.print_*.* 0 0 1289999999 1289999999 + %replaces print 0 0 1289999999 1289999999 + %replaces fw_cups 0 0 1289999999 1289999999 + %incompat patch*.print_*.* 0 0 1289999999 1289999999 + %incompat maint*.print_*.* 0 0 1289999999 1289999999 + %incompat print 0 0 1289999999 1289999999 + %incompat fw_cups 0 0 1289999999 1289999999 + + %format all +</FONT></PRE> + +<P>The subpackages come next, each with their own +dependencies:</P> + +<PRE><FONT SIZE="1"> + %subpackage libs + %description Common UNIX Printing System - shared libraries + %format rpm + %provides cups-libs 1:1.2.0 + %format deb + %provides libcups1 + %provides libcupsys2 + %provides libcupsys2-gnutls10 + %provides libcupsimage2 + %format all + + %subpackage devel + %description Common UNIX Printing System - development environment + %format rpm + %provides cups-devel 1:1.2.0 + %format deb + %provides libcupsys2-dev + %provides libcupsimage2-dev + %format all + + %subpackage lpd + %description Common UNIX Printing System - LPD support + %format rpm + %provides cups-lpd 1:1.2.0 + %format all + + %subpackage es + %description Common UNIX Printing System - Spanish support + + %subpackage ja + %description Common UNIX Printing System - Japanese support + + %subpackage +</FONT></PRE> + +<!-- NEED 3in --> +<H3>Server Programs</H3> + +<P>The server programs are installed in the <CODE>SBINDIR</CODE> +and <CODE>SERVERBIN</CODE> directories. The image and PDF filters +are conditionally included based on the <CODE>IMGFILTERS</CODE> +and <CODE>PDFTOPS</CODE> variables, respectively:</P> + +<PRE><FONT SIZE="1"> + f 0755 root sys $SBINDIR/cupsd scheduler/cupsd + + d 0755 root sys $SERVERBIN - + d 0755 root sys $SERVERBIN/backend - + f 0755 root sys $SERVERBIN/backend/ipp backend/ipp + l 0755 root sys $SERVERBIN/backend/http ipp + f 0755 root sys $SERVERBIN/backend/lpd backend/lpd + f 0755 root sys $SERVERBIN/backend/parallel backend/parallel + f 0755 root sys $SERVERBIN/backend/scsi backend/scsi + f 0755 root sys $SERVERBIN/backend/serial backend/serial + f 0755 root sys $SERVERBIN/backend/socket backend/socket + f 0755 root sys $SERVERBIN/backend/usb backend/usb + d 0755 root sys $SERVERBIN/cgi-bin - + f 0755 root sys $SERVERBIN/cgi-bin/admin.cgi cgi-bin/admin.cgi + f 0755 root sys $SERVERBIN/cgi-bin/classes.cgi cgi-bin/classes.cgi + f 0755 root sys $SERVERBIN/cgi-bin/help.cgi cgi-bin/help.cgi + f 0755 root sys $SERVERBIN/cgi-bin/jobs.cgi cgi-bin/jobs.cgi + f 0755 root sys $SERVERBIN/cgi-bin/printers.cgi cgi-bin/printers.cgi + d 0755 root sys $SERVERBIN/daemon - + f 0755 root sys $SERVERBIN/daemon/cups-deviced scheduler/cups-deviced + f 0755 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd + f 0755 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld + d 0755 root sys $SERVERBIN/driver - + d 0755 root sys $SERVERBIN/filter - + f 0755 root sys $SERVERBIN/filter/gziptoany filter/gziptoany + f 0755 root sys $SERVERBIN/filter/hpgltops filter/hpgltops + %if IMGFILTERS + f 0755 root sys $SERVERBIN/filter/imagetops filter/imagetops + f 0755 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster + %endif + %if PDFTOPS + f 0755 root sys $SERVERBIN/filter/pdftops pdftops/pdftops + %endif + f 0755 root sys $SERVERBIN/filter/pstops filter/pstops + f 0755 root sys $SERVERBIN/filter/rastertolabel filter/rastertolabel + l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel + f 0755 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson + f 0755 root sys $SERVERBIN/filter/rastertohp filter/rastertohp + f 0755 root sys $SERVERBIN/filter/texttops filter/texttops + d 0755 root sys $SERVERBIN/notifier - + f 0755 root sys $SERVERBIN/notifier/mailto notifier/mailto +</FONT></PRE> + +<P>The <CODE>cups-lpd</CODE> program goes in the "lpd" +subpackage:</P> + +<PRE><FONT SIZE="1"> + %subpackage lpd + d 0755 root sys $SERVERBIN/daemon - + f 0755 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd + %subpackage +</FONT></PRE> + +<H3>Administration Commands</H3> + +<P>The administration commands are all pretty much the same. The +only difference is that IRIX needs a symlink for the +<CODE>lpc</CODE> program in the <VAR>/usr/etc</VAR> +directory.</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $BINDIR - + l 0755 root sys $BINDIR/enable $SBINDIR/accept + l 0755 root sys $LIBDIR/accept $SBINDIR/accept + d 0755 root sys $SBINDIR - + l 0755 root sys $SBINDIR/cupsdisable accept + l 0755 root sys $SBINDIR/cupsenable accept + l 0755 root sys $BINDIR/disable $SBINDIR/accept + d 0755 root sys $LIBDIR - + l 0755 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin + l 0755 root sys $LIBDIR/reject accept + f 0755 root sys $SBINDIR/accept systemv/accept + f 0755 root sys $SBINDIR/cupsaddsmb systemv/cupsaddsmb + f 0755 root sys $SBINDIR/lpadmin systemv/lpadmin + f 0755 root sys $SBINDIR/lpc berkeley/lpc + f 0755 root sys $SBINDIR/lpinfo systemv/lpinfo + f 0755 root sys $SBINDIR/lpmove systemv/lpmove + l 0755 root sys $SBINDIR/reject accept + + %system irix + l 0755 root sys /usr/etc/lpc $SBINDIR/lpc + %system all +</FONT></PRE> + +<H3>User Commands</H3> + +<P>The user commands are all pretty much the same. As with the +administration commands, IRIX needs the Berkeley commands linked +to a different directory, <VAR>/usr/bsd</VAR>.</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $BINDIR - + f 0755 root sys $BINDIR/cancel systemv/cancel + f 0755 root sys $BINDIR/cupstestdsc systemv/cupstestdsc + f 0755 root sys $BINDIR/cupstestppd systemv/cupstestppd + f 0755 root sys $BINDIR/lp systemv/lp + f 0755 root sys $BINDIR/lpoptions systemv/lpoptions + f 4755 $CUPS_USER sys $BINDIR/lppasswd systemv/lppasswd + f 0755 root sys $BINDIR/lpq berkeley/lpq + f 0755 root sys $BINDIR/lpr berkeley/lpr + f 0755 root sys $BINDIR/lprm berkeley/lprm + f 0755 root sys $BINDIR/lpstat systemv/lpstat + + %system irix + l 0755 root sys /usr/bsd/lpq $BINDIR/lpq + l 0755 root sys /usr/bsd/lpr $BINDIR/lpr + l 0755 root sys /usr/bsd/lprm $BINDIR/lprm + %system all +</FONT></PRE> + +<H3>Shared Libraries</H3> + +<P>Shared libraries present their own challenges. AIX, HP-UX, and +MacOS X uses a different extension for shared libraries than the +other operating systems, and we only include the shared libraries +if they are enabled in the build:</P> + +<PRE><FONT SIZE="1"> + %if DSOLIBS + %subpackage libs + %system hpux + f 0755 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2 + l 0755 root sys $LIBDIR/libcups.sl libcups.sl.2 + f 0755 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2 + l 0755 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2 + %system aix + f 0755 root sys $LIBDIR/libcups_s.a cups/libcups_s.a + f 0755 root sys $LIBDIR/libcupsimage_s.a filter/libcupsimage_s.a + %system darwin + f 0755 root sys $LIBDIR/libcups.2.dylib cups/libcups.2.dylib + l 0755 root sys $LIBDIR/libcups.dylib libcups.2.dylib + f 0755 root sys $LIBDIR/libcupsimage.2.dylib filter/libcupsimage.2.dylib + l 0755 root sys $LIBDIR/libcupsimage.dylib libcupsimage.2.dylib + %system !hpux !aix !darwin + f 0755 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2 + l 0755 root sys $LIBDIR/libcups.so libcups.so.2 + f 0755 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2 + l 0755 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif +</FONT></PRE> + +<P>To keep things interesting, CUPS also supports separately +compiled 32-bit and 64-bit libraries on systems that support a +mix of 32-bit and 64-bit binaries. The <CODE>LIB32DIR</CODE> and +<CODE>LIB64DIR</CODE> variables are used to conditionally include +the corresponding libraries:</P> + +<PRE><FONT SIZE="1"> + %if LIB32DIR + %subpackage libs + f 0755 root sys $LIB32DIR/libcups.so.2 cups/libcups.32.so.2 + l 0755 root sys $LIB32DIR/libcups.so libcups.so.2 + f 0755 root sys $LIB32DIR/libcupsimage.so.2 filter/libcupsimage.32.so.2 + l 0755 root sys $LIB32DIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif + + %if LIB64DIR + %subpackage libs + f 0755 root sys $LIB64DIR/libcups.so.2 cups/libcups.64.so.2 + l 0755 root sys $LIB64DIR/libcups.so libcups.so.2 + f 0755 root sys $LIB64DIR/libcupsimage.so.2 filter/libcupsimage.64.so.2 + l 0755 root sys $LIB64DIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif +</FONT></PRE> + +<H3>Directories</H3> + +<P>The CUPS distribution uses several directories to hold the +log, request, and temporary files. The <CODE>CUPS_GROUP</CODE> +and <CODE>CUPS_PRIMARY_SYSTEM_GROUP</CODE> variables define the +group names to use for these directories:</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $LOGDIR - + d 0710 root $CUPS_GROUP $REQUESTS - + d 1770 root $CUPS_GROUP $REQUESTS/tmp - + d 0775 root $CUPS_GROUP $CACHEDIR - + d 0755 root $CUPS_GROUP $STATEDIR - + d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs - +</FONT></PRE> + +<H3>Data Files</H3> + +<P>CUPS has lots of data files. We use wildcards whenever +possible:</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $DATADIR - + + d 0755 root sys $DATADIR/banners - + f 0644 root sys $DATADIR/banners/classified data/classified + f 0644 root sys $DATADIR/banners/confidential data/confidential + f 0644 root sys $DATADIR/banners/secret data/secret + f 0644 root sys $DATADIR/banners/standard data/standard + f 0644 root sys $DATADIR/banners/topsecret data/topsecret + f 0644 root sys $DATADIR/banners/unclassified data/unclassified + + d 0755 root sys $DATADIR/charsets - + f 0644 root sys $DATADIR/charsets data/*.txt + f 0644 root sys $DATADIR/charsets/windows-874 data/windows-874 + f 0644 root sys $DATADIR/charsets/windows-1250 data/windows-1250 + f 0644 root sys $DATADIR/charsets/windows-1251 data/windows-1251 + f 0644 root sys $DATADIR/charsets/windows-1252 data/windows-1252 + f 0644 root sys $DATADIR/charsets/windows-1253 data/windows-1253 + f 0644 root sys $DATADIR/charsets/windows-1254 data/windows-1254 + f 0644 root sys $DATADIR/charsets/windows-1255 data/windows-1255 + f 0644 root sys $DATADIR/charsets/windows-1256 data/windows-1256 + f 0644 root sys $DATADIR/charsets/windows-1257 data/windows-1257 + f 0644 root sys $DATADIR/charsets/windows-1258 data/windows-1258 + f 0644 root sys $DATADIR/charsets/iso-8859-1 data/iso-8859-1 + f 0644 root sys $DATADIR/charsets/iso-8859-2 data/iso-8859-2 + f 0644 root sys $DATADIR/charsets/iso-8859-3 data/iso-8859-3 + f 0644 root sys $DATADIR/charsets/iso-8859-4 data/iso-8859-4 + f 0644 root sys $DATADIR/charsets/iso-8859-5 data/iso-8859-5 + f 0644 root sys $DATADIR/charsets/iso-8859-6 data/iso-8859-6 + f 0644 root sys $DATADIR/charsets/iso-8859-7 data/iso-8859-7 + f 0644 root sys $DATADIR/charsets/iso-8859-8 data/iso-8859-8 + f 0644 root sys $DATADIR/charsets/iso-8859-9 data/iso-8859-9 + f 0644 root sys $DATADIR/charsets/iso-8859-10 data/iso-8859-10 + f 0644 root sys $DATADIR/charsets/iso-8859-13 data/iso-8859-13 + f 0644 root sys $DATADIR/charsets/iso-8859-14 data/iso-8859-14 + f 0644 root sys $DATADIR/charsets/iso-8859-15 data/iso-8859-15 + f 0644 root sys $DATADIR/charsets/utf-8 data/utf-8 + + d 0755 root sys $DATADIR/data - + f 0644 root sys $DATADIR/data/HPGLprolog data/HPGLprolog + f 0644 root sys $DATADIR/data/psglyphs data/psglyphs + f 0644 root sys $DATADIR/data/testprint.ps data/testprint.ps + + d 0755 root sys $DATADIR/fonts - + f 0644 root sys $DATADIR/fonts fonts/Courier* + f 0644 root sys $DATADIR/fonts/Symbol fonts/Symbol + + d 0755 root sys $DATADIR/model - + f 0644 root sys $DATADIR/model ppd/*.ppd + + d 0755 root sys $DATADIR/templates - + c 0644 root sys $DATADIR/templates templates/*.tmpl +</FONT></PRE> + +<P>The template files for each of the language localizations are +put in separate subpackages:</P> + +<PRE><FONT SIZE="1"> + # Japanese template files + %subpackage es + d 0755 root sys $DATADIR/templates/es + f 0644 root sys $DATADIR/templates/es templates/es/*.tmpl + %subpackage ja + d 0755 root sys $DATADIR/templates/ja + f 0644 root sys $DATADIR/templates/ja templates/ja/*.tmpl + %subpackage +</FONT></PRE> + +<H3>Configuration Files</H3> + +<P>The server configuration files and directories go in +<CODE>SERVERROOT</CODE>. The MIME configuration files are not +treated as configuration files in the distribution since new +versions of CUPS may add filters and file types that are required +to make CUPS work:</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $SERVERROOT - + d 0755 root $CUPS_GROUP $SERVERROOT/interfaces - + d 0755 root $CUPS_GROUP $SERVERROOT/ppd - + c $CUPS_PERM root $CUPS_GROUP $SERVERROOT conf/*.conf + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/cupsd.conf.default conf/cupsd.conf + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/mime.convs conf/mime.convs + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/mime.types conf/mime.types +</FONT></PRE> + +<P>The PAM configuration file is only included if the configure +script found a PAM configuration directory:</P> + +<PRE><FONT SIZE="1"> + %if PAMDIR + d 0755 root sys $PAMDIR - + c 0644 root sys $PAMDIR/cups conf/pam.std + %endif +</FONT></PRE> + +<H3>Developer Files</H3> + +<P>The developer files include the C header files, static +libraries, and help files. The static libraries are only included +if they have been built, which is specified using the +<CODE>INSTALLSTATIC</CODE> variable:</P> + +<PRE><FONT SIZE="1"> + %subpackage devel + f 0755 root sys $BINDIR/cups-config cups-config + d 0755 root sys $INCLUDEDIR/cups - + f 0644 root sys $INCLUDEDIR/cups/cups.h cups/cups.h + f 0644 root sys $INCLUDEDIR/cups/http.h cups/http.h + f 0644 root sys $INCLUDEDIR/cups/image.h filter/image.h + f 0644 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h + f 0644 root sys $INCLUDEDIR/cups/language.h cups/language.h + f 0644 root sys $INCLUDEDIR/cups/md5.h cups/md5.h + f 0644 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h + f 0644 root sys $INCLUDEDIR/cups/raster.h filter/raster.h + + %if INSTALLSTATIC + f 0644 root sys $LIBDIR/libcups.a cups/libcups.a + f 0644 root sys $LIBDIR/libcupsimage.a filter/libcupsimage.a + %endif + + d 0755 root sys $DOCDIR/help - + f 0644 root sys $DOCDIR/help doc/help/api*.html + f 0644 root sys $DOCDIR/help doc/help/spec*.html + %subpackage +</FONT></PRE> + +<H3>Documentation Files</H3> + +<P>The documentation files go under <CODE>DOCDIR</CODE>. +Wildcards take care of most of the work:</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $DOCDIR - + f 0644 root sys $DOCDIR doc/*.css + f 0644 root sys $DOCDIR doc/*.html + d 0755 root sys $DOCDIR/help - + f 0644 root sys $DOCDIR/help/cgi.html doc/help/cgi.html + f 0644 root sys $DOCDIR/help/glossary.html doc/help/glossary.html + f 0644 root sys $DOCDIR/help/license.html doc/help/license.html + f 0644 root sys $DOCDIR/help/network.html doc/help/network.html + f 0644 root sys $DOCDIR/help/options.html doc/help/options.html + f 0644 root sys $DOCDIR/help/overview.html doc/help/overview.html + f 0644 root sys $DOCDIR/help/security.html doc/help/security.html + f 0644 root sys $DOCDIR/help/standard.html doc/help/standard.html + f 0644 root sys $DOCDIR/help/translation.html doc/help/translation.html + f 0644 root sys $DOCDIR/help/whatsnew.html doc/help/whatsnew.html + f 0644 root sys $DOCDIR/help doc/help/man-*.html + f 0644 root sys $DOCDIR/help doc/help/ref-*.html + d 0755 root sys $DOCDIR/images - + f 0644 root sys $DOCDIR/images doc/images/*.gif + f 0644 root sys $DOCDIR/images doc/images/*.jpg + f 0644 root sys $DOCDIR/images doc/images/*.png + f 0644 root sys $DOCDIR/robots.txt doc/robots.txt +</FONT></PRE> + +<P>The Japanese and Spanish version of the documentation files go +in the corresponding subpackages:</P> + +<PRE><FONT SIZE="1"> + # Localized documentation files + %subpackage es + d 0755 root sys $DOCDIR/es + f 0644 root sys $DOCDIR/es doc/es/*.html + d 0755 root sys $DOCDIR/es/images - + f 0644 root sys $DOCDIR/es/images doc/es/images/*.gif + %subpackage ja + d 0755 root sys $DOCDIR/ja + f 0644 root sys $DOCDIR/ja doc/ja/*.html + d 0755 root sys $DOCDIR/ja/images - + f 0644 root sys $DOCDIR/ja/images doc/ja/images/*.gif + %subpackage +</FONT></PRE> + +<H3>Man Pages</H3> + +<P>Man pages are almost as much fun as initialization scripts. +HP-UX, IRIX, and Solaris follow the System V convention of using +section 1m for administration commands instead of section 8 as is +used for all other operating systems. IRIX also places +administrative commands in a separate subdirectory:</P> + +<PRE><FONT SIZE="1"> + d 0755 root sys $AMANDIR - + d 0755 root sys $AMANDIR/man$MAN8DIR - + d 0755 root sys $MANDIR - + d 0755 root sys $MANDIR/man1 - + d 0755 root sys $MANDIR/man5 - + d 0755 root sys $MANDIR/man7 - + + f 0644 root sys $MANDIR/man1/cancel.$MAN1EXT man/cancel.$MAN1EXT + f 0644 root sys $MANDIR/man1/cupstestdsc.$MAN1EXT man/cupstestdsc.$MAN1EXT + f 0644 root sys $MANDIR/man1/cupstestppd.$MAN1EXT man/cupstestppd.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpoptions.$MAN1EXT man/lpoptions.$MAN1EXT + f 0644 root sys $MANDIR/man1/lppasswd.$MAN1EXT man/lppasswd.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpq.$MAN1EXT man/lpq.$MAN1EXT + f 0644 root sys $MANDIR/man1/lprm.$MAN1EXT man/lprm.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpr.$MAN1EXT man/lpr.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpstat.$MAN1EXT man/lpstat.$MAN1EXT + f 0644 root sys $MANDIR/man1/lp.$MAN1EXT man/lp.$MAN1EXT + + f 0644 root sys $MANDIR/man5/classes.conf.$MAN5EXT man/classes.conf.$MAN5EXT + f 0644 root sys $MANDIR/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.$MAN5EXT + f 0644 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.$MAN5EXT + f 0644 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.$MAN5EXT + f 0644 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.$MAN5EXT + + f 0644 root sys $MANDIR/man7/backend.$MAN7EXT man/backend.$MAN7EXT + f 0644 root sys $MANDIR/man7/filter.$MAN7EXT man/filter.$MAN7EXT + + f 0644 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT man/accept.$MAN8EXT + l 0644 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsaddsmb.$MAN8EXT man/cupsaddsmb.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cups-polld.$MAN8EXT man/cups-polld.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsd.$MAN8EXT man/cupsd.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsenable.$MAN8EXT man/cupsenable.$MAN8EXT + l 0644 root sys $AMANDIR/man$MAN8DIR/cupsdisable.$MAN8EXT cupsenable.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpadmin.$MAN8EXT man/lpadmin.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpc.$MAN8EXT man/lpc.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpinfo.$MAN8EXT man/lpinfo.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.$MAN8EXT + + %subpackage devel + f 0644 root sys $MANDIR/man1/cups-config.$MAN1EXT man/cups-config.$MAN1EXT + + %subpackage lpd + d 0755 root sys $AMANDIR/man$MAN8DIR - + f 0644 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.$MAN8EXT + %subpackage +</FONT></PRE> + +<H3>Startup Script</H3> + +<P>The CUPS startup script is last and specifies a script name of +<CODE>cups</CODE>. Startup and shutdown scripts will be created +with the (default) names <CODE>S99cups</CODE> and +<CODE>K00cups</CODE>, respectively.</P> + +<PRE><FONT SIZE="1"> + %system all + i 0555 root sys cups init/cups.sh +</FONT></PRE> + +</BODY> +</HTML> diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..eb0cae0 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,65 @@ +# +# "$Id: Makefile.in 666 2006-04-04 22:46:25Z mike $" +# +# Makefile for the ESP Package Manager (EPM) documentation. +# +# Copyright 1999-2006 by Easy Software Products, all rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +# +# Programs... +# + +CC = @CC@ +HTMLDOC = @HTMLDOC@ +NROFF = @NROFF@ +RM = @RM@ -f + + +# +# Man page generation... +# + +.SUFFIXES: .html .man +.man.html: + $(RM) $@ + ./mantohtml $< >$@ + + +# +# Targets... +# + +MANPAGES = epm.html epminstall.html mkepmlist.html setup.html +HTMLFILES = preface.html 1-intro.html 2-building.html \ + 3-packaging.html 4-advanced.html 5-examples.html \ + a-license.html b-manpages.html c-reference.html \ + d-relnotes.html $(MANPAGES) + +all: $(MANPAGES) epm-book.html + +clean: + $(RM) epm-book.html $(MANPAGES) mantohtml mantohtml.o + +epm-book.html: $(HTMLFILES) epm-book.book + $(HTMLDOC) --batch epm-book.book -f epm-book.html + +mantohtml: mantohtml.o + $(CC) -o $@ mantohtml.o + +$(MANPAGES): mantohtml + + +# +# End of "$Id: Makefile.in 666 2006-04-04 22:46:25Z mike $". +# diff --git a/doc/a-license.html b/doc/a-license.html new file mode 100644 index 0000000..6e18fb9 --- /dev/null +++ b/doc/a-license.html @@ -0,0 +1,318 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - GNU General Public License</A></H1> + +<P ALIGN=CENTER>GNU GENERAL PUBLIC LICENSE<BR> +Version 2, June 1991</P> + +<P ALIGN=CENTER>Copyright (C) 1989, 1991 Free Software Foundation, Inc.<BR> +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA<BR> +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed.</P> + +<P ALIGN=CENTER><B>GNU GENERAL PUBLIC LICENSE<BR> +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</B></P> + +<P>0. This License applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any derivative work under +copyright law: that is to say, a work containing the Program or a +portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without +limitation in the term "modification".) Each licensee is addressed as +"you".</P> + +<P>Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does.</P> + +<P>1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program.</P> + +<P>You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a +fee.</P> + +<P>2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions:</P> + +<UL> + <P>a. You must cause the modified files to carry prominent + notices stating that you changed the files and the date of any + change.</P> + + <P>b. You must cause any work that you distribute or publish, + that in whole or in part contains or is derived from the + Program or any part thereof, to be licensed as a whole at no + charge to all third parties under the terms of this + License.</P> + + <P>c. If the modified program normally reads commands + interactively when run, you must cause it, when started running + for such interactive use in the most ordinary way, to print or + display an announcement including an appropriate copyright + notice and a notice that there is no warranty (or else, saying + that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to + view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an + announcement, your work based on the Program is not required to + print an announcement.)</P> + +</UL> + +<P>These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.</P> + +<P>Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program.</P> + +<P>In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License.</P> + +<P>3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following:</P> + +<UL> + + <P>a. Accompany it with the complete corresponding + machine-readable source code, which must be distributed under + the terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or,</P> + + <P>b. Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or,</P> + + <P>c. Accompany it with the information you received as to the + offer to distribute corresponding source code. (This + alternative is allowed only for noncommercial distribution and + only if you received the program in object code or executable + form with such an offer, in accord with Subsection b above.)</P> +</UL> + +<P>The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that +is normally distributed (in either source or binary form) with the +major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies +the executable.</P> + +<P>If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to +copy the source code from the same place counts as distribution of the +source code, even though third parties are not compelled to copy the +source along with the object code.</P> + +<P>4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such parties +remain in full compliance.</P> + +<P>5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying the +Program or works based on it.</P> + +<P>6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License.</P> + +<P>7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program.</P> + +<P>If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances.</P> + +<P>It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice.</P> + +<P>This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License.</P> + +<P>8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License.</P> + +<P>9. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns.</P> + +<P>Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation.</P> + +<P>10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software +generally.</P> + +<P ALIGN=CENTER><B>NO WARRANTY</B></P> + +<P>11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS +NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE +LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS +AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF +ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P> + +<P>12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.</P> + +<P ALIGN=CENTER><B>END OF TERMS AND CONDITIONS</B></P> + +<P ALIGN=CENTER><B>HOW TO APPLY THESE TERMS TO YOUR NEW PROGRAMS</B></P> + +<P>If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +<P>To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + +<PRE> +<VAR>one line to give the program's name and an idea of what it does.</VAR> +Copyright (C) <VAR>yyyy</VAR> <VAR>name of author</VAR> + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +</PRE> + +<P>Also add information on how to contact you by electronic and +paper mail.</P> + +<P>If the program is interactive, make it output a short notice +like this when it starts in an interactive mode:</P> + +<PRE> +Gnomovision version 69, Copyright (C) <VAR>year</VAR> <VAR>name of author</VAR> +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details +type `show w'. This is free software, and you are welcome +to redistribute it under certain conditions; type `show c' +for details. +</PRE> + +<P>The hypothetical commands <SAMP>`show w'</SAMP> and <SAMP>`show c'</SAMP> should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than <SAMP>`show w'</SAMP> and +<SAMP>`show c'</SAMP>; they could even be mouse-clicks or menu items--whatever +suits your program. + +<P>You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + +<PRE> +Yoyodyne, Inc., hereby disclaims all copyright +interest in the program `Gnomovision' +(which makes passes at compilers) written +by James Hacker. + +<VAR>signature of Ty Coon</VAR>, 1 April 1989 +Ty Coon, President of Vice +</PRE> + +</BODY> +</HTML> diff --git a/doc/b-manpages.html b/doc/b-manpages.html new file mode 100644 index 0000000..3a14e5d --- /dev/null +++ b/doc/b-manpages.html @@ -0,0 +1,19 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="MANPAGES">B - Command Reference</A></H1> + +<!-- NEW PAGE --> +<EMBED SRC="epm.html"> + +<!-- NEW PAGE --> +<EMBED SRC="epminstall.html"> + +<!-- NEW PAGE --> +<EMBED SRC="mkepmlist.html"> + +<!-- NEW PAGE --> +<EMBED SRC="setup.html"> + +</BODY> +</HTML> diff --git a/doc/c-reference.html b/doc/c-reference.html new file mode 100644 index 0000000..1b44e59 --- /dev/null +++ b/doc/c-reference.html @@ -0,0 +1,455 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="REFERENCE">C - List File Reference</A></H1> + +<P>This appendix provides a complete reference for the EPM list file +and setup types formats.</P> + +<H2>The EPM List File Format</H2> + +<P>Each <I>EPM</I> product has an associated list file that +describes the files to include with the product. Comment lines +begin with the "#" character and are ignored. All other +non-blank lines must begin with a letter, dollar sign ("$"), or +the percent sign ("%").</P> + +<!-- NEED 3in --> +<H3>List File Directives</H3> + +<P>The following list describes all of the list file directives +supported by <I>EPM</I>:</P> + +<DL><DD><DL> + + <DT>$name=value + <BR> </DT> + + <DD>Sets the named variable to <I>value</I>. + <B>Note:</B> Variables set in the list file are + overridden by variables specified on the command-line or + in the current environment. + <BR> </DD> + + <!-- NEED 2in --> + <DT>%copyright <I>copyright notice</I> + <BR> </DT> + + <DD>Sets the copyright notice for the file. + <BR> </DD> + + <DT>%description <I>description text</I> + <BR> </DT> + + <DD>Adds a line of descriptive text to the distribution. + Multiple lines are supported. + <BR> </DD> + + <DT>%format <I>format [... format]</I> + <BR> </DT> + + <DD>Uses following files and directives only if the + distribution format is the same as <I>format</I>. + <BR> </DD> + + <DT>%format !<I>format [... format]</I> + <BR> </DT> + + <DD>Uses following files and directives only if the + distribution format is not the same as + <I>format</I>. + <BR> </DD> + + <DT>%include <I>filename</I> + <BR> </DT> + + <DD>Includes files listed in <I>filename</I>. + <BR> </DD> + + <DT>%incompat <I>product</I> + <DT>%incompat <I>filename</I> + <BR> </DT> + + <DD>Indicates that this product is incompatible with the + named product or file. + <BR> </DD> + + <DT>%if <I>variable [... variable]</I><BR> + %if !<I>variable [... variable]</I><BR> + %ifdef <I>variable [... variable]</I><BR> + %ifdef !<I>variable [... variable]</I><BR> + %elseif <I>variable [... variable]</I><BR> + %elseif !<I>variable [... variable]</I><BR> + %elseifdef <I>variable [... variable]</I><BR> + %elseifdef !<I>variable [... variable]</I><BR> + %else<BR> + %endif + <BR> </DT> + + <DD>Conditionally includes lines in the list file. The + <I>%if</I> lines include the lines that follow if the + named variables are (not) defined with a value. The + <I>%ifdef</I> lines include the lines that follow if the + named variables are (not) defined with any value. These + conditional lines cannot be nested. + <BR> </DD> + + <DT>%install <I>script or program</I> + <BR> </DT> + + <DD>Specifies a script or program to be run after all + files are installed. (This has been obsoleted by the + %postinstall directive) + <BR> </DD> + + <DT>%license <I>license file</I> + <BR> </DT> + + <DD>Specifies the file to display as the software + license. + <BR> </DD> + + <DT>%packager <I>name of packager</I> + <BR> </DT> + + <DD>Specifies the name of the packager. + <BR> </DD> + + <DT>%patch <I>script or program</I> + <BR> </DT> + + <DD>Specifies a script or program to be run after all + files are patched. (This has been obsoleted by the + %postpatch directive) + <BR> </DD> + + <!-- NEED 2in --> + <DT>%postinstall <I>script or program</I><BR> + %postinstall <<I>scriptfile</I><BR> + %postinstall <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run after all + files are installed. + <BR> </DD> + + <DT>%postpatch <I>script or program</I><BR> + %postpatch <<I>scriptfile</I><BR> + %postpatch <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run after all + files are patched. + <BR> </DD> + + <DT>%postremove <I>script or program</I><BR> + %postremove <<I>scriptfile</I><BR> + %postremove <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run after removing files. + <BR> </DD> + + <DT>%preinstall <I>script or program</I><BR> + %preinstall <<I>scriptfile</I><BR> + %preinstall <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run before all + files are installed. + <BR> </DD> + + <DT>%prepatch <I>script or program</I><BR> + %prepatch <<I>scriptfile</I><BR> + %prepatch <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run before all + files are patched. + <BR> </DD> + + <DT>%preremove <I>script or program</I><BR> + %preremove <<I>scriptfile</I><BR> + %preremove <<<I>string</I> + <BR> </DT> + + <DD>Specifies a script or program to be run before removing files. + <BR> </DD> + + <DT>%product <I>product name</I> + <BR> </DT> + + <DD>Specifies the product name. + <BR> </DD> + + <!-- NEED 2in --> + <DT>%provides <I>product name</I> + <BR> </DT> + + <DD>Indicates that this product provides the named dependency. + <BR> </DD> + + <DT>%readme <I>readme file</I> + <BR> </DT> + + <DD>Specifies a README file to be included in the distribution. + <BR> </DD> + + <DT>%remove <I>script or program</I> + <BR> </DT> + + <DD>Specifies a script or program to be run before removing files. + (This has been obsoleted by the %preremove directive) + <BR> </DD> + + <DT>%release <I>number</I> + <BR> </DT> + + <DD>Specifies the release or build number of a product + (defaults to 0). + <BR> </DD> + + <DT>%replaces <I>product</I> + <BR> </DT> + + <DD>Indicates that this product replaces the named product. + <BR> </DD> + + <DT>%requires <I>product</I> + <DT>%requires <I>filename</I> + <BR> </DT> + + <DD>Indicates that this product requires the named product or file. + <BR> </DD> + + <DT>%system <I>system[-release] [... system[-release]]</I> + <BR> </DT> + + <DD>Specifies that the following files should only be + used for the specified operating systems and + releases. + <BR> </DD> + + <DT>%system !<I>system[-release] [... system[-release]]</I> + <BR> </DT> + + <DD>Specifies that the following files should not be + used for the specified operating systems and + releases. + <BR> </DD> + + <DT>%system all + <BR> </DT> + + <DD>Specifies that the following files are applicable to + all operating systems. + <BR> </DD> + + <DT>%vendor <I>vendor or author name</I> + <BR> </DT> + + <DD>Specifies the vendor or author of the product. + <BR> </DD> + + <!-- NEED 2in --> + <DT>%version <I>version number</I> + <BR> </DT> + + <DD>Specifies the version number of the product. + <BR> </DD> + + <DT>c <I>mode user group destination source</I> + <DT>C <I>mode user group destination source</I> + <BR> </DT> + + <DD>Specifies a configuration file for installation. The + second form specifies that the file has changed or is + new and should be included as part of a patch. + Configuration files are installed as "destination.N" if + the destination already exists. + <BR> </DD> + + <DT>d <I>mode user group destination -</I> + <DT>D <I>mode user group destination -</I> + <BR> </DT> + + <DD>Specifies a directory should be created when + installing the software. The second form specifies that + the directory is new and should be included as part of a + patch. + <BR> </DD> + + <!-- NEED 2in --> + <DT>f <I>mode user group destination source [nostrip()]</I> + <DT>F <I>mode user group destination source [nostrip()]</I> + <BR> </DT> + + <DD>Specifies a file for installation. The second form + specifies that the file has changed or is new and should + be included as part of a patch. If the "nostrip()" + option is included, the file will not be stripped before + the installation is created. + <BR> </DD> + + <DT>f <I>mode user group destination source/pattern [nostrip()]</I> + <DT>F <I>mode user group destination source/pattern [nostrip()]</I> + <BR> </DT> + + <DD>Specifies one or more files for installation using + shell wildcard patterns. The second form specifies that + the files have changed or are new and should be included + as part of a patch. If the "nostrip()" option is + included, the file will not be stripped before the + installation is created. + <BR> </DD> + + <DT>i <I>mode user group service-name source ["options"]</I> + <DT>I <I>mode user group service-name source ["options"]</I> + <BR> </DT> + + <DD>Specifies an initialization script for installation. + The second form specifies that the file has changed or + is new and should be included as part of a patch. + Initialization scripts are stored in + <VAR>/etc/software/init.d</VAR> and are linked to the + appropriate system-specific directories for run levels + 0, 2, 3, and 5. Initialization scripts <B>must</B> + accept at least the <I>start</I> and <I>stop</I> + commands. The optional <I>options</I> following the + source filename can be any of the following: + <BR> + + <DL> + + <DT>order(<I>string</I>)</DT> + + <DD>Specifies the relative startup order + compared to the required and used system + functions. Supported values include First, + Early, None, Late, and Last (OSX only).</DD> + + <DT>provides(<I>name(s)</I>)</DT> + + <DD>Specifies names of system functions that are + provided by this startup item (OSX only).</DD> + + <!-- NEED 3 --><DT>requires(<I>name(s)</I>)</DT> + + <DD>Specifies names of system functions that are + required by this startup item (OSX only).</DD> + + <DT>runlevels(<I>levels</I>)</DT> + + <DD>Specifies the run levels to use.</DD> + + <DT>start(<I>number</I>)</DT> + + <DD>Specifies the starting sequence number from + 00 to 99.</DD> + + <DT>stop(<I>number</I>)</DT> + + <DD>Specifies the ending sequence number from 00 + to 99.</DD> + + <DT>uses(<I>name(s)</I>)</DT> + + <DD>Specifies names of system functions that are + used by this startup item (OSX only).</DD> + + </DL> + <BR> </DD> + + <!-- NEED 2in --> + <DT>l <I>mode user group destination source</I> + <DT>L <I>mode user group destination source</I> + <BR> </DT> + + <DD>Specifies a symbolic link in the installation. The + second form specifies that the link has changed or is + new and should be included as part of a patch. + <BR> </DD> + + <DT>R <I>mode user group destination</I> + <BR> </DT> + + <DD>Specifies that the file is to be removed upon + patching. The <I>user</I> and <I>group</I> fields are + ignored. The <I>mode</I> field is only used to + determine if a check should be made for a previous + version of the file. + <BR> </DD> + +</DL></DD></DL> + +<!-- NEED 3in --> +<H3>List Variables</H3> + +<P><I>EPM</I> maintains a list of variables and their values +which can be used to substitute values in the list file. These +variables are imported from the current environment and taken +from the command-line and list file as provided. Substitutions +occur when the variable name is referenced with the dollar sign +($):</P> + +<PRE> + %postinstall <<EOF + echo What is your name: + read $$name + echo Your name is $$name + EOF + + f 0555 root sys ${bindir}/foo foo + f 0555 root sys $datadir/foo/foo.dat foo.dat +</PRE> + +<P>Variable names can be surrounded by curly brackets (${name}) +or alone ($name); without brackets the name is terminated by the +first slash (/), dash (-), or whitespace. The dollar sign can be +inserted using $$.</P> + +<!-- NEED 5in --> +<H2><A NAME="SETUPTYPES">The setup.types File</A></H2> + +<P>The EPM <B>setup</B> program normally presents the user with +a list of software products to install, which is called a +"custom" software installation.</P> + +<P>If a file called <I>setup.types</I> is present in the package +directory, the user will instead be presented with a list of +installation types. Each type has an associated product list +which determines the products that are installed by default. If +a type has no products associated with it, then it is treated as +a custom installation and the user is presented with a list of +packages to choose from.</P> + +<P>The <I>setup.types</I> file is an ASCII text file consisting +of type and product lines. Comments can be inserted by starting +a line with the pound sign (#). Each installation type is +defined by a line starting with the word <CODE>TYPE</CODE>. +Products are defined by a line starting with the word +<CODE>INSTALL</CODE>:</P> + +<PRE> + # Pre-select the user packages + TYPE Typical End-User Configuration + INSTALL foo + INSTALL foo-help + + # Pre-select the developer packages + TYPE Typical Developer Configuration + INSTALL foo + INSTALL foo-help + INSTALL foo-devel + INSTALL foo-examples + + # Allow the user to select packages + TYPE Custom Configuration +</PRE> + +<P>In the example above, three installation types are defined. +Since the last type includes no products, the user will be +presented with the full list of products to choose from.</P> + +</BODY> +</HTML> diff --git a/doc/d-relnotes.html b/doc/d-relnotes.html new file mode 100644 index 0000000..299d786 --- /dev/null +++ b/doc/d-relnotes.html @@ -0,0 +1,102 @@ +<HTML> +<BODY> + +<H1 ALIGN="RIGHT"><A NAME="RELNOTES">D - Release Notes</A></H1> + +<P>This appendix lists the change log for each release of the +EPM software.</P> + +<h2>Changes in EPM v4.2</h2> + +<ul> + <li>EPM now supports a %arch conditional directive (STR #27)</li> + <li>EPM now uses hard links whenever possible instead of copying files for distribution (STR #21)</li> + <li>EPM no longer puts files in /export in the root file set for AIX packages (STR #15)</li> + <li>EPM did not work with newer versions of RPM (STR #23, STR #25)</li> + <li>EPM did not clean up temporary files from Solaris packages (STR #20)</li> + <li>Building Solaris gzip'd packages failed if the pkg.gz file already existed (STR #16)</li> + <li>Fixed handling of %preremove and %postremove for AIX packages (STR #22)</li> + <li>Fixed directory permissions in HP-UX packages (STR #24)</li> + <li>Removed unnecessary quoting of "!" in filenames (STR #26)</li> + <li>Added support for signed RPM packages (STR #19)</li> + <li>Added support for inclusion of format-specific packaging files and directives via a %literal directive (STR #5)</li> + <li>*BSD init scripts were not installed properly.</li> + <li>EPM now displays a warning message when a variable is undefined (STR #10)</li> + <li>*BSD dependencies on versioned packages are now specified correctly (STR #4)</li> + <li>EPM now uses /usr/sbin/pkg_create on FreeBSD (STR #2)</li> + <li>FreeBSD packages are now created with a .tbz extension (STR #1)</li> + <li>FreeBSD packages incorrectly assumed that chown was installed in /bin (STR #3)</li> + <li>Added support for an "lsb" package format which uses RPM with the LSB dependencies (STR #7)</li> + <li>The configure script now supports a --with-archflags and no longer automatically builds universal binaries on Mac OS X.</li> + <li>The epm program now automatically detects when the setup GUI is not available, displays a warning message, and then creates a non-GUI package.</li> + <li>RPM packages did not map %replaces to Obsoletes:</li> +</ul> + + +<h2>Changes in EPM v4.1</h2> + +<ul> + + <li>Mac OS X portable packages did not create a correct Uninstall application. + <li>The temporary package files for portable packages are now removed after creation of the .tar.gz file unless the -k (keep files) option is used. + <li>The RPM summary string for subpackages did not contain + the first line of the package description as for other + package formats. + <li>The setup and uninst GUIs now support installing and + removing RPM packages. + <li>The setup GUI now confirms acceptance of all licenses prior to installing the first package. + <li>Subpackages are no longer automatically dependent on the main package. + <li>Multi-line descriptions were not embedded properly into portable package install/patch/remove scripts. + <li>Updated the setup and uninstall GUIs for a nicer look-n-feel. + <li>Mac OS X portable packages now show the proper name, version, and copyright for the packaged software instead of the EPM version and copyright... + <li>Fixed a problem with creation of Mac OS X metapackages with the latest Xcode. + <li>EPM now removes the individual .rpm and .deb files when creating a package with subpackages unless the -k option (keep files) is used. + <li>EPM now only warns about package names containing characters other than letters and numbers. + <li>EPM now generates disk images as well as a .tar.gz file when creating portable packages on Mac OS X. + +</ul> + + +<H2>Changes in EPM v4.0</H2> + +<UL> + + <LI>New subpackage support for creating multiple dependent + packages or a combined package with selectable + subpackages, depending on the package format. + <LI>Added support for compressing the package files in + portable packages (reduces disk space requirements on + platforms that provide gzip...) + <LI>Added support for custom platform names via the new + "-m name" option. + <LI>Added support for non-numeric %release values. + <LI>Added new --depend option to list all of the source + files that a package depends on. + <LI>The setup GUI now sets the EPM_INSTALL_TYPE environment + variable to the value of the selected TYPE line in the + setup.types file. + <LI>Fixed NetBSD and OpenBSD packaging support - no longer + use FreeBSD-specific extensions to pkg_create on those + variants. + <LI>Fixed PowerPC platform support for RPM and Debian + packages. + <LI>Many fixes to AIX package support. + <LI>Tru64 packages with init scripts now work when + installing for the first time. + <LI>RPM file dependencies should now work properly. + <LI>Portable product names containing spaces will now + display properly. + +</UL> + +<!-- NEW SHEET + HEADER CENTER "" + FOOTER LEFT "" + FOOTER RIGHT "" --> +<P> </P> + +<!-- NEW SHEET --> +<P> </P> + +</BODY> +</HTML> diff --git a/doc/epm-book.book b/doc/epm-book.book new file mode 100644 index 0000000..544105a --- /dev/null +++ b/doc/epm-book.book @@ -0,0 +1,12 @@ +#HTMLDOC 1.8.26 +-t pdf14 -f "epm-book.pdf" --book --toclevels 2 --no-numbered --toctitle "Table of Contents" --title --titleimage "title.html" --linkstyle plain --size 6x9in --left 1in --right 0.750in --top 0.750in --bottom 0.750in --header .t. --header1 ... --footer h.1 --nup 1 --tocheader .t. --tocfooter ..i --duplex --portrait --grayscale --no-pscommands --no-xrxcomments --compression=9 --jpeg=90 --fontsize 10.0 --fontspacing 1.2 --headingfont Sans --bodyfont Sans --headfootsize 9.0 --headfootfont Sans-Oblique --charset iso-8859-1 --links --embedfonts --pagemode document --pagelayout tworight --firstpage p1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 680 --strict --no-overflow +preface.html +1-intro.html +2-building.html +3-packaging.html +4-advanced.html +5-examples.html +a-license.html +b-manpages.html +c-reference.html +d-relnotes.html diff --git a/doc/epm-book.html b/doc/epm-book.html new file mode 100644 index 0000000..967f776 --- /dev/null +++ b/doc/epm-book.html @@ -0,0 +1,2930 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<HTML> +<HEAD> +<TITLE>Software Distribution Using the ESP Package Manager</TITLE> +<META NAME="author" CONTENT="Michael Sweet"> +<META NAME="copyright" CONTENT="Copyright 1999-2010 by Easy Software Products"> +<META NAME="docnumber" CONTENT="ESP-004-20101231"> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-iso-8859-1"> +<STYLE TYPE="text/css"><!-- +BODY { font-family: sans-serif } +H1 { font-family: sans-serif } +H2 { font-family: sans-serif } +H3 { font-family: sans-serif } +H4 { font-family: sans-serif } +H5 { font-family: sans-serif } +H6 { font-family: sans-serif } +SUB { font-size: smaller } +SUP { font-size: smaller } +PRE { font-family: monospace } +A { text-decoration: none } +--></STYLE> +</HEAD> +<BODY> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<H1 ALIGN="CENTER">Software Distribution Using the ESP Package Manager</H1> +<P ALIGN="CENTER">MICHAEL R. SWEET</P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> </P> +<P> <IMG HEIGHT="10" SRC="gradient.gif" WIDTH="100"> +<BR><VAR> ESP Press</VAR> +<BR> <SMALL>Easy Software Products, 516 Rio Grand Ct, Morgan Hill, CA + 95037 USA</SMALL></P> + +<!-- NEW PAGE --> +<H2>Software Distribution Using the ESP Package Manager</H2> +<H3>Copyright © 2006-2010 by Easy Software Products</H3> +<P><SMALL>This book may be redistributed and/or modified under the terms + of version 2 of the GNU General Public License as published by the Free + Software Foundation.</SMALL></P> +<P><SMALL>This book is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details.</SMALL></P> +<P><SMALL>You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA.</SMALL></P> +<P><SMALL>This book was created solely using free software tools.</SMALL> +</P> +<P><SMALL>International Standard Book Number: 978-1-4116-8913-8</SMALL></P> +<P><SMALL>First Printing: April 2006 +<BR> Second Printing: December 2010</SMALL></P> +<HR NOSHADE> +<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1> +<BR> +<BR><B><A HREF="#1">Preface</A></B> +<UL> +<LI><A HREF="#1_1">Notation Conventions</A></LI> +<LI><A HREF="#1_2">Abbreviations</A></LI> +<LI><A HREF="#1_3">Other References</A></LI> +<LI><A HREF="#1_4">Help Us Improve This Book!</A></LI> +<LI><A HREF="#1_5">Acknowledgments</A></LI> +</UL> +<B><A HREF="#INTRO">1 - Introduction to EPM</A></B> +<UL> +<LI><A HREF="#2_1">What is EPM?</A></LI> +<LI><A HREF="#2_2">History and Evolution</A></LI> +<LI><A HREF="#2_3">Existing Software Packaging Systems</A></LI> +<LI><A HREF="#2_4">Design Goals of EPM</A></LI> +<LI><A HREF="#2_5">Resources</A></LI> +</UL> +<B><A HREF="#BUILDING">2 - Building EPM</A></B> +<UL> +<LI><A HREF="#3_1">Requirements</A></LI> +<LI><A HREF="#3_2">Configuring the Software</A></LI> +<LI><A HREF="#3_3">Building the Software</A></LI> +<LI><A HREF="#3_4">Installing the Software</A></LI> +</UL> +<B><A HREF="#PACKAGING">3 - Packaging Your Software with EPM</A></B> +<UL> +<LI><A HREF="#4_1">The Basics</A></LI> +<LI><A HREF="#4_2">Building a Software Package</A></LI> +<LI><A HREF="#4_3">Package Files</A></LI> +</UL> +<B><A HREF="#ADVANCED">4 - Advanced Packaging with EPM</A></B> +<UL> +<LI><A HREF="#5_1">Including Other List Files</A></LI> +<LI><A HREF="#5_2">Dependencies</A></LI> +<LI><A HREF="#5_3">Scripts</A></LI> +<LI><A HREF="#5_4">Conditional Directives</A></LI> +<LI><A HREF="#5_5">Protecting Object Files from Stripping</A></LI> +<LI><A HREF="#5_6">Software Patches</A></LI> +<LI><A HREF="#5_7">Variables</A></LI> +<LI><A HREF="#5_8">Init Scripts</A></LI> +<LI><A HREF="#5_9">Literal Package Data</A></LI> +</UL> +<B><A HREF="#EXAMPLES">5 - EPM Packaging Examples</A></B> +<UL> +<LI><A HREF="#6_1">Packaging the EPM Software</A></LI> +<LI><A HREF="#6_2">Packaging the CUPS Software</A></LI> +</UL> +<B><A HREF="#LICENSE">A - GNU General Public License</A></B> +<BR> +<BR><B><A HREF="#MANPAGES">B - Command Reference</A></B> +<UL> +<LI><A HREF="#8_1">epm(1)</A></LI> +<LI><A HREF="#8_2">epminstall(1)</A></LI> +<LI><A HREF="#8_3">mkepmlist(1)</A></LI> +<LI><A HREF="#8_4">setup(1)</A></LI> +</UL> +<B><A HREF="#REFERENCE">C - List File Reference</A></B> +<UL> +<LI><A HREF="#9_1">The EPM List File Format</A></LI> +<LI><A HREF="#SETUPTYPES">The setup.types File</A></LI> +</UL> +<B><A HREF="#RELNOTES">D - Release Notes</A></B> +<UL> +<LI><A HREF="#10_1">Changes in EPM v4.2</A></LI> +<LI><A HREF="#10_2">Changes in EPM v4.1</A></LI> +<LI><A HREF="#10_3">Changes in EPM v4.0</A></LI> +</UL> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1> +<P>This book provides a tutorial and reference for the ESP Package + Manager ("EPM") software, version 4.2, and is organized into the + following chapters and appendices:</P> +<UL> +<LI><A HREF="#INTRO">1 - Introduction to EPM</A></LI> +<LI><A HREF="#BUILDING">2 - Building EPM</A></LI> +<LI><A HREF="#PACKAGING">3 - Packaging Your Software with EPM</A></LI> +<LI><A HREF="#ADVANCED">4 - Advanced Packaging with EPM</A></LI> +<LI><A HREF="#EXAMPLES">5 - EPM Packaging Examples</A></LI> +<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI> +<LI><A HREF="#MANPAGES">B - Command Reference</A></LI> +<LI><A HREF="#REFERENCE">C - List File Reference</A></LI> +<LI><A HREF="#RELNOTES">D - Release Notes</A></LI> +</UL> + +<!-- NEED 6in --> +<H2><A NAME="1_1">Notation Conventions</A></H2> +<DL> +<DT>The names of commands; the first mention of a command or function in + a chapter is followed by a manual page section number: +<BR> </DT> +<DD><CODE>epm</CODE> +<BR> <CODE>epm(1)</CODE> +<BR> </DD> +<DT>File and directory names: +<BR> </DT> +<DD><VAR>/var</VAR> +<BR><VAR> /usr/bin/epm</VAR> +<BR> </DD> +<DT>Screen output: +<BR> </DT> +<DD><TT>Request ID is Printer-123</TT> +<BR> </DD> +<DT>Literal user input; special keys like <KBD>ENTER</KBD> are in ALL + CAPS: +<BR> </DT> +<DD><KBD>lp -d printer filename ENTER</KBD> +<BR> </DD> +<DT>Long commands are broken up on multiple lines using the backslash + (\) character; enter the commands without the backslash: +<BR> </DT> +<DD><KBD>foo start of long command \ +<BR> end of long command ENTER</KBD> +<BR> </DD> +<DT>Numbers in the text are written using the period (.) to indicate the + decimal point: +<BR> </DT> +<DD>12.3 +<BR> </DD> +</DL> + +<!-- NEED 3in --> +<H2><A NAME="1_2">Abbreviations</A></H2> +<P>The following abbreviations are used throughout this book:</P> +<DL> +<DD>kb</DD> +<DD>Kilobytes, or 1024 bytes +<BR> </DD> +<DD>Mb</DD> +<DD>Megabytes, or 1048576 bytes +<BR> </DD> +<DD>Gb</DD> +<DD>Gigabytes, or 1073741824 bytes +<BR> </DD> +</DL> + +<!-- NEED 4in --> +<H2><A NAME="1_3">Other References</A></H2> +<DL> +<DT><A HREF="http://www.epmhome.org/">http://www.epmhome.org/</A></DT> +<DD>The official home page of the ESP Package Manager software. +<BR> </DD> +<DT><A HREF="http://www.debian.org/devel/">http://www.debian.org/devel/</A> +</DT> +<DD>Debian Developers' Corner +<BR> </DD> +<DT><A HREF="http://techpubs.sgi.com/">http://techpubs.sgi.com/</A></DT> +<DD>IRIX Documentation On-Line +<BR> </DD> +<DT><A HREF="http://www.rpm.org/">http://www.rpm.org/</A></DT> +<DD>The Red Hat Package Manager home page. +<BR> </DD> +<DT><A HREF="http://docs.sun.com/">http://docs.sun.com/</A></DT> +<DD>Solaris Documentation On-Line +<BR> </DD> +</DL> +<H2><A NAME="1_4">Help Us Improve This Book!</A></H2> +<P>We've done our best to ensure that this book is both accurate and + clear. If you find errors or have a suggestion for improving the book, + please send us an email to "<A HREF="mailto:epm-book@easysw.com"> +epm-book@easysw.com</A>".</P> +<H2><A NAME="1_5">Acknowledgments</A></H2> +<P>We'd like to thank the following people for their contributions to + EPM:</P> +<UL> +<LI>Gareth Armstrong: HP-UX and %release enhancements</LI> +<LI>Nicolas Bazin: Openserver and Unixware support</LI> +<LI>Richard Begg: HP-UX fixes</LI> +<LI>Dirk Datzert: Bug fixes</LI> +<LI>Alan Eldridge: Makefile and RPM fixes</LI> +<LI>Vicentini Emanuele: IRIX enhancements</LI> +<LI>Jeff Harrell: IRIX enhancements</LI> +<LI>Lars Kellogg-Stedman: Debian fixes</LI> +<LI>Jochen Kmietsch: mkepmlist fixes</LI> +<LI>Aneesh Kumar K.V.: Tru64 setld package support</LI> +<LI>David Lee: Build system improvements</LI> +<LI>Scott Leerssen: mkepmlist fixes, BSD package support</LI> +<LI>Jeff Licquia: Debian support/enhancements</LI> +<LI>David Maltz: AIX fixes</LI> +<LI>Joel Nordell: SCO fixes</LI> +<LI>Rok Papez: Bug fixes and absolute output directory support</LI> +<LI>Holger Paschke: Documentation fixes</LI> +<LI>Phil Reynolds: OpenBSD fixes</LI> +<LI>Ganesan Rajagopal: Solaris fixes</LI> +<LI>Uwe Räsche: AIX support</LI> +<LI>Ralf Rohm: Solaris fixes</LI> +<LI>Jochen Schaeuble: epminstall fixes</LI> +<LI>Jason Shiffer: HP-UX fixes</LI> +<LI>Andrea Suatoni: IRIX fixes</LI> +<LI>Andy Walter: QNX support</LI> +<LI>Geoffrey Wossum: --output-directory option</LI> +<LI>Jean Yves: BSD package and mkepmlist fixes</LI> +</UL> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="INTRO">1 - Introduction to EPM</A></H1> +<P>This chapter provides an introduction to the ESP Package Manager + ("EPM").</P> +<H2><A NAME="2_1">What is EPM?</A></H2> +<P>Software distribution under UNIX/Linux can be a challenge, especially + if you ship software for more than one operating system. Every + operating system provides its own software packaging tools and each has + unique requirements or implications for the software development + environment.</P> +<P>The ESP Package Manager ("EPM") is one solution to this problem. + Besides its own "portable" distribution format, EPM also supports the + generation of several vendor-specific formats. This allows you to build + software distribution files for almost any operating system from the + same sources.</P> +<H2><A NAME="2_2">History and Evolution</A></H2> +<P>When Easy Software Products was founded in 1993, we originally + shipped software only for the SGI IRIX operating system. In 1997 we + added support for Solaris, which was quickly followed by HP-UX support + in 1998.</P> +<P>Each new operating system and supported processor required a new set + of packaging files. While this worked, it also meant that we had to + keep all of the packaging files synchronized manually. Needless to say, + this process was far from perfect and we had more than one distribution + that was not identical on all operating systems.</P> +<P>As we began developing CUPS (<A HREF="http://www.cups.org/"> +http://www.cups.org/</A>) in 1997, our initial goal was to add support + for two additional operating systems: Linux and Compaq Tru64 UNIX. If + we wanted to avoid the mistakes of the past, we clearly had to change + how we produced software distributions.</P> +<P>The first version of EPM was released in 1999 and supported so-called + "portable" software distributions that were not tied to any particular + operating system or packaging software. Due to popular demand, we added + support for vendor-specific packaging formats in the second major + release of EPM, allowing the generation of portable or "native" + distributions from one program and one set of software distribution + files.</P> +<H2><A NAME="2_3">Existing Software Packaging Systems</A></H2> +<P>As we looked for a solution to our problem, we naturally investigated + the existing open-source packaging systems. Under Linux, we looked at + the Red Hat Package Manager ("RPM") and Debian packaging software + ("dpkg" and "dselect"). For the commercial UNIX's we looked at the + vendor-supplied packaging systems. <A HREF="#TABLE_1_1">Table 1.1</A> + shows the results of our investigation.</P> + +<!-- NEED 5in --> +<TABLE ALIGN="CENTER" BORDER="1"><CAPTION> <A NAME="TABLE_1_1">Table + 1.1: Software Packaging Formats</A></CAPTION> +<TR><TH><FONT SIZE="-4">Format</FONT></TH><TH><FONT SIZE="-4">Operating + Systems<SUP>1</SUP></FONT></TH><TH><FONT SIZE="-4">Binaries</FONT></TH><TH> +<FONT SIZE="-4">Cross- Platform</FONT></TH><TH><FONT SIZE="-4">Patches</FONT> +</TH><TH><FONT SIZE="-4">Up- grades</FONT></TH><TH><FONT SIZE="-4">Con- + flicts</FONT></TH><TH><FONT SIZE="-4">Re- quires</FONT></TH><TH><FONT SIZE="-4"> +Re- places</FONT></TH><TH><FONT SIZE="-4">Config Files</FONT></TH><TH><FONT +SIZE="-4">Map Files</FONT></TH><TH><FONT SIZE="-4">Un- install</FONT></TH> +</TR> +<TR><TD ALIGN="CENTER"><SMALL>installp</SMALL></TD><TD ALIGN="CENTER"><SMALL> +AIX</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>pkg_add</SMALL></TD><TD ALIGN="CENTER"><SMALL> +FreeBSD</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes<SUP>2</SUP></SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD +ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL> +</TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL> +No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>pkg_add</SMALL></TD><TD ALIGN="CENTER"><SMALL> +NetBSD +<BR> OpenBSD</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes<SUP>2</SUP></SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD +ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL> +</TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL> +No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>dpkg</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Corel Linux +<BR> Debian GNU/Linux</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD +ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD><TD ALIGN="CENTER"><SMALL> +No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>depot</SMALL></TD><TD ALIGN="CENTER"><SMALL> +HP-UX</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>inst</SMALL></TD><TD ALIGN="CENTER"><SMALL> +IRIX</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>Install.app</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>MacOS X</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>pkgadd</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Solaris</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>rpm</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Mandrake +<BR> Red Hat +<BR> SuSE +<BR> TurboLinux</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD +ALIGN="CENTER"><SMALL>Yes<SUP>2</SUP></SMALL></TD><TD ALIGN="CENTER"><SMALL> +No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>setld</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Tru64 UNIX</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>Yes</SMALL></TD></TR> +<TR><TD ALIGN="CENTER"><SMALL>slackware</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Slackware Linux</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD +ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL> +</TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL> +Yes</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>No</SMALL></TD><TD ALIGN="CENTER"> +<SMALL>No</SMALL></TD><TD ALIGN="CENTER"><SMALL>Yes</SMALL></TD></TR> +</TABLE> +<OL> +<LI>Standard packaging system for named operating systems.</LI> +<LI>These packaging systems are cross-platform but require the package + management utilities to be installed on the platform before installing + the package.</LI> +</OL> +<P> </P> +<P>As you can see, none of the formats supported every feature we were + looking for. One common fault of all these formats is that they do not + support a common software specification file format. That is, making a + Debian software distribution requires significantly different support + files than required for a Solaris pkg distribution. This makes it + extremely difficult to manage distributions for multiple operating + systems.</P> +<P>All of the package formats support binary distributions. The RPM and + Debian formats also support source distributions that specifically + allow for recompilation and installation. Only the commercial UNIX + formats support patch distributions - you have to completely upgrade a + software package with RPM and Debian. All but the Solaris <CODE>pkg</CODE> + format allow you to upgrade a package without removing the old version + first.</P> +<P>When building the software packages, RPM and Debian force you to + create the actual directories, copy the files to those directories, and + set the ownerships and permissions. You essentially are creating a + directory for your software that can be archived in the corresponding + package format. To ensure that all file permissions and ownerships are + correct, you must build the distribution as the root user or use the <CODE> +fakeroot</CODE> software, introducing potential security risks and + violating many corporate security policies. It can also make building + distributions difficult when dynamic data such as changing data files + or databases is involved.</P> +<P>The commercial UNIX formats use software list files that map source + files to the correct directories and permissions. This allows for + easier delivery of dynamic data, configuration management of what each + distribution actually contains, and eliminates security issues with + special permissions and building distributions as the root user. Using + the proprietary format also has the added benefit of allowing for + software patches and using the familiar software installation tools for + that operating system. The primary disadvantage is that the same + distributions and packaging software cannot be used on other operating + systems.</P> +<H2><A NAME="2_4">Design Goals of EPM</A></H2> +<P>EPM was designed from the beginning to build binary software + distributions using a common software specification format. The same + distribution files work for all operating systems and all distribution + formats. Supporting source code distributions was not a goal since most + RPM and Debian source distributions are little more than wrapping + around a compressed tar file containing the source files and a + configure script.</P> +<P>Over the years, additional features have made their way into EPM to + support more advanced software packages. Whenever possible, EPM + emulates a feature if the vendor package format does not support it + natively.</P> +<H2><A NAME="2_5">Resources</A></H2> +<P>The EPM web site provides access to the current software, + documentation, and discussion forums for EPM:</P> +<PRE> + <A HREF="http://www.epmhome.org/">http://www.epmhome.org/</A> +</PRE> +<P>The EPM source code can be downloaded in compressed tar files or via + the popular Subversion software. Please see the EPM web site for + complete instructions.</P> +<P>Send book feedback to "<A HREF="mailto:epm-book@easysw.com"> +epm-book@easysw.com</A>".</P> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="BUILDING">2 - Building EPM</A></H1> +<P>This chapter shows how to configure, build, and install the ESP + Package Manager.</P> +<H2><A NAME="3_1">Requirements</A></H2> +<P>EPM requires very little pre-installed software to work. Most items + will likely be provided as part of your OS. Your development system + will need a C compiler, the <CODE>make(1)</CODE> program (GNU, BSD, and + most vendor <CODE>make</CODE> programs should work), the Bourne (or + Korn or Bash) shell (<CODE>sh(1)</CODE>), and <CODE>gzip(1)</CODE>.</P> +<P>The optional graphical setup program requires a C++ compiler, the + FLTK library, version 1.1.x, and (for UNIX/Linux) the X11 libraries. + FLTK is available at the following URL:</P> +<PRE> + <A HREF="http://www.fltk.org/">http://www.fltk.org/</A> +</PRE> +<P>Your end-user systems will require the Bourne (or Korn or Bash) shell + (<CODE>sh</CODE>), the <CODE>df(1)</CODE> program, the <CODE>tar(1)</CODE> + program, and the <CODE>gzip(1)</CODE> program to install portable + distributions. All but the last are standard items, and most vendors + include <CODE>gzip</CODE> as well.</P> +<P>EPM can also generate vendor-specific distributions. These require + the particular vendor tool, such as <CODE>rpm(8)</CODE> and <CODE> +dpkg(8)</CODE>, to generate the software distribution on the development + system and load the software distribution on the end-user system.</P> +<H2><A NAME="3_2">Configuring the Software</A></H2> +<P>EPM uses GNU <CODE>autoconf(1)</CODE> to configure itself for your + system. The <CODE>configure</CODE> script is used to configure the EPM + software, as follows:</P> +<PRE> + <KBD>./configure ENTER</KBD> +</PRE> +<H3>Choosing Compilers</H3> +<P>If the <CODE>configure</CODE> script is unable to determine the name + of your C or C++ compiler, set the <CODE>CC</CODE> and <CODE>CXX</CODE> + environment variables to point to the C and C++ compiler programs, + respectively. You can set these variables using the following commands + in the Bourne, Korn, or Bash shells:</P> +<PRE> + <KBD>export CC=/foo/bar/gcc ENTER + export CXX=/foo/bar/gcc ENTER</KBD> +</PRE> +<P>If you are using C shell or tcsh, use the following commands instead:</P> +<PRE> + <KBD>setenv CC /foo/bar/gcc ENTER + setenv CXX /foo/bar/gcc ENTER</KBD> +</PRE> +<P>Run the <CODE>configure</CODE> script again to use the new commands.</P> +<H3>Choosing Installation Directories</H3> +<P>The default installation prefix is<VAR> /usr</VAR>, which will place + the EPM programs in<VAR> /usr/bin</VAR>, the setup GUI in<VAR> + /usr/lib/epm</VAR>, and the man pages in<VAR> /usr/man</VAR>. Use the <CODE> +--prefix</CODE> option to relocate these files</P> +<P>to another directory:</P> +<PRE> + <KBD>./configure --prefix=/usr/local ENTER</KBD> +</PRE> +<P>The <CODE>configure</CODE> script also accepts the <CODE>--bindir</CODE> +, <CODE>--libdir</CODE>, and <CODE>--mandir</CODE> options to relocate + each directory separately, as follows:</P> +<PRE> + <KBD>./configure --bindir=/usr/local/bin --libdir=/usr/local/lib \ + --mandir=/usr/local/share/man ENTER</KBD> +</PRE> +<H3>Options for the Setup GUI</H3> +<P>The setup GUI requires the FLTK library. The configure script will + look for the <CODE>fltk-config</CODE> utility that comes with FLTK + 1.1.x. Set the FLTKCONFIG environment variable to the full path of this + utility if it cannot be found in the current path:</P> +<PRE> + <KBD>setenv FLTKCONFIG /foo/bar/bin/fltk-config ENTER</KBD> +</PRE> +<P>or:</P> +<PRE> + <KBD>FLTKCONFIG=/foo/bar/bin/fltk-config ENTER + export FLTKCONFIG</KBD> +</PRE> +<H2><A NAME="3_3">Building the Software</A></H2> +<P>Once you have configured the software, type the following command to + compile it:</P> +<PRE> + <KBD>make ENTER</KBD> +</PRE> +<P>Compilation should take a few minutes at most. Then type the + following command to determine if the software</P> +<P>compiled successfully:</P> +<PRE> + <KBD>make test ENTER</KBD> + Portable distribution build test PASSED. + Native distribution build test PASSED. +</PRE> +<P>The <CODE>test</CODE> target builds a portable and native + distribution of EPM and reports if the two distributions were generated + successfully.</P> +<H2><A NAME="3_4">Installing the Software</A></H2> +<P>Now that you have compiled and tested the software, you can install + it using the <CODE>make</CODE> command or one of the distributions that + was created. You should be logged in as the super-user unless you + specified installation directories for which you have write permission. + The <CODE>su(8)</CODE> command is usually sufficient to install + software:</P> +<PRE> + <KBD>su ENTER</KBD> +</PRE> +<P>Operating systems such as MacOS X do not enable the root account by + default. The <CODE>sudo(8)</CODE> command is used instead:</P> +<PRE> + <KBD>sudo <I>installation command</I> ENTER</KBD> +</PRE> + +<!-- NEED 2in --> +<H3>Installing Using the <CODE>make</CODE> Command</H3> +<P>Type the following command to install the EPM software using the <CODE> +make</CODE> command:</P> +<PRE> + <KBD>make install ENTER</KBD> + Installing EPM setup in /usr/lib/epm + Installing EPM programs in /usr/bin + Installing EPM manpages in /usr/man/man1 + Installing EPM documentation in /usr/share/doc/epm +</PRE> +<P>Use the <CODE>sudo</CODE> command to install on MacOS X:</P> +<PRE> + <KBD>sudo make install ENTER</KBD> + Installing EPM setup in /usr/lib/epm + Installing EPM programs in /usr/bin + Installing EPM manpages in /usr/man/man1 + Installing EPM documentation in /usr/share/doc/epm +</PRE> +<H3><A NAME="INSTALL_PORTABLE">Installing Using the Portable + Distribution</A></H3> +<P>The portable distribution can be found in a subdirectory named using + the operating system, version, and architecture. For example, the + subdirectory for a Linux 2.4.x system on an Intel-based system would be<VAR> + linux-2.4-intel</VAR>. The subdirectory name is built from the + following template:</P> +<PRE> + <I>os-major.minor-architecture</I> +</PRE> +<P>The <CODE>os</CODE> name is the common name for the operating system. + <A HREF="#TABLE_2_1">Table 2.1</A> lists the abbreviations for most + operating systems.</P> +<P>The <CODE>major.minor</CODE> string is the operating system version + number. Any patch revision information is stripped from the version + number, as are leading characters before the major version number. For + example, HP-UX version B.11.11 will result in a version number string + of <CODE>11.11</CODE>.</P> +<P> </P> +<CENTER> +<TABLE BORDER CELLPADDING="2"><CAPTION> <A NAME="TABLE_2_1">Table 2.1: + Operating System Name Abbreviations</A></CAPTION> +<TR><TH>Operating System</TH><TH>Name</TH></TR> +<TR><TD>AIX</TD><TD><CODE>aix</CODE></TD></TR> +<TR><TD>Compaq Tru64 UNIX +<BR> Digital UNIX +<BR> OSF/1</TD><TD><CODE>tru64</CODE></TD></TR> +<TR><TD>FreeBSD</TD><TD><CODE>freebsd</CODE></TD></TR> +<TR><TD>HP-UX</TD><TD><CODE>hpux</CODE></TD></TR> +<TR><TD>IRIX</TD><TD><CODE>irix</CODE></TD></TR> +<TR><TD>Linux</TD><TD><CODE>linux</CODE></TD></TR> +<TR><TD>MacOS X</TD><TD><CODE>macosx</CODE></TD></TR> +<TR><TD>NetBSD</TD><TD><CODE>netbsd</CODE></TD></TR> +<TR><TD>OpenBSD</TD><TD><CODE>openbsd</CODE></TD></TR> +<TR><TD>Solaris</TD><TD><CODE>solaris</CODE></TD></TR> +</TABLE> +</CENTER> + +<!-- NEED 3in --> +<CENTER> +<TABLE BORDER CELLPADDING="2"><CAPTION> <A NAME="TABLE_2_2">Table 2.2: + Processor Architecture Abbreviations</A></CAPTION> +<TR><TH>Processor(s)</TH><TH>Abbreviation</TH></TR> +<TR><TD>Compaq Alpha</TD><TD><CODE>alpha</CODE></TD></TR> +<TR><TD>HP Precision Architecture</TD><TD><CODE>hppa</CODE></TD></TR> +<TR><TD>INTEL 80x86</TD><TD><CODE>intel</CODE></TD></TR> +<TR><TD>INTEL 80x86 w/64bit Extensions</TD><TD><CODE>x86_64</CODE></TD></TR> +<TR><TD>MIPS RISC</TD><TD><CODE>mips</CODE></TD></TR> +<TR><TD>IBM Power PC</TD><TD><CODE>powerpc</CODE></TD></TR> +<TR><TD>SPARC +<BR> MicroSPARC +<BR> UltraSPARC</TD><TD><CODE>sparc</CODE></TD></TR> +</TABLE> +</CENTER> +<P> </P> +<P>The <CODE>architecture</CODE> string identifies the target processor. + <A HREF="#TABLE_2_2">Table 2.2</A> lists the supported processors.</P> +<P>Once you have determined the subdirectory containing the + distribution, type the following commands to install EPM from the + portable distribution:</P> +<PRE> + <KBD>cd <I>os-major.minor-architecture<I> ENTER + ./epm.install ENTER</I></I></KBD> +</PRE> +<P>The software will be installed after answering a few yes/no + questions.</P> +<H3>Installing Using the Native Distribution</H3> +<P>The <CODE>test</CODE> target also builds a distribution in the native + operating system format, if supported. <A HREF="#TABLE_2_3">Table 2.3</A> + lists the native formats for each supported operating system and the + command to run to install the software.</P> + +<!-- NEED 5in --> +<CENTER> +<TABLE BORDER CELLPADDING="2"><CAPTION> <A NAME="TABLE_2_3">Table 2.3: + Native Operating System Formats</A></CAPTION> +<TR><TH>Operating System</TH><TH>Format</TH><TH>Command</TH></TR> +<TR><TD>AIX</TD><TD><CODE>aix</CODE></TD><TD NOWRAP><CODE>installp -d<I> +directory</I> epm</CODE></TD></TR> +<TR><TD>Compaq Tru64 UNIX +<BR> Digital UNIX +<BR> OSF/1</TD><TD><CODE>setld</CODE></TD><TD NOWRAP><CODE>setld -a<I> + directory</I></CODE></TD></TR> +<TR><TD>FreeBSD +<BR> NetBSD +<BR> OpenBSD</TD><TD><CODE>bsd</CODE></TD><TD NOWRAP><CODE>cd<I> + directory</I> +<BR> pkg_add epm</CODE></TD></TR> +<TR><TD>HP-UX</TD><TD><CODE>depot</CODE></TD><TD NOWRAP><CODE>swinstall + -f<I> directory</I></CODE></TD></TR> +<TR><TD>IRIX</TD><TD><CODE>inst</CODE></TD><TD NOWRAP><CODE>swmgr -f<I> + directory</I></CODE></TD></TR> +<TR><TD>Linux</TD><TD><CODE>rpm</CODE></TD><TD NOWRAP><CODE>rpm -i<I> + directory</I>/epm-4.1.rpm</CODE></TD></TR> +<TR><TD>MacOS X</TD><TD><CODE>osx</CODE></TD><TD NOWRAP><CODE>open<I> + directory</I>/<CODE>epm-4.1.pkg</CODE></CODE></TD></TR> +<TR><TD>Solaris</TD><TD><CODE>pkg</CODE></TD><TD NOWRAP><CODE>pkgadd -d<I> + directory</I> epm</CODE></TD></TR> +</TABLE> +</CENTER> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="PACKAGING">3 - Packaging Your Software with + EPM</A></H1> +<P>This chapter describes how to use EPM to package your own software + packages.</P> +<H2><A NAME="4_1">The Basics</A></H2> +<P>EPM reads one or more software "list" files that describe a single + software package. Each list file contains one or more lines of ASCII + text containing product or file information.</P> +<P>Comments lines start with the <CODE>#</CODE> character, directive + lines start with the <CODE>%</CODE> character, variables lines start + with the <CODE>$</CODE> character, and file, directory, init script, + and symlink lines start with a letter.</P> + +<!-- NEED 3in --> +<H3>Product Information</H3> +<P>Every list file needs to define the product name, copyright, + description, license, README file, vendor, and version:</P> +<PRE> + %product Kung Foo Firewall + %copyright 1999-2005 by Foo Industries, All Rights Reserved. + %vendor Foo Industries + %license COPYING + %readme README + %description Kung Foo firewall software for your firewall. + %version 1.2.3p4 1020304 +</PRE> +<P>The <CODE>%license</CODE> and <CODE>%readme</CODE> directives specify + files for the license agreement and README files for the package, + respectively.</P> +<P>The <CODE>%product</CODE>, <CODE>%copyright</CODE>, <CODE>%vendor</CODE> +, and <CODE>%description</CODE> directives take text directly from the + line.</P> +<P>The <CODE>%version</CODE> directive specifies the version numbers of + the package. The first number is the human-readable version number, + while the second number is the integer version number. If you omit the + integer version number, EPM will calculate one for you.</P> +<H3>Files, Directories, and Symlinks</H3> +<P>Each file in the distribution is listed on a line starting with a + letter. The format of all lines is:</P> +<PRE> + type mode owner group destination source <I>options</I> +</PRE> +<P>Regular files use the letter <CODE>f</CODE> for the type field:</P> +<PRE> + f 755 root sys /usr/bin/foo foo +</PRE> +<P>Configuration files use the letter <CODE>c</CODE> for the type field:</P> +<PRE> + c 644 root sys /etc/foo.conf foo.conf +</PRE> + +<!-- NEED 2in --> +<P>Directories use the letter <CODE>d</CODE> for the type field and use + a source path of "-":</P> +<PRE> + d 755 root sys /var/spool/foo - +</PRE> +<P>Finally, symbolic links use the letter <CODE>l</CODE> (lowercase L) + for the type field:</P> +<PRE> + l 000 root sys /usr/bin/foobar foo +</PRE> +<P>The source field specifies the file to link to and can be a relative + path.</P> +<H3>Wildcards</H3> +<P>Wildcard patterns can be used in the source field to include multiple + files on a single line:</P> +<PRE> + f 0444 root sys /usr/share/doc/foo *.html +</PRE> + +<!-- NEED 3in --> +<H3>Subpackages</H3> +<P>Subpackages are optional parts of your software package. For example, + if your package includes developer files, you might provide them as a + subpackage so that users that will not be developing add-ons to your + software can omit them from the installation.</P> +<CENTER> +<TABLE BGCOLOR="#cccccc" BORDER CELLPADDING="5" WIDTH="80%"> +<TR><TD><B>Note:</B> +<BR> Subpackages are implemented as native subsets of the main package + for the AIX, HPUX, IRIX, Solaris, and Tru64 formats and as separate + packages that depend on the main (parent) package for all other + formats.</TD></TR> +</TABLE> +</CENTER> +<P>To define a subpackage, use the <CODE>%subpackage</CODE> directive + followed by a <CODE>%description</CODE> directive:</P> +<PRE> + %subpackage foo + %description One-Line Description of Foo +</PRE> +<P>Files, scripts, and dependencies that follow the <CODE>%subpackage</CODE> + directive are treated as part of that subpackage. Specifying the <CODE> +%subpackage</CODE> directive with no name returns processing to the main + (parent) package.</P> + +<!-- NEED 2in --> +<P>You can alternate between subpackages as many times as you like:</P> +<PRE> + %description Main package description + f 0755 /usr/bin/bar bar + + %subpackage foo + %description Foo programs + f 0755 /usr/bin/foo foo + %requires bla + + %subpackage + f 0644 /usr/share/man/man1/bar.1 + + %subpackage foo + f 0644 /usr/share/man/man1/foo.1 +</PRE> +<P>The above example creates a package containing the "bar" program and + man page with a subpackage containing the "foo" program and man page. + The "foo" subpackage depends both on the main package (implicit <CODE> +%requires</CODE>) and another package called "bla".</P> + +<!-- NEED 2in --> +<H2><A NAME="4_2">Building a Software Package</A></H2> +<P>The <CODE>epm(1)</CODE> program is used to build software package + from list files. To build a portable software package for an + application called "foo", type the following command:</P> +<PRE> + <KBD>epm foo ENTER</KBD> +</PRE> +<P>If your application uses a different base name than the list file, + you can specify the list filename on the command-line as well:</P> +<PRE> + <KBD>epm foo bar.list ENTER</KBD> +</PRE> +<CENTER> +<TABLE><CAPTION ALIGN="BOTTOM"> <A NAME="FIGURE_3_1">Figure 3.1: The EPM + Setup GUI</A></CAPTION> +<TR><TD><IMG HEIGHT="371" SRC="setup.png" WIDTH="592"></TD></TR> +</TABLE> +</CENTER> +<P> </P> +<H3>Installing the Software Package</H3> +<P>Once you have created the software package, you can install it. + Portable packages include an installation script called<VAR> + product.install</VAR>, where "product" is the name of the package:</P> +<PRE> + <KBD>cd os-release-arch ENTER + ./product.install ENTER</KBD> +</PRE> +<P>After answering a few yes/no questions, the software will be + installed. To bypass the questions, run the script with the <CODE>now</CODE> + argument:</P> +<PRE> + <KBD>cd os-release-arch ENTER + ./product.install now ENTER</KBD> + +</PRE> +<H3>Including the Setup GUI</H3> +<P>EPM also provides an optional graphical setup program (<A HREF="#FIGURE_3_1"> +Figure 3.1</A>). To include the setup program in your distributions, + create a product logo image in GIF or XPM format and use the <CODE> +--setup-image</CODE> option when creating your distribution:</P> +<PRE> + <KBD>epm --setup-image foo.xpm foo ENTER</KBD> +</PRE> +<P>This option is only supported when creating for portable and MacOS X + software packages.</P> + +<!-- NEED 5in --> +<H3>Creating Vendor Package Files</H3> +<P>EPM can also produce vendor-specific packages using the <CODE>-f</CODE> + option:</P> +<PRE> + <KBD>epm -f format foo bar.list ENTER</KBD> +</PRE> +<P>The<I> format</I> option can be one of the following keywords:</P> +<UL> +<LI><CODE>aix</CODE> - AIX software packages.</LI> +<LI><CODE>bsd</CODE> - FreeBSD, NetBSD, or OpenBSD software packages.</LI> +<LI><CODE>depot</CODE> or <CODE>swinstall</CODE> - HP-UX software + packages.</LI> +<LI><CODE>dpkg</CODE> - Debian software packages.</LI> +<LI><CODE>inst</CODE> or <CODE>tardist</CODE> - IRIX software packages.</LI> +<LI><CODE>native</CODE> - "Native" software packages (RPM, INST, DEPOT, + PKG, etc.) for the platform.</LI> +<LI><CODE>osx</CODE> - MacOS X software packages.</LI> +<LI><CODE>pkg</CODE> - Solaris software packages.</LI> +<LI><CODE>portable</CODE> - Portable software packages (default).</LI> +<LI><CODE>rpm</CODE> - Red Hat software packages.</LI> +<LI><CODE>setld</CODE> - Tru64 (setld) software packages.</LI> +<LI><CODE>slackware</CODE> - Slackware software packages.</LI> +</UL> +<P>Everything in the software list file stays the same - you just use + the <CODE>-f</CODE> option to select the format. For example, to build + an RPM distribution of EPM, type:</P> +<PRE> + epm -f rpm epm +</PRE> +<P>The result will be one or more RPM package files instead of the + portable package files.</P> +<H2><A NAME="4_3">Package Files</A></H2> +<P>EPM creates the package files in the output directory. As mentioned + in <A HREF="#INSTALL_PORTABLE">Chapter 1, "Installing Using the + Portable Distribution"</A>, the default output directory is based on + the operating system name, version, and architecture. Each package + format will leave different files in the output directory.</P> +<H3>AIX Package Files</H3> +<P>AIX packages are contained in a file called<VAR> name.bff</VAR>, + where "name" is the product/package name you supplied on the + command-line.</P> +<H3>BSD Package Files</H3> +<P>BSD packages are contained in a file called<VAR> name.tgz</VAR>, + where "name" is the product/package name you supplied on the + command-line.</P> +<H3>HP-UX Package Files</H3> +<P>HP-UX packages are contained in two files called<VAR> name.depot.gz</VAR> + and<VAR> name.depot.tgz</VAR>, where "name" is the product/package name + you supplied on the command-line. The<VAR> name.depot.gz</VAR> file can + be supplied directly to the <CODE>swinstall(1m)</CODE> command, while + the<VAR> name.depot.tgz</VAR> file contains a compressed <CODE>tar(1)</CODE> + archive that can be used to install the software from CD-ROM or network + filesystem.</P> +<H3>Debian Package Files</H3> +<P>Debian packages are contained in a file called<VAR> name.deb</VAR> or<VAR> + name.deb.tgz</VAR> when there are subpackages, where "name" is the + product/package name you supplied on the command-line. The<VAR> + name.deb.tgz</VAR> file contains a compressed <CODE>tar</CODE> archive + containing<VAR> name.deb</VAR> and<VAR> name-subpackage.deb</VAR> files + that can be installed from CD-ROM, disk, or network filesystem.</P> +<H3>IRIX Package Files</H3> +<P>IRIX packages are contained in a file called<VAR> name.tardist</VAR>, + where "name" is the product/package name you supplied on the + command-line.</P> +<H3>MacOS X Package Files</H3> +<P>MacOS X packages are contained in a file called<VAR> name.dmg</VAR>, + where "name" is the product/package name you supplied on the + command-line.</P> +<H3>RPM Package Files</H3> +<P>RPM packages are contained in a file called<VAR> name.rpm</VAR> or<VAR> + name.rpm.tgz</VAR> when there are subpackages, where "name" is the + product/package name you supplied on the command-line. The<VAR> + name.rpm.tgz</VAR> file contains a compressed <CODE>tar</CODE> archive + containing<VAR> name.rpm</VAR> and<VAR> name-subpackage.rpm</VAR> files + that can be installed from CD-ROM, disk, or network filesystem.</P> +<H3>Slackware Package Files</H3> +<P>Slackware packages are contained in a file called<VAR> name.tgz</VAR> +, where "name" is the product/package name you supplied on the + command-line.</P> +<H3>Solaris Package Files</H3> +<P>Solaris packages are contained in two files called<VAR> name.pkg.gz</VAR> + and<VAR> name.pkg.tgz</VAR>, where "name" is the product/package name + you supplied on the command-line. The<VAR> name.pkg.gz</VAR> file is a + compressed package file that can be used directly with the <CODE> +pkgadd(1m)</CODE> command, while the<VAR> name.pkg.tgz</VAR> file is a + compressed <CODE>tar</CODE> archive that can be used to install the + software from CD-ROM, disk, or network filesystem.</P> +<H3>Tru64 Package Files</H3> +<P>Tru64 packages are contained in a file called<VAR> name.tar.gz</VAR>, + where "name" is the product/package name you supplied on the + command-line.</P> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="ADVANCED">4 - Advanced Packaging with EPM</A></H1> +<P>This chapter describes the advanced packaging features of EPM.</P> +<H2><A NAME="5_1">Including Other List Files</A></H2> +<P>The <CODE>%include</CODE> directive includes another list file:</P> +<PRE> + %include filename +</PRE> +<P>Includes can usually be nested up to 250 levels depending on the host + operating system and libraries.</P> +<H2><A NAME="5_2">Dependencies</A></H2> +<P>EPM supports four types of dependencies in list files: <CODE> +%incompat</CODE>, <CODE>%provides</CODE>, <CODE>%replaces</CODE>, and <CODE> +%requires</CODE>. <A HREF="#TABLE_4_1">Table 4.1</A> shows the level of + support for each package format.</P> + +<!-- NEED 5in --> +<CENTER> +<TABLE BORDER CELLPADDING="2"><CAPTION> <A NAME="TABLE_4_1">Table 4.1: + Dependency Support</A></CAPTION> +<TR><TH>Format</TH><TH>%incompat</TH><TH>%provides</TH><TH>%replaces</TH><TH> +%requires</TH></TR> +<TR><TD ALIGN="CENTER">aix</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">bsd</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">deb</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes<SUP>1</SUP></TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD> +</TR> +<TR><TD ALIGN="CENTER">inst</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">osx</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">pkg</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">portable</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">rpm</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">setld</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">slackware</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">swinstall</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +</TABLE> +</CENTER> +<OL> +<LI>Debian's package format does not currently support version numbers + for <CODE>%provides</CODE> dependencies.</LI> +</OL> +<P> </P> +<P>Software conflicts and requirements are specified using the <CODE> +%incompat</CODE> and <CODE>%requires</CODE> directives.</P> +<P>If your software replaces another package, you can specify that using + the <CODE>%replaces</CODE> directive. <CODE>%replaces</CODE> is + silently mapped to <CODE>%incompat</CODE> when the package format does + not support package replacement.</P> +<P>If your package provides certain functionality associated with a + standard name, the <CODE>%provides</CODE> directive can be used.</P> + +<!-- NEED 1in --> +<P>Dependencies are specified using the package name and optionally the + lower and upper version numbers:</P> +<PRE> + %requires foobar + %requires foobar 1.0 + %incompat foobar 0.9 + %replaces foobar + %replaces foobar 1.2 3.4 + %provides foobar +</PRE> +<P>or the filename:</P> +<PRE> + %requires /usr/lib/libfoobar.so + %incompat /usr/lib/libfoobar.so.1.2 +</PRE> +<P>Package dependencies are currently enforced only for the same package + format, so a portable distribution that requires package "foobar" will + only look for an installed "foobar" package in portable format.</P> +<P>Filename dependencies are only supported by the Debian, portable, and + RPM distribution formats.</P> +<H2><A NAME="5_3">Scripts</A></H2> +<P>Bourne shell script commands can be executed before or after + installation, patching, or removal of the software. <A HREF="#TABLE_4_2"> +Table 4.2</A> shows the support for scripts in each package format.</P> +<P>The <CODE>%preinstall</CODE> and <CODE>%postinstall</CODE> directives + specify commands to be run before and after installation, respectively:</P> +<PRE> + %preinstall echo Command before installing + %postinstall echo Command after installing +</PRE> +<P>Similarly, the <CODE>%prepatch</CODE> and <CODE>%postpatch</CODE> + directives specify commands to be executed before and after patching + the software:</P> +<PRE> + %prepatch echo Command before patching + %postpatch echo Command after patching +</PRE> +<P>Finally, the <CODE>%preremove</CODE> and <CODE>%postremove</CODE> + directives specify commands that are run before and after removal of + the software:</P> +<PRE> + %preremove echo Command before removing + %postremove echo Command after removing +</PRE> + +<!-- NEED 3in --> +<CENTER> +<TABLE ALIGN="CENTER" BORDER="1"><CAPTION> <A NAME="TABLE_4_2">Table + 4.2: Scripts Support</A></CAPTION> +<TR><TH><SMALL>Format</SMALL></TH><TH><SMALL>%preinstall</SMALL></TH><TH> +<SMALL>%postinstall</SMALL></TH><TH><SMALL>%prepatch</SMALL></TH><TH><SMALL> +%postpatch</SMALL></TH><TH><SMALL>%preremove</SMALL></TH><TH><SMALL> +%postremove</SMALL></TH></TR> +<TR><TD ALIGN="CENTER">aix</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">bsd</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">deb</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">inst</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">osx</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">pkg</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">portable</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">rpm</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">setld</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +<TR><TD ALIGN="CENTER">slackware</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +No</TD><TD ALIGN="CENTER">No</TD></TR> +<TR><TD ALIGN="CENTER">swinstall</TD><TD ALIGN="CENTER">Yes</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER">No</TD><TD ALIGN="CENTER"> +Yes</TD><TD ALIGN="CENTER">Yes</TD></TR> +</TABLE> +</CENTER> +<P> </P> +<P>To include an external script file, use the <CODE><filename</CODE> + notation:</P> +<PRE> + %postinstall <filename +</PRE> +<P>To include multiple lines directly, use the <CODE><<string</CODE> + notation (a.k.a. a "here" document):</P> +<PRE> + %postinstall <<EOF + echo Command before installing + /usr/bin/foo + EOF +</PRE> +<P>Note that all commands specified in the list file will use the + variable expansion provided by EPM, so be sure to quote any dollar sign + (<CODE>$</CODE>) characters in your commands. For example, "$foo" is + replaced by the value of "foo", but "$$foo" becomes "$foo".</P> + +<!-- NEED 4in --> +<H2><A NAME="5_4">Conditional Directives</A></H2> +<P>The <CODE>%system</CODE> directive can match or not match specific + operating system names or versions. The operating system name is the + name reported by <CODE>uname</CODE> in lowercase, while the operating + system version is the major and minor version number reported by <CODE> +uname -r</CODE>:</P> +<DL> +<DD> +<DL> +<DT><CODE>%system irix</CODE> +<BR> </DT> +<DD>Only include the following files when building a distribution for + the IRIX operating system. +<BR> </DD> +<DT><CODE>%system linux-2.0</CODE> +<BR> </DT> +<DD>Only include the following files when building a distribution for + Linux 2.0.x. +<BR> </DD> +<DT><CODE>%system !irix !linux-2.0</CODE> +<BR> </DT> +<DD>Only include the following files when building a distribution for + operating systems other than IRIX and Linux 2.0.x. +<BR> </DD> +</DL> +</DD> +</DL> +<P>The special name <CODE>all</CODE> is used to match all operating + systems:</P> +<PRE> + %system all +</PRE> +<P>For format-specific files, the <CODE>%format</CODE> directive can be + used:</P> +<DL> +<DD> +<DL> +<DT><CODE>%format rpm</CODE> +<BR> </DT> +<DD>Only include the following files when building an RPM distribution. +<BR> </DD> +<DT><CODE>%format !rpm</CODE> +<BR> </DT> +<DD>Only include the following files when not building an RPM + distribution.x. +<BR> </DD> +<DT><CODE>%format all</CODE> +<BR> </DT> +<DD>Include the following files for all types of distributions. +<BR> </DD> +</DL> +</DD> +</DL> +<P>The <CODE>%arch</CODE> directive can match or not match specific + architectures. The architecture name is the name reported by <CODE> +uname -m</CODE>; "arm" is a synonym for "armv6", "armv7", and "armv8", + "intel" is a synonym for "i386", "i486", "i586", and "i686", and + "powerpc" is a synonym for "ppc":</P> +<DL> +<DD> +<DL> +<DT><CODE>%arch intel</CODE> +<BR> </DT> +<DD>Only include the following files when building a package for 32-bit + Intel processors. +<BR> </DD> +<DT><CODE>%arch armv6</CODE> +<BR> </DT> +<DD>Only include the following files when building a package for ARMv6 + processors. +<BR> </DD> +<DT><CODE>%system !powerpc</CODE> +<BR> </DT> +<DD>Only include the following files when building a package for + processors other than PowerPC. +<BR> </DD> +</DL> +</DD> +</DL> +<P>The special name <CODE>all</CODE> is used to match all architectures:</P> +<PRE> + %arch all +</PRE> +<P>Finally, EPM can conditionally include lines using the <CODE>%if</CODE> +, <CODE>%elseif</CODE>, <CODE>%ifdef</CODE>, <CODE>%elseifdef</CODE>, <CODE> +%else</CODE>, and <CODE>%endif</CODE> directives.</P> +<P><CODE>%if</CODE> directives include the text that follows if the + named variable(s) are defined to a non-empty string:</P> +<PRE> + %if FOO + f 755 root sys /usr/bin/foo foo + %elseif BAR + f 755 root sys /usr/bin/bar bar + %endif +</PRE> +<P><CODE>%ifdef</CODE> directives only include the text if the named + variable(s) are defined to any value:</P> +<PRE> + %ifdef OSTYPE + f 755 root sys /usr/bin/program program-$OSTYPE + %else + f 755 root sys /usr/bin/program program.sh + %endif +</PRE> +<H2><A NAME="5_5">Protecting Object Files from Stripping</A></H2> +<P>The <CODE>nostrip()</CODE> option can be included at the end of a + file line to prevent EPM from stripping the symbols and debugging + information from a file:</P> +<PRE> + f 755 root sys /usr/lib/libfoo.so libfoo.so nostrip() +</PRE> +<H2><A NAME="5_6">Software Patches</A></H2> +<P>EPM supports portable software patch distributions which contain only + the differences between the original and patch release. Patch files are + specified using uppercase letters for the affected files. In the + following example, the files<VAR> /usr/bin/bar</VAR> and<VAR> + /etc/foo.conf</VAR> are marked</P> + +<!-- NEED 2in --> +<P>as changed since the original release:</P> +<PRE> + f 755 root sys /usr/bin/foo foo + F 755 root sys /usr/bin/bar bar + f 755 root sys /usr/share/man/man1/foo.1 foo.man + f 755 root sys /usr/share/man/man1/bar.1 bar.man + C 644 root sys /etc/foo.conf foo.conf +</PRE> +<H2><A NAME="5_7">Variables</A></H2> +<P>EPM imports the current environment variables for use in your list + file. You can also define new variable in the list file or on the + command-line when running EPM.</P> +<P>Variables are defined by starting the line with the dollar sign (<CODE> +$</CODE>) followed by the name and value:</P> +<PRE> + $name=value + $prefix=/usr + $exec_prefix=${prefix} + $bindir=$exec_prefix/bin +</PRE> +<P>Variable substitution is performed when the variable is defined, so + be careful with the ordering of your variable definitions.</P> +<P>Also, any variables you specify in your list file will be overridden + by variables defined on the command-line or in your environment, just + like with <CODE>make</CODE>. This can be a useful feature or a curse, + depending on your choice of variable names.</P> +<P>As you can see, variables are referenced using the dollar sign (<CODE> +$</CODE>). As with most shells, variable names can be surrounded by + curly braces (<CODE>${variable}</CODE>) to explicitly delimit the name.</P> + +<!-- NEED 1in --> +<P>If you need to insert a <CODE>$</CODE> in a filename or a script, use + <CODE>$$</CODE>:</P> +<PRE> + %install echo Enter your name: + %install read $$name + %install echo Your name is $$name. +</PRE> +<H2><A NAME="5_8">Init Scripts</A></H2> +<P>Initialization scripts are generally portable between platforms, + however the location of initialization scripts varies greatly.</P> +<P>The <CODE>i</CODE> file type can be used to specify and init script + that is to be installed on the system. EPM will then determine the + appropriate init file directories to use and create any required + symbolic links to support the init script:</P> +<PRE> + i 755 root sys foo foo.sh +</PRE> +<P>The previous example creates an init script named<VAR> foo</VAR> on + the end-user system and will create symbolic links to run levels 0, 2, + 3, and 5 as needed, using a sequence number of 00 (or 000) for the + shutdown script and 99 (or 999) for the startup script.</P> +<P>To specify run levels and sequence numbers, use the <CODE>runlevel()</CODE> +, <CODE>start()</CODE>, and <CODE>stop()</CODE> options:</P> +<PRE> + i 755 root sys foo foo.sh "runlevel(02) start(50) stop(30)" +</PRE> +<H2><A NAME="5_9">Literal Package Data</A></H2> +<P>Sometimes you need to include format-specific package data such as + keywords, signing keys, and response data. The <CODE>%literal(section)</CODE> + directive adds format-specific data to the packages you create. Literal + data is currently only supported for RPM and PKG packages.</P> +<H3>PKG Literal Data</H3> +<P>PKG packages support request files that are used to do batch + installations when installation commands require user input. The <CODE> +%literal(request)</CODE> directive can be used to provide this user + input:</P> +<PRE> + %literal(request) <<EOF + John Doe + 1 Any Lane + Forest Lawn, OH 12345 + EOF +</PRE> +<H3>RPM Literal Data</H3> +<P>RPM packages support numerous attributes in the "spec" file that + control how the package is created and what metadata is included with + the package. The <CODE>%literal(spec)</CODE> directive can be used to + provide attributes for the spec file:</P> +<PRE> + %literal(spec) <<EOF + %changelog + * Tue Aug 26 2008 John Doe <johndoe@domain.com> + + - Added new feature "bar" + + * Fri Aug 1 2008 John Doe <johndoe@domain.com> + + - Added new feature "foo" + EOF +</PRE> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="EXAMPLES">5 - EPM Packaging Examples</A></H1> +<P>This chapter shows how the EPM and CUPS software is packaged using + EPM list files. The EPM list file example highlights the basic features + of EPM, while the CUPS list file example shows the more advanced + features of EPM.</P> +<H2><A NAME="6_1">Packaging the EPM Software</A></H2> +<P>The EPM software comes with its own autoconf-generated<VAR> epm.list</VAR> + file that is used to package and test EPM. The EPM package consists of + the main package plus a "documentation" subpackage for the + documentation files and a "man" subpackage for the man pages.</P> +<P>We start by defining variables for each of the autoconf directory + variables:</P> +<PRE><FONT SIZE="1"> + $prefix=/usr + $exec_prefix=/usr + $bindir=${exec_prefix}/bin + $datadir=/usr/share + $docdir=${datadir}/doc/epm + $libdir=/usr/lib + $mandir=/usr/share/man + $srcdir=. +</FONT></PRE> +<P>Then we provide the general product information that is required for + all packages; notice the use of <CODE>${srcdir}</CODE> to reference the + COPYING and README files:</P> +<PRE><FONT SIZE="1"> + %product ESP Package Manager + %copyright 1999-2006 by Easy Software Products, All Rights Reserved. + %vendor Easy Software Products + %license ${srcdir}/COPYING + %readme ${srcdir}/README + %description Universal software packaging tool for UNIX. + %version 4.0 400 +</FONT></PRE> +<P>After the product information, we include all of the non-GUI files + that are part of EPM:</P> +<PRE><FONT SIZE="1"> + # Executables + %system all + f 0555 root sys ${bindir}/epm epm + f 0555 root sys ${bindir}/epminstall epminstall + f 0555 root sys ${bindir}/mkepmlist mkepmlist + + # Documentation + %subpackage documentation + %description Documentation for EPM + f 0444 root sys ${docdir}/README $srcdir/README + f 0444 root sys ${docdir}/COPYING $srcdir/COPYING + f 0444 root sys ${docdir}/epm-book.html $srcdir/doc/epm-book.html + + # Man pages + %subpackage man + %description Man pages for EPM + f 0444 root sys ${mandir}/man1/epm.1 $srcdir/doc/epm.man + f 0444 root sys ${mandir}/man1/epminstall.1 $srcdir/doc/epminstall.man + f 0444 root sys ${mandir}/man1/mkepmlist.1 $srcdir/doc/mkepmlist.man + f 0444 root sys ${mandir}/man5/epm.list.5 $srcdir/doc/epm.list.man +</FONT></PRE> +<P>Finally, we conditionally include the GUI files depending on the + state of a variable called <CODE>GUIS</CODE>:</P> +<PRE><FONT SIZE="1"> + # GUI files... + $GUIS=setup uninst + + %if GUIS + %subpackage + f 0555 root sys ${libdir}/epm/setup setup + f 0555 root sys ${libdir}/epm/uninst uninst + + %system darwin + f 0444 root sys ${datadir}/epm/setup.icns macosx/setup.icns + f 0444 root sys ${datadir}/epm/setup.info macosx/setup.info + f 0444 root sys ${datadir}/epm/setup.plist macosx/setup.plist + + f 0444 root sys ${datadir}/epm/uninst.icns macosx/uninst.icns + f 0444 root sys ${datadir}/epm/uninst.info macosx/uninst.info + f 0444 root sys ${datadir}/epm/uninst.plist macosx/uninst.plist + %system all + + %subpackage man + f 0444 root sys ${mandir}/man1/setup.1 $srcdir/doc/setup.man + f 0444 root sys ${mandir}/man5/setup.types.5 $srcdir/doc/setup.types.man + + %endif +</FONT></PRE> +<H2><A NAME="6_2">Packaging the CUPS Software</A></H2> +<P>The Common UNIX Printing System provides an EPM list file to generate + software distributions for most UNIX operating systems. This list file + is more complex than the EPM example and contains several subpackages:</P> +<UL> +<LI>"devel"; Developer header, library, and documentation files</LI> +<LI>"es"; Spanish localization files</LI> +<LI>"ja"; Japanese localization files</LI> +<LI>"libs"; Shared libraries</LI> +<LI>"lpd"; LPD client support</LI> +</UL> +<H3>Variables Used for the Distribution</H3> +<P>In addition to the autoconf variables defined in the EPM list file, + the CUPS list file defines the following autoconf-derived variables for + the distribution:</P> +<UL> +<LI><CODE>AMANDIR</CODE>; The directory for administrative manual pages.</LI> +<LI><CODE>BINDIR</CODE>; The directory for user programs.</LI> +<LI><CODE>CACHEDIR</CODE>; The directory for cache files.</LI> +<LI><CODE>DATADIR</CODE>; The directory for data files.</LI> +<LI><CODE>DOCDIR</CODE>; The directory for documentation files.</LI> +<LI><CODE>INCLUDEDIR</CODE>; The directory for header files.</LI> +<LI><CODE>INITDIR</CODE>; The directory for startup scripts.</LI> +<LI><CODE>INITDDIR</CODE>; The directory to reference from run-level + scripts.</LI> +<LI><CODE>LIBDIR</CODE>; The directory for library files.</LI> +<LI><CODE>LIB32DIR</CODE>; The directory for 32-bit library files.</LI> +<LI><CODE>LIB64DIR</CODE>; The directory for 64-bit library files.</LI> +<LI><CODE>LOCALEDIR</CODE>; The directory for message (localization) + files.</LI> +<LI><CODE>LOGDIR</CODE>; The directory for log files.</LI> +<LI><CODE>MANDIR</CODE>; The directory for man pages.</LI> +<LI><CODE>PAMDIR</CODE>; The directory for PAM configuration files.</LI> +<LI><CODE>REQUESTS</CODE>; The directory for request files.</LI> +<LI><CODE>SBINDIR</CODE>; The directory for administration programs.</LI> +<LI><CODE>SERVERBIN</CODE>; The directory for server programs.</LI> +<LI><CODE>SERVERROOT</CODE>; The directory for server configuration + files.</LI> +<LI><CODE>STATEDIR</CODE>; The directory for server state files.</LI> +</UL> +<H3>Product Information</H3> +<P>The list file starts with the standard product information:</P> +<PRE><FONT SIZE="1"> + %product Common UNIX Printing System + %copyright 1993-2006 by Easy Software Products, All Rights Reserved. + %vendor Easy Software Products + %license LICENSE.txt + %readme packaging/cups.license + %version 1.2.0 + %description The Common UNIX Printing System provides a portable + %description printing layer for UNIX(r) operating systems. It + %description has been developed by Easy Software Products to + %description promote a standard printing solution for all UNIX + %description vendors and users. CUPS provides the System V and + %description Berkeley command-line interfaces. +</FONT></PRE> +<P>We then list different dependencies depending on the package format:</P> +<PRE><FONT SIZE="1"> + %format rpm + %provides cups 1:1.2.0 + %provides lpd, lpr, LPRng + %replaces lpd, lpr, LPRng + + %format deb + %provides cupsys + %provides cupsys-client + %provides cupsys-bsd + + %format pkg + %replaces SUNWlpmsg LP Alerts + %replaces SUNWlpr LP Print Service, (Root) + %replaces SUNWlps LP Print Service - Server, (Usr) + %replaces SUNWlpu LP Print Service - Client, (Usr) + %replaces SUNWpsu LP Print Server, (Usr) + %replaces SUNWpsr LP Print Server, (Root) + %replaces SUNWpcu LP Print Client, (Usr) + %replaces SUNWpcr LP Print Client, (Root) + %replaces SUNWppm + %replaces SUNWmp + %replaces SUNWscplp SunOS Print Compatibility + + %format inst + %replaces patch*.print_*.* 0 0 1289999999 1289999999 + %replaces maint*.print_*.* 0 0 1289999999 1289999999 + %replaces print 0 0 1289999999 1289999999 + %replaces fw_cups 0 0 1289999999 1289999999 + %incompat patch*.print_*.* 0 0 1289999999 1289999999 + %incompat maint*.print_*.* 0 0 1289999999 1289999999 + %incompat print 0 0 1289999999 1289999999 + %incompat fw_cups 0 0 1289999999 1289999999 + + %format all +</FONT></PRE> +<P>The subpackages come next, each with their own dependencies:</P> +<PRE><FONT SIZE="1"> + %subpackage libs + %description Common UNIX Printing System - shared libraries + %format rpm + %provides cups-libs 1:1.2.0 + %format deb + %provides libcups1 + %provides libcupsys2 + %provides libcupsys2-gnutls10 + %provides libcupsimage2 + %format all + + %subpackage devel + %description Common UNIX Printing System - development environment + %format rpm + %provides cups-devel 1:1.2.0 + %format deb + %provides libcupsys2-dev + %provides libcupsimage2-dev + %format all + + %subpackage lpd + %description Common UNIX Printing System - LPD support + %format rpm + %provides cups-lpd 1:1.2.0 + %format all + + %subpackage es + %description Common UNIX Printing System - Spanish support + + %subpackage ja + %description Common UNIX Printing System - Japanese support + + %subpackage +</FONT></PRE> + +<!-- NEED 3in --> +<H3>Server Programs</H3> +<P>The server programs are installed in the <CODE>SBINDIR</CODE> and <CODE> +SERVERBIN</CODE> directories. The image and PDF filters are + conditionally included based on the <CODE>IMGFILTERS</CODE> and <CODE> +PDFTOPS</CODE> variables, respectively:</P> +<PRE><FONT SIZE="1"> + f 0755 root sys $SBINDIR/cupsd scheduler/cupsd + + d 0755 root sys $SERVERBIN - + d 0755 root sys $SERVERBIN/backend - + f 0755 root sys $SERVERBIN/backend/ipp backend/ipp + l 0755 root sys $SERVERBIN/backend/http ipp + f 0755 root sys $SERVERBIN/backend/lpd backend/lpd + f 0755 root sys $SERVERBIN/backend/parallel backend/parallel + f 0755 root sys $SERVERBIN/backend/scsi backend/scsi + f 0755 root sys $SERVERBIN/backend/serial backend/serial + f 0755 root sys $SERVERBIN/backend/socket backend/socket + f 0755 root sys $SERVERBIN/backend/usb backend/usb + d 0755 root sys $SERVERBIN/cgi-bin - + f 0755 root sys $SERVERBIN/cgi-bin/admin.cgi cgi-bin/admin.cgi + f 0755 root sys $SERVERBIN/cgi-bin/classes.cgi cgi-bin/classes.cgi + f 0755 root sys $SERVERBIN/cgi-bin/help.cgi cgi-bin/help.cgi + f 0755 root sys $SERVERBIN/cgi-bin/jobs.cgi cgi-bin/jobs.cgi + f 0755 root sys $SERVERBIN/cgi-bin/printers.cgi cgi-bin/printers.cgi + d 0755 root sys $SERVERBIN/daemon - + f 0755 root sys $SERVERBIN/daemon/cups-deviced scheduler/cups-deviced + f 0755 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd + f 0755 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld + d 0755 root sys $SERVERBIN/driver - + d 0755 root sys $SERVERBIN/filter - + f 0755 root sys $SERVERBIN/filter/gziptoany filter/gziptoany + f 0755 root sys $SERVERBIN/filter/hpgltops filter/hpgltops + %if IMGFILTERS + f 0755 root sys $SERVERBIN/filter/imagetops filter/imagetops + f 0755 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster + %endif + %if PDFTOPS + f 0755 root sys $SERVERBIN/filter/pdftops pdftops/pdftops + %endif + f 0755 root sys $SERVERBIN/filter/pstops filter/pstops + f 0755 root sys $SERVERBIN/filter/rastertolabel filter/rastertolabel + l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel + f 0755 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson + f 0755 root sys $SERVERBIN/filter/rastertohp filter/rastertohp + f 0755 root sys $SERVERBIN/filter/texttops filter/texttops + d 0755 root sys $SERVERBIN/notifier - + f 0755 root sys $SERVERBIN/notifier/mailto notifier/mailto +</FONT></PRE> +<P>The <CODE>cups-lpd</CODE> program goes in the "lpd" subpackage:</P> +<PRE><FONT SIZE="1"> + %subpackage lpd + d 0755 root sys $SERVERBIN/daemon - + f 0755 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd + %subpackage +</FONT></PRE> +<H3>Administration Commands</H3> +<P>The administration commands are all pretty much the same. The only + difference is that IRIX needs a symlink for the <CODE>lpc</CODE> + program in the<VAR> /usr/etc</VAR> directory.</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $BINDIR - + l 0755 root sys $BINDIR/enable $SBINDIR/accept + l 0755 root sys $LIBDIR/accept $SBINDIR/accept + d 0755 root sys $SBINDIR - + l 0755 root sys $SBINDIR/cupsdisable accept + l 0755 root sys $SBINDIR/cupsenable accept + l 0755 root sys $BINDIR/disable $SBINDIR/accept + d 0755 root sys $LIBDIR - + l 0755 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin + l 0755 root sys $LIBDIR/reject accept + f 0755 root sys $SBINDIR/accept systemv/accept + f 0755 root sys $SBINDIR/cupsaddsmb systemv/cupsaddsmb + f 0755 root sys $SBINDIR/lpadmin systemv/lpadmin + f 0755 root sys $SBINDIR/lpc berkeley/lpc + f 0755 root sys $SBINDIR/lpinfo systemv/lpinfo + f 0755 root sys $SBINDIR/lpmove systemv/lpmove + l 0755 root sys $SBINDIR/reject accept + + %system irix + l 0755 root sys /usr/etc/lpc $SBINDIR/lpc + %system all +</FONT></PRE> +<H3>User Commands</H3> +<P>The user commands are all pretty much the same. As with the + administration commands, IRIX needs the Berkeley commands linked to a + different directory,<VAR> /usr/bsd</VAR>.</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $BINDIR - + f 0755 root sys $BINDIR/cancel systemv/cancel + f 0755 root sys $BINDIR/cupstestdsc systemv/cupstestdsc + f 0755 root sys $BINDIR/cupstestppd systemv/cupstestppd + f 0755 root sys $BINDIR/lp systemv/lp + f 0755 root sys $BINDIR/lpoptions systemv/lpoptions + f 4755 $CUPS_USER sys $BINDIR/lppasswd systemv/lppasswd + f 0755 root sys $BINDIR/lpq berkeley/lpq + f 0755 root sys $BINDIR/lpr berkeley/lpr + f 0755 root sys $BINDIR/lprm berkeley/lprm + f 0755 root sys $BINDIR/lpstat systemv/lpstat + + %system irix + l 0755 root sys /usr/bsd/lpq $BINDIR/lpq + l 0755 root sys /usr/bsd/lpr $BINDIR/lpr + l 0755 root sys /usr/bsd/lprm $BINDIR/lprm + %system all +</FONT></PRE> +<H3>Shared Libraries</H3> +<P>Shared libraries present their own challenges. AIX, HP-UX, and MacOS + X uses a different extension for shared libraries than the other + operating systems, and we only include the shared libraries if they are + enabled in the build:</P> +<PRE><FONT SIZE="1"> + %if DSOLIBS + %subpackage libs + %system hpux + f 0755 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2 + l 0755 root sys $LIBDIR/libcups.sl libcups.sl.2 + f 0755 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2 + l 0755 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2 + %system aix + f 0755 root sys $LIBDIR/libcups_s.a cups/libcups_s.a + f 0755 root sys $LIBDIR/libcupsimage_s.a filter/libcupsimage_s.a + %system darwin + f 0755 root sys $LIBDIR/libcups.2.dylib cups/libcups.2.dylib + l 0755 root sys $LIBDIR/libcups.dylib libcups.2.dylib + f 0755 root sys $LIBDIR/libcupsimage.2.dylib filter/libcupsimage.2.dylib + l 0755 root sys $LIBDIR/libcupsimage.dylib libcupsimage.2.dylib + %system !hpux !aix !darwin + f 0755 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2 + l 0755 root sys $LIBDIR/libcups.so libcups.so.2 + f 0755 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2 + l 0755 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif +</FONT></PRE> +<P>To keep things interesting, CUPS also supports separately compiled + 32-bit and 64-bit libraries on systems that support a mix of 32-bit and + 64-bit binaries. The <CODE>LIB32DIR</CODE> and <CODE>LIB64DIR</CODE> + variables are used to conditionally include the corresponding + libraries:</P> +<PRE><FONT SIZE="1"> + %if LIB32DIR + %subpackage libs + f 0755 root sys $LIB32DIR/libcups.so.2 cups/libcups.32.so.2 + l 0755 root sys $LIB32DIR/libcups.so libcups.so.2 + f 0755 root sys $LIB32DIR/libcupsimage.so.2 filter/libcupsimage.32.so.2 + l 0755 root sys $LIB32DIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif + + %if LIB64DIR + %subpackage libs + f 0755 root sys $LIB64DIR/libcups.so.2 cups/libcups.64.so.2 + l 0755 root sys $LIB64DIR/libcups.so libcups.so.2 + f 0755 root sys $LIB64DIR/libcupsimage.so.2 filter/libcupsimage.64.so.2 + l 0755 root sys $LIB64DIR/libcupsimage.so libcupsimage.so.2 + %system all + %subpackage + %endif +</FONT></PRE> +<H3>Directories</H3> +<P>The CUPS distribution uses several directories to hold the log, + request, and temporary files. The <CODE>CUPS_GROUP</CODE> and <CODE> +CUPS_PRIMARY_SYSTEM_GROUP</CODE> variables define the group names to use + for these directories:</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $LOGDIR - + d 0710 root $CUPS_GROUP $REQUESTS - + d 1770 root $CUPS_GROUP $REQUESTS/tmp - + d 0775 root $CUPS_GROUP $CACHEDIR - + d 0755 root $CUPS_GROUP $STATEDIR - + d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs - +</FONT></PRE> +<H3>Data Files</H3> +<P>CUPS has lots of data files. We use wildcards whenever possible:</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $DATADIR - + + d 0755 root sys $DATADIR/banners - + f 0644 root sys $DATADIR/banners/classified data/classified + f 0644 root sys $DATADIR/banners/confidential data/confidential + f 0644 root sys $DATADIR/banners/secret data/secret + f 0644 root sys $DATADIR/banners/standard data/standard + f 0644 root sys $DATADIR/banners/topsecret data/topsecret + f 0644 root sys $DATADIR/banners/unclassified data/unclassified + + d 0755 root sys $DATADIR/charsets - + f 0644 root sys $DATADIR/charsets data/*.txt + f 0644 root sys $DATADIR/charsets/windows-874 data/windows-874 + f 0644 root sys $DATADIR/charsets/windows-1250 data/windows-1250 + f 0644 root sys $DATADIR/charsets/windows-1251 data/windows-1251 + f 0644 root sys $DATADIR/charsets/windows-1252 data/windows-1252 + f 0644 root sys $DATADIR/charsets/windows-1253 data/windows-1253 + f 0644 root sys $DATADIR/charsets/windows-1254 data/windows-1254 + f 0644 root sys $DATADIR/charsets/windows-1255 data/windows-1255 + f 0644 root sys $DATADIR/charsets/windows-1256 data/windows-1256 + f 0644 root sys $DATADIR/charsets/windows-1257 data/windows-1257 + f 0644 root sys $DATADIR/charsets/windows-1258 data/windows-1258 + f 0644 root sys $DATADIR/charsets/iso-8859-1 data/iso-8859-1 + f 0644 root sys $DATADIR/charsets/iso-8859-2 data/iso-8859-2 + f 0644 root sys $DATADIR/charsets/iso-8859-3 data/iso-8859-3 + f 0644 root sys $DATADIR/charsets/iso-8859-4 data/iso-8859-4 + f 0644 root sys $DATADIR/charsets/iso-8859-5 data/iso-8859-5 + f 0644 root sys $DATADIR/charsets/iso-8859-6 data/iso-8859-6 + f 0644 root sys $DATADIR/charsets/iso-8859-7 data/iso-8859-7 + f 0644 root sys $DATADIR/charsets/iso-8859-8 data/iso-8859-8 + f 0644 root sys $DATADIR/charsets/iso-8859-9 data/iso-8859-9 + f 0644 root sys $DATADIR/charsets/iso-8859-10 data/iso-8859-10 + f 0644 root sys $DATADIR/charsets/iso-8859-13 data/iso-8859-13 + f 0644 root sys $DATADIR/charsets/iso-8859-14 data/iso-8859-14 + f 0644 root sys $DATADIR/charsets/iso-8859-15 data/iso-8859-15 + f 0644 root sys $DATADIR/charsets/utf-8 data/utf-8 + + d 0755 root sys $DATADIR/data - + f 0644 root sys $DATADIR/data/HPGLprolog data/HPGLprolog + f 0644 root sys $DATADIR/data/psglyphs data/psglyphs + f 0644 root sys $DATADIR/data/testprint.ps data/testprint.ps + + d 0755 root sys $DATADIR/fonts - + f 0644 root sys $DATADIR/fonts fonts/Courier* + f 0644 root sys $DATADIR/fonts/Symbol fonts/Symbol + + d 0755 root sys $DATADIR/model - + f 0644 root sys $DATADIR/model ppd/*.ppd + + d 0755 root sys $DATADIR/templates - + c 0644 root sys $DATADIR/templates templates/*.tmpl +</FONT></PRE> +<P>The template files for each of the language localizations are put in + separate subpackages:</P> +<PRE><FONT SIZE="1"> + # Japanese template files + %subpackage es + d 0755 root sys $DATADIR/templates/es + f 0644 root sys $DATADIR/templates/es templates/es/*.tmpl + %subpackage ja + d 0755 root sys $DATADIR/templates/ja + f 0644 root sys $DATADIR/templates/ja templates/ja/*.tmpl + %subpackage +</FONT></PRE> +<H3>Configuration Files</H3> +<P>The server configuration files and directories go in <CODE>SERVERROOT</CODE> +. The MIME configuration files are not treated as configuration files in + the distribution since new versions of CUPS may add filters and file + types that are required to make CUPS work:</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $SERVERROOT - + d 0755 root $CUPS_GROUP $SERVERROOT/interfaces - + d 0755 root $CUPS_GROUP $SERVERROOT/ppd - + c $CUPS_PERM root $CUPS_GROUP $SERVERROOT conf/*.conf + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/cupsd.conf.default conf/cupsd.conf + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/mime.convs conf/mime.convs + f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/mime.types conf/mime.types +</FONT></PRE> +<P>The PAM configuration file is only included if the configure script + found a PAM configuration directory:</P> +<PRE><FONT SIZE="1"> + %if PAMDIR + d 0755 root sys $PAMDIR - + c 0644 root sys $PAMDIR/cups conf/pam.std + %endif +</FONT></PRE> +<H3>Developer Files</H3> +<P>The developer files include the C header files, static libraries, and + help files. The static libraries are only included if they have been + built, which is specified using the <CODE>INSTALLSTATIC</CODE> + variable:</P> +<PRE><FONT SIZE="1"> + %subpackage devel + f 0755 root sys $BINDIR/cups-config cups-config + d 0755 root sys $INCLUDEDIR/cups - + f 0644 root sys $INCLUDEDIR/cups/cups.h cups/cups.h + f 0644 root sys $INCLUDEDIR/cups/http.h cups/http.h + f 0644 root sys $INCLUDEDIR/cups/image.h filter/image.h + f 0644 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h + f 0644 root sys $INCLUDEDIR/cups/language.h cups/language.h + f 0644 root sys $INCLUDEDIR/cups/md5.h cups/md5.h + f 0644 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h + f 0644 root sys $INCLUDEDIR/cups/raster.h filter/raster.h + + %if INSTALLSTATIC + f 0644 root sys $LIBDIR/libcups.a cups/libcups.a + f 0644 root sys $LIBDIR/libcupsimage.a filter/libcupsimage.a + %endif + + d 0755 root sys $DOCDIR/help - + f 0644 root sys $DOCDIR/help doc/help/api*.html + f 0644 root sys $DOCDIR/help doc/help/spec*.html + %subpackage +</FONT></PRE> +<H3>Documentation Files</H3> +<P>The documentation files go under <CODE>DOCDIR</CODE>. Wildcards take + care of most of the work:</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $DOCDIR - + f 0644 root sys $DOCDIR doc/*.css + f 0644 root sys $DOCDIR doc/*.html + d 0755 root sys $DOCDIR/help - + f 0644 root sys $DOCDIR/help/cgi.html doc/help/cgi.html + f 0644 root sys $DOCDIR/help/glossary.html doc/help/glossary.html + f 0644 root sys $DOCDIR/help/license.html doc/help/license.html + f 0644 root sys $DOCDIR/help/network.html doc/help/network.html + f 0644 root sys $DOCDIR/help/options.html doc/help/options.html + f 0644 root sys $DOCDIR/help/overview.html doc/help/overview.html + f 0644 root sys $DOCDIR/help/security.html doc/help/security.html + f 0644 root sys $DOCDIR/help/standard.html doc/help/standard.html + f 0644 root sys $DOCDIR/help/translation.html doc/help/translation.html + f 0644 root sys $DOCDIR/help/whatsnew.html doc/help/whatsnew.html + f 0644 root sys $DOCDIR/help doc/help/man-*.html + f 0644 root sys $DOCDIR/help doc/help/ref-*.html + d 0755 root sys $DOCDIR/images - + f 0644 root sys $DOCDIR/images doc/images/*.gif + f 0644 root sys $DOCDIR/images doc/images/*.jpg + f 0644 root sys $DOCDIR/images doc/images/*.png + f 0644 root sys $DOCDIR/robots.txt doc/robots.txt +</FONT></PRE> +<P>The Japanese and Spanish version of the documentation files go in the + corresponding subpackages:</P> +<PRE><FONT SIZE="1"> + # Localized documentation files + %subpackage es + d 0755 root sys $DOCDIR/es + f 0644 root sys $DOCDIR/es doc/es/*.html + d 0755 root sys $DOCDIR/es/images - + f 0644 root sys $DOCDIR/es/images doc/es/images/*.gif + %subpackage ja + d 0755 root sys $DOCDIR/ja + f 0644 root sys $DOCDIR/ja doc/ja/*.html + d 0755 root sys $DOCDIR/ja/images - + f 0644 root sys $DOCDIR/ja/images doc/ja/images/*.gif + %subpackage +</FONT></PRE> +<H3>Man Pages</H3> +<P>Man pages are almost as much fun as initialization scripts. HP-UX, + IRIX, and Solaris follow the System V convention of using section 1m + for administration commands instead of section 8 as is used for all + other operating systems. IRIX also places administrative commands in a + separate subdirectory:</P> +<PRE><FONT SIZE="1"> + d 0755 root sys $AMANDIR - + d 0755 root sys $AMANDIR/man$MAN8DIR - + d 0755 root sys $MANDIR - + d 0755 root sys $MANDIR/man1 - + d 0755 root sys $MANDIR/man5 - + d 0755 root sys $MANDIR/man7 - + + f 0644 root sys $MANDIR/man1/cancel.$MAN1EXT man/cancel.$MAN1EXT + f 0644 root sys $MANDIR/man1/cupstestdsc.$MAN1EXT man/cupstestdsc.$MAN1EXT + f 0644 root sys $MANDIR/man1/cupstestppd.$MAN1EXT man/cupstestppd.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpoptions.$MAN1EXT man/lpoptions.$MAN1EXT + f 0644 root sys $MANDIR/man1/lppasswd.$MAN1EXT man/lppasswd.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpq.$MAN1EXT man/lpq.$MAN1EXT + f 0644 root sys $MANDIR/man1/lprm.$MAN1EXT man/lprm.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpr.$MAN1EXT man/lpr.$MAN1EXT + f 0644 root sys $MANDIR/man1/lpstat.$MAN1EXT man/lpstat.$MAN1EXT + f 0644 root sys $MANDIR/man1/lp.$MAN1EXT man/lp.$MAN1EXT + + f 0644 root sys $MANDIR/man5/classes.conf.$MAN5EXT man/classes.conf.$MAN5EXT + f 0644 root sys $MANDIR/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.$MAN5EXT + f 0644 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.$MAN5EXT + f 0644 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.$MAN5EXT + f 0644 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.$MAN5EXT + + f 0644 root sys $MANDIR/man7/backend.$MAN7EXT man/backend.$MAN7EXT + f 0644 root sys $MANDIR/man7/filter.$MAN7EXT man/filter.$MAN7EXT + + f 0644 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT man/accept.$MAN8EXT + l 0644 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsaddsmb.$MAN8EXT man/cupsaddsmb.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cups-polld.$MAN8EXT man/cups-polld.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsd.$MAN8EXT man/cupsd.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/cupsenable.$MAN8EXT man/cupsenable.$MAN8EXT + l 0644 root sys $AMANDIR/man$MAN8DIR/cupsdisable.$MAN8EXT cupsenable.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpadmin.$MAN8EXT man/lpadmin.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpc.$MAN8EXT man/lpc.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpinfo.$MAN8EXT man/lpinfo.$MAN8EXT + f 0644 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.$MAN8EXT + + %subpackage devel + f 0644 root sys $MANDIR/man1/cups-config.$MAN1EXT man/cups-config.$MAN1EXT + + %subpackage lpd + d 0755 root sys $AMANDIR/man$MAN8DIR - + f 0644 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.$MAN8EXT + %subpackage +</FONT></PRE> +<H3>Startup Script</H3> +<P>The CUPS startup script is last and specifies a script name of <CODE> +cups</CODE>. Startup and shutdown scripts will be created with the + (default) names <CODE>S99cups</CODE> and <CODE>K00cups</CODE>, + respectively.</P> +<PRE><FONT SIZE="1"> + %system all + i 0555 root sys cups init/cups.sh +</FONT></PRE> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - GNU General Public License</A></H1> +<P ALIGN="CENTER">GNU GENERAL PUBLIC LICENSE +<BR> Version 2, June 1991</P> +<P ALIGN="CENTER">Copyright (C) 1989, 1991 Free Software Foundation, + Inc. +<BR> 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +<BR> Everyone is permitted to copy and distribute verbatim copies of + this license document, but changing it is not allowed.</P> +<P ALIGN="CENTER"><B>GNU GENERAL PUBLIC LICENSE +<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</B></P> +<P>0. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you".</P> +<P>Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + the Program is not restricted, and the output from the Program is + covered only if its contents constitute a work based on the Program + (independent of having been made by running the Program). Whether that + is true depends on what the Program does.</P> +<P>1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any warranty; + and give any other recipients of the Program a copy of this License + along with the Program.</P> +<P>You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.</P> +<P>2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions:</P> +<UL> +<P>a. You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change.</P> +<P>b. You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License.</P> +<P>c. If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the most ordinary way, to print or display an announcement including + an appropriate copyright notice and a notice that there is no warranty + (or else, saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling the user + how to view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an announcement, your + work based on the Program is not required to print an announcement.)</P> +</UL> +<P>These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.</P> +<P>Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program.</P> +<P>In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.</P> +<P>3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following:</P> +<UL> +<P>a. Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or,</P> +<P>b. Accompany it with a written offer, valid for at least three years, + to give any third party, for a charge no more than your cost of + physically performing source distribution, a complete machine-readable + copy of the corresponding source code, to be distributed under the + terms of Sections 1 and 2 above on a medium customarily used for + software interchange; or,</P> +<P>c. Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.)</P> +</UL> +<P>The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to control + compilation and installation of the executable. However, as a special + exception, the source code distributed need not include anything that + is normally distributed (in either source or binary form) with the + major components (compiler, kernel, and so on) of the operating system + on which the executable runs, unless that component itself accompanies + the executable.</P> +<P>If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent access + to copy the source code from the same place counts as distribution of + the source code, even though third parties are not compelled to copy + the source along with the object code.</P> +<P>4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt otherwise + to copy, modify, sublicense or distribute the Program is void, and will + automatically terminate your rights under this License. However, + parties who have received copies, or rights, from you under this + License will not have their licenses terminated so long as such parties + remain in full compliance.</P> +<P>5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying the + Program or works based on it.</P> +<P>6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further restrictions + on the recipients' exercise of the rights granted herein. You are not + responsible for enforcing compliance by third parties to this License.</P> +<P>7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent license + would not permit royalty-free redistribution of the Program by all + those who receive copies directly or indirectly through you, then the + only way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program.</P> +<P>If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances.</P> +<P>It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.</P> +<P>This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.</P> +<P>8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License may + add an explicit geographical distribution limitation excluding those + countries, so that distribution is permitted only in or among countries + not thus excluded. In such case, this License incorporates the + limitation as if written in the body of this License.</P> +<P>9. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns.</P> +<P>Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by + the Free Software Foundation.</P> +<P>10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we + sometimes make exceptions for this. Our decision will be guided by the + two goals of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software generally.</P> +<P ALIGN="CENTER"><B>NO WARRANTY</B></P> +<P>11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, + EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH + YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION.</P> +<P>12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.</P> +<P ALIGN="CENTER"><B>END OF TERMS AND CONDITIONS</B></P> +<P ALIGN="CENTER"><B>HOW TO APPLY THESE TERMS TO YOUR NEW PROGRAMS</B></P> +<P>If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it + free software which everyone can redistribute and change under these + terms.</P> +<P>To do so, attach the following notices to the program. It is safest + to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least + the "copyright" line and a pointer to where the full notice is found.</P> +<PRE> +<VAR>one line to give the program's name and an idea of what it does.</VAR> +Copyright (C) <VAR>yyyy</VAR> <VAR>name of author</VAR> + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +</PRE> +<P>Also add information on how to contact you by electronic and paper + mail.</P> +<P>If the program is interactive, make it output a short notice like + this when it starts in an interactive mode:</P> +<PRE> +Gnomovision version 69, Copyright (C) <VAR>year</VAR> <VAR>name of author</VAR> +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details +type `show w'. This is free software, and you are welcome +to redistribute it under certain conditions; type `show c' +for details. +</PRE> +<P>The hypothetical commands <SAMP>`show w'</SAMP> and <SAMP>`show c'</SAMP> + should show the appropriate parts of the General Public License. Of + course, the commands you use may be called something other than <SAMP> +`show w'</SAMP> and <SAMP>`show c'</SAMP>; they could even be + mouse-clicks or menu items--whatever suits your program.</P> +<P>You should also get your employer (if you work as a programmer) or + your school, if any, to sign a "copyright disclaimer" for the program, + if necessary. Here is a sample; alter the names:</P> +<PRE> +Yoyodyne, Inc., hereby disclaims all copyright +interest in the program `Gnomovision' +(which makes passes at compilers) written +by James Hacker. + +<VAR>signature of Ty Coon</VAR>, 1 April 1989 +Ty Coon, President of Vice +</PRE> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="MANPAGES">B - Command Reference</A></H1> + +<!-- NEW PAGE --> + +<!-- SECTION: Man Pages --> +<H2><A NAME="8_1">epm(1)</A></H2> +<H3><A name="NAME">Name</A></H3> + epm - create software packages. +<H3><A name="SYNOPSIS">Synopsis</A></H3> +<B> epm</B> [ -a<I> architecture</I> ] [ -f<I> format</I> ] [ -g ] [ -k + ] [ -m<I> name</I> ] [ -n[mrs] ] [ -s<I> setup.xpm</I> ] [ --depend ] [ + --help ] [ --keep-files ] [ --output-dir<I> directory</I> ] [ + --setup-image<I> setup.xpm</I> ] [ --setup-program<I> /foo/bar/setup</I> + ] [ --setup-types<I> setup.types</I> ] [ -v ] [<I> name=value</I> ...<I> + name=value</I> ] product [<I> listfile</I> ] +<H3><A name="DESCRIPTION">Description</A></H3> +<B> epm</B> generates software packages complete with installation, + removal, and (if necessary) patch scripts. Unless otherwise specified, + the files required for<I> product</I> are read from a file named "<I> +product</I>.list". +<P>The<I> -a</I> option ("architecture") specifies the actual + architecture for the software. Without this option the generic + processor architecture is used ("intel", "sparc", "mips", etc.)</P> +<P>The<I> -f</I> option ("format") specifies the distribution format:</P> +<DL> +<!-- NEED 3 --> +<DT>aix</DT> +<DD>Generate an AIX distribution suitable for installation on an AIX + system.</DD> + +<!-- NEED 3 --> +<DT>bsd</DT> +<DD>Generate a BSD distribution suitable for installation on a FreeBSD, + NetBSD, or OpenBSD system.</DD> + +<!-- NEED 3 --> +<DT>deb</DT> +<DD>Generate a Debian distribution suitable for installation on a Debian + Linux system.</DD> + +<!-- NEED 3 --> +<DT>inst, tardist</DT> +<DD>Generate an IRIX distribution suitable for installation on an system + running IRIX.</DD> + +<!-- NEED 3 --> +<DT>lsb, lsb-signed</DT> +<DD>Generate RPM packages for LSB-conforming systems. The lsb-signed + format uses the GPG private key you have defined in the ~/.rpmmacros + file.</DD> + +<!-- NEED 3 --> +<DT>native</DT> +<DD>Generate an native distribution. This uses<I> rpm</I> for Linux,<I> + inst</I> for IRIX,<I> pkg</I> for Solaris,<I> swinstall</I> for HP-UX,<I> + bsd</I> for FreeBSD, NetBSD, and OpenBSD, and<I> osx</I> for MacOS X. + All other operating systems default to the<I> portable</I> format.</DD> + +<!-- NEED 3 --> +<DT>osx</DT> +<DD>Generate a MacOS X software package.</DD> + +<!-- NEED 3 --> +<DT>pkg</DT> +<DD>Generate an AT&T software package. These are used primarily under + Solaris.</DD> + +<!-- NEED 3 --> +<DT>portable</DT> +<DD>Generate a portable distribution based on shell scripts and tar + files. The resulting distribution is installed and removed the same way + on all operating systems. [default]</DD> + +<!-- NEED 3 --> +<DT>rpm, rpm-signed</DT> +<DD>Generate a Red Hat Package Manager ("RPM") distribution suitable for + installation on a Red Hat Linux system. The rpm-signed format uses the + GPG private key you have defined in the ~/.rpmmacros file.</DD> + +<!-- NEED 3 --> +<DT>setld</DT> +<DD>Generate a Tru64 (setld) software distribution.</DD> + +<!-- NEED 3 --> +<DT>slackware</DT> +<DD>Generate a Slackware Linux software distribution.</DD> + +<!-- NEED 3 --> +<DT>swinstall, depot</DT> +<DD>Generate a HP-UX software distribution.</DD> +</DL> +<P>Executable files in the distribution are normally stripped of + debugging information when packaged. To disable this functionality use + the<I> -g</I> option.</P> +<P>Intermediate (spec, etc.) files used to create the distribution are + normally removed after the distribution is created. The<I> -k</I> + option keeps these files in the distribution directory.</P> +<P>The<I> -s</I> and<I> --setup-image</I> options ("setup") include the + ESP Software Wizard with the specified GIF or XPM image file with the + distribution. This option is currently only supported by portable and + RPM distributions.</P> +<P>The<I> --setup-program</I> option specifies the setup executable to + use with the distribution. This option is currently only supported by + portable distributions.</P> +<P>The<I> --setup-types</I> option specifies the<I> setup.types</I> file + to include with the distribution. This option is currently only + supported by portable distributions.</P> +<P>The<I> --output-dir</I> option specifies the directory to place + output file into. The default directory is based on the operating + system, version, and architecture.</P> +<P>The<I> -v</I> option ("verbose") increases the amount of information + that is reported. Use multiple v's for more verbose output.</P> +<P>The<I> --depend</I> option lists the dependent (source) files for all + files in the package.</P> +<P>Distributions normally are named + "product-version-system-release-machine.ext" and + "product-version-system-release-machine-patch.ext" (for patch + distributions.) The "system-release-machine" information can be + customized or eliminated using the<I> -n</I> option with the + appropriate trailing letters. Using<I> -n</I> by itself will remove the + "system-release-machine" string from the filename entirely. The + "system-release-machine" information can also be customized by using + the<I> -m</I> option with an arbitrary string.</P> +<P>Debian, IRIX, portable, and Red Hat distributions use the extensions + ".deb", ".tardist", "tar.gz", and ".rpm" respectively.</P> +<H3><A name="LIST_FILES">List Files</A></H3> + The EPM list file format is now described in the<I> epm.list(5)</I> man + page. +<H3><A name="KNOWN_BUGS">Known Bugs</A></H3> + EPM does not currently support generation of IRIX software patches. +<H3><A name="SEE_ALSO">See Also</A></H3> + epminstall(1) - add a directory, file, or symlink to a list file +<BR> mkepmlist(1) - make an epm list file from a directory +<BR> epm.list(5) - epm list file format +<BR> setup(1) - graphical setup program for the esp package manager +<H3><A name="COPYRIGHT">Copyright</A></H3> + Copyright 1999-2008 by Easy Software Products, All Rights Reserved. +<P>This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) any + later version.</P> +<P>This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details.</P> + +<!-- NEW PAGE --> + +<!-- SECTION: Man Pages --> +<H2><A NAME="8_2">epminstall(1)</A></H2> +<H3><A name="NAME">Name</A></H3> + epminstall - add a directory, file, or symlink to a list file. +<H3><A name="SYNOPSIS">Synopsis</A></H3> +<B> epminstall</B><I> options</I> file1 file2 ... fileN directory +<BR><B> epminstall</B><I> options</I> file1 file2 +<BR><B> epminstall</B><I> options</I> -d directory1 directory2 ... + directoryN +<H3><A name="DESCRIPTION">Description</A></H3> +<B> epminstall</B> adds or replaces a directory, file, or symlink in a + list file. The default list file is "epm.list" and can be overridden + using the<I> EPMLIST</I> environment variable or the<I> --list-file</I> + option. +<P>Entries are either added to the end of the list file or replaced + in-line. Comments, directives, and variable declarations in the list + file are preserved.</P> +<H3><A name="OPTIONS">Options</A></H3> +<B> epminstall</B> recognizes the standard Berkeley<I> install</I> + command options: +<DL> +<!-- NEED 3 --> +<DT>-b</DT> +<DD>Make a backup of existing files (ignored, default for EPM.)</DD> + +<!-- NEED 3 --> +<DT>-c</DT> +<DD>BSD old compatibility mode (ignored.)</DD> + +<!-- NEED 3 --> +<DT>-g<I> group</I></DT> +<DD>Set the group owner of the file or directory to<I> group</I>. The + default group is "sys".</DD> + +<!-- NEED 3 --> +<DT>-m<I> mode</I></DT> +<DD>Set the permissions of the file or directory to<I> mode</I>. The + default permissions are 0755 for directories and executable files and + 0644 for non-executable files.</DD> + +<!-- NEED 3 --> +<DT>-o<I> owner</I></DT> +<DD>Set the owner of the file or directory to<I> owner</I>. The default + owner is "root".</DD> + +<!-- NEED 3 --> +<DT>-s</DT> +<DD>Strip the files (ignored, default for EPM.)</DD> + +<!-- NEED 3 --> +<DT>--list-file<I> filename.list</I></DT> +<DD>Specify the list file to update.</DD> +</DL> +<H3><A name="SEE_ALSO">See Also</A></H3> + epm(1) - create software packages +<BR> mkepmlist(1) - make an epm list file from a directory +<BR> epm.list(5) - epm list file format +<H3><A name="COPYRIGHT">Copyright</A></H3> + Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +<P>This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) any + later version.</P> +<P>This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details.</P> + +<!-- NEW PAGE --> + +<!-- SECTION: Man Pages --> +<H2><A NAME="8_3">mkepmlist(1)</A></H2> +<H3><A name="NAME">Name</A></H3> + mkepmlist - make an epm list file from a directory. +<H3><A name="SYNOPSIS">Synopsis</A></H3> +<B> mkepmlist</B> [ -g<I> group</I> ] [ -u<I> user</I> ] [ --prefix<I> + directory</I> ]<I> directory</I> [ ...<I> directory</I> ] +<H3><A name="DESCRIPTION">Description</A></H3> +<B> mkepmlist</B> recursively generates file list entries for files, + links, and directories. The file list is send to the standard output. +<P>The<I> -g</I> option overrides the group ownership of the files in + the specified directories with the specified group name.</P> +<P>The<I> -u</I> option overrides the user ownership of the files in the + specified directories with the specified user name.</P> +<P>The<I> --prefix</I> option adds the specified directory to the + destination path. For example, if you installed files to "/opt/foo" and + wanted to build a distribution that installed the files in + "/usr/local", the following command would generate a file list that is + installed in "/usr/local":</P> +<PRE> + mkepmlist --prefix=/usr/local /opt/foo >foo.list +</PRE> +<H3><A name="SEE_ALSO">See Also</A></H3> + epm(1) - create software packages +<BR> epminstall(1) - add a directory, file, or symlink to a list file +<BR> epm.list(5) - epm list file format +<H3><A name="COPYRIGHT">Copyright</A></H3> + Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +<P>This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) any + later version.</P> +<P>This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details.</P> + +<!-- NEW PAGE --> + +<!-- SECTION: Man Pages --> +<H2><A NAME="8_4">setup(1)</A></H2> +<H3><A name="NAME">Name</A></H3> + setup - graphical setup program for the esp package manager +<H3><A name="SYNOPSIS">Synopsis</A></H3> +<B> setup</B> [<I> directory</I> ] +<H3><A name="DESCRIPTION">Description</A></H3> +<B> setup</B> provides a graphical installation interface for + EPM-generated portable installation packages. It presents a + step-by-step dialog for collecting a list of packages to install and + accepting any license agreements for those packages. +<P><B>setup</B> searches for products in the current directory or the + directory specified on the command-line.</P> +<H3><A name="INSTALLATION_TYPES">Installation Types</A></H3> + The default type of installation is "custom". That is, users will be + able to select from the list of products and install them. +<P><B>setup</B> also supports other types of installations. The<I> + setup.types</I> file, if present, defines the other installation types.</P> +<H3><A name="SEE_ALSO">See Also</A></H3> + epm(1) - create software packages. +<BR> setup.types(5) - epm gui setup types file format. +<H3><A name="COPYRIGHT">Copyright</A></H3> + Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +<P>This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) any + later version.</P> +<P>This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details.</P> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="REFERENCE">C - List File Reference</A></H1> +<P>This appendix provides a complete reference for the EPM list file and + setup types formats.</P> +<H2><A NAME="9_1">The EPM List File Format</A></H2> +<P>Each<I> EPM</I> product has an associated list file that describes + the files to include with the product. Comment lines begin with the "#" + character and are ignored. All other non-blank lines must begin with a + letter, dollar sign ("$"), or the percent sign ("%").</P> + +<!-- NEED 3in --> +<H3>List File Directives</H3> +<P>The following list describes all of the list file directives + supported by<I> EPM</I>:</P> +<DL> +<DD> +<DL> +<DT>$name=value +<BR> </DT> +<DD>Sets the named variable to<I> value</I>.<B> Note:</B> Variables set + in the list file are overridden by variables specified on the + command-line or in the current environment. +<BR> </DD> + +<!-- NEED 2in --> +<DT>%copyright<I> copyright notice</I> +<BR> </DT> +<DD>Sets the copyright notice for the file. +<BR> </DD> +<DT>%description<I> description text</I> +<BR> </DT> +<DD>Adds a line of descriptive text to the distribution. Multiple lines + are supported. +<BR> </DD> +<DT>%format<I> format [... format]</I> +<BR> </DT> +<DD>Uses following files and directives only if the distribution format + is the same as<I> format</I>. +<BR> </DD> +<DT>%format !<I>format [... format]</I> +<BR> </DT> +<DD>Uses following files and directives only if the distribution format + is not the same as<I> format</I>. +<BR> </DD> +<DT>%include<I> filename</I> +<BR> </DT> +<DD>Includes files listed in<I> filename</I>. +<BR> </DD> +<DT>%incompat<I> product</I></DT> +<DT>%incompat<I> filename</I> +<BR> </DT> +<DD>Indicates that this product is incompatible with the named product + or file. +<BR> </DD> +<DT>%if<I> variable [... variable]</I> +<BR> %if !<I>variable [... variable]</I> +<BR> %ifdef<I> variable [... variable]</I> +<BR> %ifdef !<I>variable [... variable]</I> +<BR> %elseif<I> variable [... variable]</I> +<BR> %elseif !<I>variable [... variable]</I> +<BR> %elseifdef<I> variable [... variable]</I> +<BR> %elseifdef !<I>variable [... variable]</I> +<BR> %else +<BR> %endif +<BR> </DT> +<DD>Conditionally includes lines in the list file. The<I> %if</I> lines + include the lines that follow if the named variables are (not) defined + with a value. The<I> %ifdef</I> lines include the lines that follow if + the named variables are (not) defined with any value. These conditional + lines cannot be nested. +<BR> </DD> +<DT>%install<I> script or program</I> +<BR> </DT> +<DD>Specifies a script or program to be run after all files are + installed. (This has been obsoleted by the %postinstall directive) +<BR> </DD> +<DT>%license<I> license file</I> +<BR> </DT> +<DD>Specifies the file to display as the software license. +<BR> </DD> +<DT>%packager<I> name of packager</I> +<BR> </DT> +<DD>Specifies the name of the packager. +<BR> </DD> +<DT>%patch<I> script or program</I> +<BR> </DT> +<DD>Specifies a script or program to be run after all files are patched. + (This has been obsoleted by the %postpatch directive) +<BR> </DD> + +<!-- NEED 2in --> +<DT>%postinstall<I> script or program</I> +<BR> %postinstall <<I>scriptfile</I> +<BR> %postinstall <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run after all files are + installed. +<BR> </DD> +<DT>%postpatch<I> script or program</I> +<BR> %postpatch <<I>scriptfile</I> +<BR> %postpatch <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run after all files are patched. +<BR> </DD> +<DT>%postremove<I> script or program</I> +<BR> %postremove <<I>scriptfile</I> +<BR> %postremove <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run after removing files. +<BR> </DD> +<DT>%preinstall<I> script or program</I> +<BR> %preinstall <<I>scriptfile</I> +<BR> %preinstall <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run before all files are + installed. +<BR> </DD> +<DT>%prepatch<I> script or program</I> +<BR> %prepatch <<I>scriptfile</I> +<BR> %prepatch <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run before all files are + patched. +<BR> </DD> +<DT>%preremove<I> script or program</I> +<BR> %preremove <<I>scriptfile</I> +<BR> %preremove <<<I>string</I> +<BR> </DT> +<DD>Specifies a script or program to be run before removing files. +<BR> </DD> +<DT>%product<I> product name</I> +<BR> </DT> +<DD>Specifies the product name. +<BR> </DD> + +<!-- NEED 2in --> +<DT>%provides<I> product name</I> +<BR> </DT> +<DD>Indicates that this product provides the named dependency. +<BR> </DD> +<DT>%readme<I> readme file</I> +<BR> </DT> +<DD>Specifies a README file to be included in the distribution. +<BR> </DD> +<DT>%remove<I> script or program</I> +<BR> </DT> +<DD>Specifies a script or program to be run before removing files. (This + has been obsoleted by the %preremove directive) +<BR> </DD> +<DT>%release<I> number</I> +<BR> </DT> +<DD>Specifies the release or build number of a product (defaults to 0). +<BR> </DD> +<DT>%replaces<I> product</I> +<BR> </DT> +<DD>Indicates that this product replaces the named product. +<BR> </DD> +<DT>%requires<I> product</I></DT> +<DT>%requires<I> filename</I> +<BR> </DT> +<DD>Indicates that this product requires the named product or file. +<BR> </DD> +<DT>%system<I> system[-release] [... system[-release]]</I> +<BR> </DT> +<DD>Specifies that the following files should only be used for the + specified operating systems and releases. +<BR> </DD> +<DT>%system !<I>system[-release] [... system[-release]]</I> +<BR> </DT> +<DD>Specifies that the following files should not be used for the + specified operating systems and releases. +<BR> </DD> +<DT>%system all +<BR> </DT> +<DD>Specifies that the following files are applicable to all operating + systems. +<BR> </DD> +<DT>%vendor<I> vendor or author name</I> +<BR> </DT> +<DD>Specifies the vendor or author of the product. +<BR> </DD> + +<!-- NEED 2in --> +<DT>%version<I> version number</I> +<BR> </DT> +<DD>Specifies the version number of the product. +<BR> </DD> +<DT>c<I> mode user group destination source</I></DT> +<DT>C<I> mode user group destination source</I> +<BR> </DT> +<DD>Specifies a configuration file for installation. The second form + specifies that the file has changed or is new and should be included as + part of a patch. Configuration files are installed as "destination.N" + if the destination already exists. +<BR> </DD> +<DT>d<I> mode user group destination -</I></DT> +<DT>D<I> mode user group destination -</I> +<BR> </DT> +<DD>Specifies a directory should be created when installing the + software. The second form specifies that the directory is new and + should be included as part of a patch. +<BR> </DD> + +<!-- NEED 2in --> +<DT>f<I> mode user group destination source [nostrip()]</I></DT> +<DT>F<I> mode user group destination source [nostrip()]</I> +<BR> </DT> +<DD>Specifies a file for installation. The second form specifies that + the file has changed or is new and should be included as part of a + patch. If the "nostrip()" option is included, the file will not be + stripped before the installation is created. +<BR> </DD> +<DT>f<I> mode user group destination source/pattern [nostrip()]</I></DT> +<DT>F<I> mode user group destination source/pattern [nostrip()]</I> +<BR> </DT> +<DD>Specifies one or more files for installation using shell wildcard + patterns. The second form specifies that the files have changed or are + new and should be included as part of a patch. If the "nostrip()" + option is included, the file will not be stripped before the + installation is created. +<BR> </DD> +<DT>i<I> mode user group service-name source ["options"]</I></DT> +<DT>I<I> mode user group service-name source ["options"]</I> +<BR> </DT> +<DD>Specifies an initialization script for installation. The second form + specifies that the file has changed or is new and should be included as + part of a patch. Initialization scripts are stored in<VAR> + /etc/software/init.d</VAR> and are linked to the appropriate + system-specific directories for run levels 0, 2, 3, and 5. + Initialization scripts<B> must</B> accept at least the<I> start</I> and<I> + stop</I> commands. The optional<I> options</I> following the source + filename can be any of the following: +<BR> +<DL> +<DT>order(<I>string</I>)</DT> +<DD>Specifies the relative startup order compared to the required and + used system functions. Supported values include First, Early, None, + Late, and Last (OSX only).</DD> +<DT>provides(<I>name(s)</I>)</DT> +<DD>Specifies names of system functions that are provided by this + startup item (OSX only).</DD> + +<!-- NEED 3 --> +<DT>requires(<I>name(s)</I>)</DT> +<DD>Specifies names of system functions that are required by this + startup item (OSX only).</DD> +<DT>runlevels(<I>levels</I>)</DT> +<DD>Specifies the run levels to use.</DD> +<DT>start(<I>number</I>)</DT> +<DD>Specifies the starting sequence number from 00 to 99.</DD> +<DT>stop(<I>number</I>)</DT> +<DD>Specifies the ending sequence number from 00 to 99.</DD> +<DT>uses(<I>name(s)</I>)</DT> +<DD>Specifies names of system functions that are used by this startup + item (OSX only).</DD> +</DL> +<BR> </DD> + +<!-- NEED 2in --> +<DT>l<I> mode user group destination source</I></DT> +<DT>L<I> mode user group destination source</I> +<BR> </DT> +<DD>Specifies a symbolic link in the installation. The second form + specifies that the link has changed or is new and should be included as + part of a patch. +<BR> </DD> +<DT>R<I> mode user group destination</I> +<BR> </DT> +<DD>Specifies that the file is to be removed upon patching. The<I> user</I> + and<I> group</I> fields are ignored. The<I> mode</I> field is only used + to determine if a check should be made for a previous version of the + file. +<BR> </DD> +</DL> +</DD> +</DL> + +<!-- NEED 3in --> +<H3>List Variables</H3> +<P><I>EPM</I> maintains a list of variables and their values which can + be used to substitute values in the list file. These variables are + imported from the current environment and taken from the command-line + and list file as provided. Substitutions occur when the variable name + is referenced with the dollar sign ($):</P> +<PRE> + %postinstall <<EOF + echo What is your name: + read $$name + echo Your name is $$name + EOF + + f 0555 root sys ${bindir}/foo foo + f 0555 root sys $datadir/foo/foo.dat foo.dat +</PRE> +<P>Variable names can be surrounded by curly brackets (${name}) or alone + ($name); without brackets the name is terminated by the first slash + (/), dash (-), or whitespace. The dollar sign can be inserted using $$.</P> + +<!-- NEED 5in --> +<H2><A NAME="SETUPTYPES">The setup.types File</A></H2> +<P>The EPM<B> setup</B> program normally presents the user with a list + of software products to install, which is called a "custom" software + installation.</P> +<P>If a file called<I> setup.types</I> is present in the package + directory, the user will instead be presented with a list of + installation types. Each type has an associated product list which + determines the products that are installed by default. If a type has no + products associated with it, then it is treated as a custom + installation and the user is presented with a list of packages to + choose from.</P> +<P>The<I> setup.types</I> file is an ASCII text file consisting of type + and product lines. Comments can be inserted by starting a line with the + pound sign (#). Each installation type is defined by a line starting + with the word <CODE>TYPE</CODE>. Products are defined by a line + starting with the word <CODE>INSTALL</CODE>:</P> +<PRE> + # Pre-select the user packages + TYPE Typical End-User Configuration + INSTALL foo + INSTALL foo-help + + # Pre-select the developer packages + TYPE Typical Developer Configuration + INSTALL foo + INSTALL foo-help + INSTALL foo-devel + INSTALL foo-examples + + # Allow the user to select packages + TYPE Custom Configuration +</PRE> +<P>In the example above, three installation types are defined. Since the + last type includes no products, the user will be presented with the + full list of products to choose from.</P> +<HR NOSHADE> +<H1 ALIGN="RIGHT"><A NAME="RELNOTES">D - Release Notes</A></H1> +<P>This appendix lists the change log for each release of the EPM + software.</P> +<H2><A NAME="10_1">Changes in EPM v4.2</A></H2> +<UL> +<LI>EPM now supports a %arch conditional directive (STR #27)</LI> +<LI>EPM now uses hard links whenever possible instead of copying files + for distribution (STR #21)</LI> +<LI>EPM no longer puts files in /export in the root file set for AIX + packages (STR #15)</LI> +<LI>EPM did not work with newer versions of RPM (STR #23, STR #25)</LI> +<LI>EPM did not clean up temporary files from Solaris packages (STR #20)</LI> +<LI>Building Solaris gzip'd packages failed if the pkg.gz file already + existed (STR #16)</LI> +<LI>Fixed handling of %preremove and %postremove for AIX packages (STR + #22)</LI> +<LI>Fixed directory permissions in HP-UX packages (STR #24)</LI> +<LI>Removed unnecessary quoting of "!" in filenames (STR #26)</LI> +<LI>Added support for signed RPM packages (STR #19)</LI> +<LI>Added support for inclusion of format-specific packaging files and + directives via a %literal directive (STR #5)</LI> +<LI>*BSD init scripts were not installed properly.</LI> +<LI>EPM now displays a warning message when a variable is undefined (STR + #10)</LI> +<LI>*BSD dependencies on versioned packages are now specified correctly + (STR #4)</LI> +<LI>EPM now uses /usr/sbin/pkg_create on FreeBSD (STR #2)</LI> +<LI>FreeBSD packages are now created with a .tbz extension (STR #1)</LI> +<LI>FreeBSD packages incorrectly assumed that chown was installed in + /bin (STR #3)</LI> +<LI>Added support for an "lsb" package format which uses RPM with the + LSB dependencies (STR #7)</LI> +<LI>The configure script now supports a --with-archflags and no longer + automatically builds universal binaries on Mac OS X.</LI> +<LI>The epm program now automatically detects when the setup GUI is not + available, displays a warning message, and then creates a non-GUI + package.</LI> +<LI>RPM packages did not map %replaces to Obsoletes:</LI> +</UL> +<H2><A NAME="10_2">Changes in EPM v4.1</A></H2> +<UL> +<LI>Mac OS X portable packages did not create a correct Uninstall + application.</LI> +<LI>The temporary package files for portable packages are now removed + after creation of the .tar.gz file unless the -k (keep files) option is + used.</LI> +<LI>The RPM summary string for subpackages did not contain the first + line of the package description as for other package formats.</LI> +<LI>The setup and uninst GUIs now support installing and removing RPM + packages.</LI> +<LI>The setup GUI now confirms acceptance of all licenses prior to + installing the first package.</LI> +<LI>Subpackages are no longer automatically dependent on the main + package.</LI> +<LI>Multi-line descriptions were not embedded properly into portable + package install/patch/remove scripts.</LI> +<LI>Updated the setup and uninstall GUIs for a nicer look-n-feel.</LI> +<LI>Mac OS X portable packages now show the proper name, version, and + copyright for the packaged software instead of the EPM version and + copyright...</LI> +<LI>Fixed a problem with creation of Mac OS X metapackages with the + latest Xcode.</LI> +<LI>EPM now removes the individual .rpm and .deb files when creating a + package with subpackages unless the -k option (keep files) is used.</LI> +<LI>EPM now only warns about package names containing characters other + than letters and numbers.</LI> +<LI>EPM now generates disk images as well as a .tar.gz file when + creating portable packages on Mac OS X.</LI> +</UL> +<H2><A NAME="10_3">Changes in EPM v4.0</A></H2> +<UL> +<LI>New subpackage support for creating multiple dependent packages or a + combined package with selectable subpackages, depending on the package + format.</LI> +<LI>Added support for compressing the package files in portable packages + (reduces disk space requirements on platforms that provide gzip...)</LI> +<LI>Added support for custom platform names via the new "-m name" + option.</LI> +<LI>Added support for non-numeric %release values.</LI> +<LI>Added new --depend option to list all of the source files that a + package depends on.</LI> +<LI>The setup GUI now sets the EPM_INSTALL_TYPE environment variable to + the value of the selected TYPE line in the setup.types file.</LI> +<LI>Fixed NetBSD and OpenBSD packaging support - no longer use + FreeBSD-specific extensions to pkg_create on those variants.</LI> +<LI>Fixed PowerPC platform support for RPM and Debian packages.</LI> +<LI>Many fixes to AIX package support.</LI> +<LI>Tru64 packages with init scripts now work when installing for the + first time.</LI> +<LI>RPM file dependencies should now work properly.</LI> +<LI>Portable product names containing spaces will now display properly.</LI> +</UL> + +<!-- NEW SHEET + HEADER CENTER "" + FOOTER LEFT "" + FOOTER RIGHT "" --> +<P> </P> + +<!-- NEW SHEET --> +<P> </P> +</BODY> +</HTML> diff --git a/doc/epm.list.man b/doc/epm.list.man new file mode 100644 index 0000000..827107f --- /dev/null +++ b/doc/epm.list.man @@ -0,0 +1,372 @@ +.\" +.\" "$Id: epm.list.man 842 2010-12-31 02:16:45Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM) list file format. +.\" +.\" Copyright 1999-2010 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH epm.list 5 "ESP Package Manager" "30 December 2010" "Easy Software Products" +.SH NAME +epm.list \- epm list file format. +.SH DESCRIPTION +Each \fIEPM\fR product has an associated list file that +describes the files to include with the product. Comment lines +begin with the "#" character and are ignored. All other +non-blank lines must begin with a letter, dollar sign ("$"), or +the percent sign ("%") as follows: +.TP 5 +$name=value +.br +Sets the named variable to \fIvalue\fR. \fBNote:\fR Variables +set in the list file are overridden by variables specified on +the command-line or in the current environment. +.TP 5 +%arch all +.br +Uses following files and directives on all processor architectures. +.TP 5 +%arch \fIarchitecture [... architecture]\fR +.br +Uses following files and directives on the named processor architectures. +.TP 5 +%arch !\fIarchitecture [... architecture]\fR +.br +Uses following files and directives on all but the named processor +architectures. +.TP 5 +%copyright \fIcopyright notice\fR +.br +Sets the copyright notice for the file. +.TP 5 +%description \fIdescription text\fR +.br +Adds a line of descriptive text to the distribution. Multiple lines are +supported. +.TP 5 +%format \fIformat [... format]\fR +.br +Uses following files and directives only if the distribution format is +the same as \fIformat\fR. +.TP 5 +%format !\fIformat [... format]\fR +.br +Uses following files and directives only if the distribution format is +not the same as \fIformat\fR. +.TP 5 +%if \fIvariable\fR [... variable]\fR +.TP 5 +%if !\fIvariable\fR [... variable]\fR +.TP 5 +%ifdef \fIvariable\fR [... variable]\fR +.TP 5 +%ifdef !\fIvariable\fR [... variable]\fR +.TP 5 +%elseif \fIvariable\fR [... variable]\fR +.TP 5 +%elseif !\fIvariable\fR [... variable]\fR +.TP 5 +%elseifdef \fIvariable\fR [... variable]\fR +.TP 5 +%elseifdef !\fIvariable\fR [... variable]\fR +.TP 5 +%else +.TP 5 +%endif +.br +Conditionally includes lines in the list file. The \fI%if\fR +lines include the lines that follow if the named variables are +(not) defined with a value. The \fI%ifdef\fR lines include the +lines that follow if the named variables are (not) defined with +any value. These conditional lines cannot be nested. +.TP 5 +%include \fIfilename\fR +.br +Includes files listed in \fIfilename\fR. +.TP 5 +%incompat \fIproduct\fR +.TP 5 +%incompat \fIfilename\fR +.br +Indicates that this product is incompatible with the named product or +file. +.TP 5 +%install \fIscript or program\fR +.br +Specifies a script or program to be run after all files are installed. +(This has been obsoleted by the %postinstall directive) +.TP 5 +%license \fIlicense file\fR +.br +Specifies the file to display as the software license. +.TP 5 +%literal(section) \fIline\fR +.TP 5 +%literal(section) <\fIfile\fR +.TP 5 +%literal(section) <<\fIstring\fR +.br +Specifies format-specific literal data for packaging. Currently only supported +for RPM and PKG packages. +.TP 5 +%packager \fIname of packager\fR +.br +Specifies the name of the packager. +.TP 5 +%patch \fIscript or program\fR +.br +Specifies a script or program to be run after all files are patched. +(This has been obsoleted by the %postpatch directive) +.TP 5 +%postinstall \fIscript or program\fR +.TP 5 +%postinstall <\fIscriptfile\fR +.TP 5 +%postinstall <<\fIstring\fR +.br +Specifies a script or program to be run after all files are installed. +.TP 5 +%postpatch \fIscript or program\fR +.TP 5 +%postpatch <\fIscriptfile\fR +.TP 5 +%postpatch <<\fIstring\fR +.br +Specifies a script or program to be run after all files are patched. +.TP 5 +%postremove \fIscript or program\fR +.TP 5 +%postremove <\fIscriptfile\fR +.TP 5 +%postremove <<\fIstring\fR +.br +Specifies a script or program to be run after removing files. +.TP 5 +%preinstall \fIscript or program\fR +.TP 5 +%preinstall <\fIscriptfile\fR +.TP 5 +%preinstall <<\fIstring\fR +.br +Specifies a script or program to be run before all files are installed. +.TP 5 +%prepatch \fIscript or program\fR +.TP 5 +%prepatch <\fIscriptfile\fR +.TP 5 +%prepatch <<\fIstring\fR +.br +Specifies a script or program to be run before all files are patched. +.TP 5 +%preremove \fIscript or program\fR +.TP 5 +%preremove <\fIscriptfile\fR +.TP 5 +%preremove <<\fIstring\fR +.br +Specifies a script or program to be run before removing files. +.TP 5 +%product \fIproduct name\fR +.br +Specifies the product name. +.TP 5 +%readme \fIreadme file\fR +.br +Specifies a README file to be included in the distribution. +.TP 5 +%remove \fIscript or program\fR +.br +Specifies a script or program to be run before removing files. +(This has been obsoleted by the %preremove directive) +.TP 5 +%release \fInumber\fR +.br +Specifies the release or build number of a product (defaults to 0). +.TP 5 +%replaces \fIproduct\fR +.br +Indicates that this product replaces the named product. +.TP 5 +%requires \fIproduct\fR +.TP 5 +%requires \fIfilename\fR +.br +Indicates that this product requires the named product or file. +.TP 5 +%subpackage +.TP 5 +%subpackage \fIname\fR +.br +Selects the named subpackage; if no name is given, selects the +main (parent) package. +.TP 5 +%vendor \fIvendor or author name\fR +.br +Specifies the vendor or author of the product. +.TP 5 +%version \fIversion number\fR +.br +Specifies the version number of the product. +.TP 5 +%system \fIsystem[-release] [... system[-release]]\fR +.br +Specifies that the following files should only be used for the specified +operating systems and releases. +.TP 5 +%system !\fIsystem[-release] [... system[-release]]\fR +.br +Specifies that the following files should not be used for the specified +operating systems and releases. +.TP 5 +%system all +.br +Specifies that the following files are applicable to all operating systems. +.TP 5 +c \fImode user group destination source\fR +.TP 5 +C \fImode user group destination source\fR +.br +Specifies a configuration file for installation. The second form +specifies that the file has changed or is new and should be included as +part of a patch. Configuration files are installed as "destination.N" +if the destination already exists. +.TP 5 +d \fImode user group destination -\fR +.TP 5 +D \fImode user group destination -\fR +.br +Specifies a directory should be created when installing the software. The +second form specifies that the directory is new and should be included as part +of a patch. +.TP 5 +f \fImode user group destination source [nostrip()]\fR +.TP 5 +F \fImode user group destination source [nostrip()]\fR +.br +Specifies a file for installation. The second form specifies +that the file has changed or is new and should be included as +part of a patch. If the "nostrip()" option is included, the file +will not be stripped before the installation is created. +.TP 5 +f \fImode user group destination source/pattern [nostrip()]\fR +.TP 5 +F \fImode user group destination source/pattern [nostrip()]\fR +.br +Specifies one or more files for installation using shell +wildcard patterns. The second form specifies that the files have +changed or are new and should be included as part of a patch. If +the "nostrip()" option is included, the file will not be +stripped before the installation is created. +.TP 5 +i \fImode user group service-name source ["options"]\fR +.TP 5 +I \fImode user group service-name source ["options"]\fR +.br +Specifies an initialization script for installation. The second form +specifies that the file has changed or is new and should be included as +part of a patch. Initialization scripts are stored in /etc/software/init.d and +are linked to the appropriate system-specific directories for run levels 0, +2, 3, and 5. Initialization scripts \fBmust\fR accept at least the \fIstart\fR +and \fIstop\fR commands. The optional \fIoptions\fR following the source +filename can be any of the following: + +.TP 10 + order(\fIstring\fR) +.br +Specifies the relative startup order compared to the required +and used system functions. Supported values include First, +Early, None, Late, and Last (OSX only). +.TP 10 + provides(\fIname(s)\fR) +.br +Specifies names of system functions that are provided by this startup +item (OSX only). +.TP 10 + requires(\fIname(s)\fR) +.br +Specifies names of system functions that are required by this startup +item (OSX only). +.TP 10 + runlevel(\fIlevels\fR) +.br +Specifies the run levels to use. +.TP 10 + start(\fInumber\fR) +.br +Specifies the starting sequence number from 00 to 99. +.TP 10 + stop(\fInumber\fR) +.br +Specifies the ending sequence number from 00 to 99. +.TP 10 + uses(\fIname(s)\fR) +.br +Specifies names of system functions that are used by this startup +item (OSX only). + +.TP 5 +l \fImode user group destination source\fR +.TP 5 +L \fImode user group destination source\fR +.br +Specifies a symbolic link in the installation. The second form specifies that +the link has changed or is new and should be included as part of a patch. +.TP 5 +R \fImode user group destination\fR +.br +Specifies that the file is to be removed upon patching. The \fIuser\fR and +\fIgroup\fR fields are ignored. The \fImode\fR field is only used to determine +if a check should be made for a previous version of the file. +.SH LIST VARIABLES +\fIEPM\fR maintains a list of variables and their values which can be used +to substitute values in the list file. These variables are imported from the +current environment and taken from the command-line and list file as provided. +Substitutions occur when the variable name is referenced with the dollar sign +($): +.nf +.br + + %postinstall <<EOF + echo What is your name: + read $$name + Your name is $$name + EOF + + f 0555 root sys ${bindir}/foo foo + f 0555 root sys $datadir/foo/foo.dat foo.dat +.fi +.LP +Variable names can be surrounded by curley brackets (${name}) or +alone ($name); without brackets the name is terminated by the +first slash (/), dash (-), or whitespace. The dollar sign can be +inserted using $$. +.SH SEE ALSO +epm(1) - create software packages +.br +epminstall(1) - add a directory, file, or symlink to a list file +.br +mkepmlist(1) - make an epm list file from a directory +.SH COPYRIGHT +Copyright 1999-2010 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: epm.list.man 842 2010-12-31 02:16:45Z mike $". +.\" diff --git a/doc/epm.man b/doc/epm.man new file mode 100644 index 0000000..e096d7d --- /dev/null +++ b/doc/epm.man @@ -0,0 +1,192 @@ +.\" +.\" "$Id: epm.man 816 2008-08-27 03:44:15Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM). +.\" +.\" Copyright 1999-2008 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH epm 1 "ESP Package Manager" "26 August 2008" "Easy Software Products" +.SH NAME +epm \- create software packages. +.SH SYNOPSIS +.B epm +[ -a +.I architecture +] [ -f +.I format +] [ -g ] [ -k ] [ -m +.I name +] [ -n[mrs] ] [ -s +.I setup.xpm +] [ --depend ] [ --help ] [ --keep-files ] [ --output-dir +.I directory +] [ --setup-image +.I setup.xpm +] [ --setup-program +.I /foo/bar/setup +] [ --setup-types +.I setup.types +] [ -v ] [ +.I name=value +\... +.I name=value +] product [ +.I listfile +] +.SH DESCRIPTION +\fBepm\fR generates software packages complete with installation, +removal, and (if necessary) patch scripts. Unless otherwise +specified, the files required for \fIproduct\fR are read from a +file named "\fIproduct\fR.list". +.LP +The \fI-a\fR option ("architecture") specifies the actual +architecture for the software. Without this option the generic +processor architecture is used ("intel", "sparc", "mips", etc.) +.LP +The \fI-f\fR option ("format") specifies the distribution format: +.TP 5 +aix +.br +Generate an AIX distribution suitable for installation on an AIX system. +.TP 5 +bsd +.br +Generate a BSD distribution suitable for installation on a FreeBSD, NetBSD, +or OpenBSD system. +.TP 5 +deb +.br +Generate a Debian distribution suitable for installation on a Debian Linux +system. +.TP 5 +inst, tardist +.br +Generate an IRIX distribution suitable for installation on an system running +IRIX. +.TP 5 +lsb, lsb-signed +.br +Generate RPM packages for LSB-conforming systems. The lsb-signed format uses +the GPG private key you have defined in the ~/.rpmmacros file. +.TP 5 +native +.br +Generate an native distribution. This uses \fIrpm\fR for Linux, +\fIinst\fR for IRIX, \fIpkg\fR for Solaris, \fIswinstall\fR for +HP-UX, \fIbsd\fR for FreeBSD, NetBSD, and OpenBSD, and \fIosx\fR +for MacOS X. All other operating systems default to the +\fIportable\fR format. +.TP 5 +osx +.br +Generate a MacOS X software package. +.TP 5 +pkg +.br +Generate an AT&T software package. These are used primarily under Solaris. +.TP 5 +portable +.br +Generate a portable distribution based on shell scripts and tar files. The +resulting distribution is installed and removed the same way on all +operating systems. [default] +.TP 5 +rpm, rpm-signed +.br +Generate a Red Hat Package Manager ("RPM") distribution suitable +for installation on a Red Hat Linux system. The rpm-signed format uses +the GPG private key you have defined in the ~/.rpmmacros file. +.TP 5 +setld +.br +Generate a Tru64 (setld) software distribution. +.TP 5 +slackware +.br +Generate a Slackware Linux software distribution. +.TP 5 +swinstall, depot +.br +Generate a HP-UX software distribution. +.LP +Executable files in the distribution are normally stripped of debugging +information when packaged. To disable this functionality use the +\fI\-g\fR option. +.LP +Intermediate (spec, etc.) files used to create the distribution are normally +removed after the distribution is created. The \fI\-k\fR option keeps these +files in the distribution directory. +.LP +The \fI-s\fR and \fI--setup-image\fR options ("setup") include +the ESP Software Wizard with the specified GIF or XPM image file with +the distribution. This option is currently only supported by +portable and RPM distributions. +.LP +The \fI--setup-program\fR option specifies the setup executable +to use with the distribution. This option is currently only +supported by portable distributions. +.LP +The \fI--setup-types\fR option specifies the \fIsetup.types\fR +file to include with the distribution. This option is currently +only supported by portable distributions. +.LP +The \fI--output-dir\fR option specifies the directory to +place output file into. The default directory is based on the +operating system, version, and architecture. +.LP +The \fI-v\fR option ("verbose") increases the amount of information that is +reported. Use multiple v's for more verbose output. +.LP +The \fI--depend\fR option lists the dependent (source) files for +all files in the package. +.LP +Distributions normally are named +"product-version-system-release-machine.ext" and +"product-version-system-release-machine-patch.ext" (for patch +distributions.) The "system-release-machine" information can be +customized or eliminated using the \fI-n\fR option with the +appropriate trailing letters. Using \fI-n\fR by itself will +remove the "system-release-machine" string from the filename +entirely. The "system-release-machine" information can also be +customized by using the \fI-m\fR option with an arbitrary string. +.LP +Debian, IRIX, portable, and Red Hat distributions use the extensions ".deb", +".tardist", "tar.gz", and ".rpm" respectively. +.SH LIST FILES +The EPM list file format is now described in the \fIepm.list(5)\fR +man page. +.SH KNOWN BUGS +EPM does not currently support generation of IRIX software patches. +.SH SEE ALSO +epminstall(1) - add a directory, file, or symlink to a list file +.br +mkepmlist(1) - make an epm list file from a directory +.br +epm.list(5) - epm list file format +.br +setup(1) - graphical setup program for the esp package manager +.SH COPYRIGHT +Copyright 1999-2008 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: epm.man 816 2008-08-27 03:44:15Z mike $". +.\" diff --git a/doc/epminstall.man b/doc/epminstall.man new file mode 100644 index 0000000..b6b672d --- /dev/null +++ b/doc/epminstall.man @@ -0,0 +1,97 @@ +.\" +.\" "$Id: epminstall.man 753 2007-04-10 18:34:01Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM) install program. +.\" +.\" Copyright 1999-2007 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH epminstall 1 "ESP Package Manager" "3 April 2006" "Easy Software Products" +.SH NAME +epminstall \- add a directory, file, or symlink to a list file. +.SH SYNOPSIS +.B epminstall +.I options +file1 file2 ... fileN directory +.br +.B epminstall +.I options +file1 file2 +.br +.B epminstall +.I options +-d directory1 directory2 ... directoryN +.SH DESCRIPTION +\fBepminstall\fR adds or replaces a directory, file, or symlink +in a list file. The default list file is "epm.list" and can be +overridden using the \fIEPMLIST\fR environment variable or the +\fI--list-file\fR option. +.LP +Entries are either added to the end of the list file or replaced +in-line. Comments, directives, and variable declarations in the +list file are preserved. +.SH OPTIONS +\fBepminstall\fR recognizes the standard Berkeley \fIinstall\fR command +options: +.TP 5 +\-b +.br +Make a backup of existing files (ignored, default for EPM.) +.TP 5 +\-c +.br +BSD old compatibility mode (ignored.) +.TP 5 +\-g \fIgroup\fR +.br +Set the group owner of the file or directory to \fIgroup\fR. The default +group is "sys". +.TP 5 +\-m \fImode\fR +.br +Set the permissions of the file or directory to \fImode\fR. The default +permissions are 0755 for directories and executable files and +0644 for non-executable files. +.TP 5 +\-o \fIowner\fR +.br +Set the owner of the file or directory to \fIowner\fR. The default +owner is "root". +.TP 5 +\-s +.br +Strip the files (ignored, default for EPM.) +.TP 5 +\--list-file \fIfilename.list\fR +.br +Specify the list file to update. +.SH SEE ALSO +epm(1) - create software packages +.br +mkepmlist(1) - make an epm list file from a directory +.br +epm.list(5) - epm list file format +.SH COPYRIGHT +Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: epminstall.man 753 2007-04-10 18:34:01Z mike $". +.\" diff --git a/doc/epmlogo.gif b/doc/epmlogo.gif Binary files differnew file mode 100644 index 0000000..2f61877 --- /dev/null +++ b/doc/epmlogo.gif diff --git a/doc/epmlogo.tif b/doc/epmlogo.tif Binary files differnew file mode 100644 index 0000000..4280772 --- /dev/null +++ b/doc/epmlogo.tif diff --git a/doc/gradient.gif b/doc/gradient.gif Binary files differnew file mode 100644 index 0000000..02abf16 --- /dev/null +++ b/doc/gradient.gif diff --git a/doc/mantohtml.c b/doc/mantohtml.c new file mode 100644 index 0000000..eae1994 --- /dev/null +++ b/doc/mantohtml.c @@ -0,0 +1,697 @@ +/* + * "$Id: mantohtml.c 667 2006-04-05 03:16:04Z mike $" + * + * Man page to HTML conversion program. + * + * Copyright 2004-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Convert a man page to HTML. + * putc_entity() - Put a single character, using entities as needed. + * strmove() - Move characters within a string. + */ + +/* + * Include necessary headers. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + + +/* + * Local functions... + */ + +static void putc_entity(int ch, FILE *fp); +static void strmove(char *d, const char *s); + + +/* + * 'main()' - Convert a man page to HTML. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *infile, /* Input file */ + *outfile; /* Output file */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + *endptr, /* Pointer to end of current */ + endchar, /* End character */ + *paren, /* Pointer to parenthesis */ + name[1024]; /* Man page name */ + int section, /* Man page section */ + pre, /* Preformatted */ + font, /* Current font */ + blist, /* In a bullet list? */ + list, /* In a list? */ + linenum; /* Current line number */ + const char *post; /* Text to add after the current line */ + static const char /* Start/end tags for fonts */ + * const start_fonts[] = { "", "<b>", "<i>" }, + * const end_fonts[] = { "", "</b>", "</i>" }; + + /* + * Check arguments... + */ + + if (argc > 3) + { + fputs("Usage: mantohtml [filename.man [filename.html]]\n", stderr); + return (1); + } + + /* + * Open files as needed... + */ + + if (argc > 1) + { + if ((infile = fopen(argv[1], "r")) == NULL) + { + perror(argv[1]); + return (1); + } + } + else + infile = stdin; + + if (argc > 2) + { + if ((outfile = fopen(argv[2], "w")) == NULL) + { + perror(argv[2]); + fclose(infile); + return (1); + } + } + else + outfile = stdout; + + /* + * Read from input and write the output... + */ + + fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" " + "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" + "<html>\n" + "<!-- SECTION: Man Pages -->\n" + "<head>\n" + "\t<style type='text/css'><!--\n" + "\th1, h2, h3, p { font-family: sans-serif; text-align: justify; }\n" + "\ttt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }\n" + "\tpre { font-weight: bold; color: #7f0000; margin-left: 2em; }\n" + "\th1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }\n" + "\t--></style>\n", outfile); + + blist = 0; + font = 0; + list = 0; + linenum = 0; + pre = 0; + post = NULL; + section = -1; + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (line[0] == '.') + { + /* + * Strip leading whitespace... + */ + + while (line[1] == ' ' || line[1] == '\t') + strmove(line + 1, line + 2); + + /* + * Process man page commands... + */ + + if (!strncmp(line, ".TH ", 4) && section < 0) + { + /* + * Grab man page title... + */ + + sscanf(line + 4, "%s%d", name, §ion); + + fprintf(outfile, + "\t<title>%s(%d)</title>\n" + "</head>\n" + "<body>\n" + "<h2>%s(%d)</h2>\n" + "%s", + name, section, name, section, start_fonts[font]); + } + else if (section < 0) + continue; + else if (!strncmp(line, ".SH ", 4) || !strncmp(line, ".Sh ", 4)) + { + /* + * Grab heading... + */ + + int first = 1; + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("</li>\n</ul>\n", outfile); + blist = 0; + } + + if (list) + { + if (list == 1) + fputs("</dt>\n", outfile); + else if (list) + fputs("</dd>\n", outfile); + + fputs("</dl>\n", outfile); + list = 0; + } + + line[strlen(line) - 1] = '\0'; /* Strip LF */ + + if (line[2] == 'H') + fputs("<h3><a name='", outfile); + else + fputs("<h4><a name='", outfile); + + for (lineptr = line + 4; *lineptr; lineptr ++) + if (*lineptr == '\"') + continue; + else if (*lineptr == ' ') + putc_entity('_', outfile); + else + putc_entity(*lineptr, outfile); + + fputs("'>", outfile); + + for (lineptr = line + 4; *lineptr; lineptr ++) + if (*lineptr == '\"') + continue; + else if (*lineptr == ' ') + { + putc_entity(' ', outfile); + + first = 1; + } + else + { + if (first) + putc_entity(*lineptr, outfile); + else + putc_entity(tolower(*lineptr), outfile); + + first = 0; + } + + if (line[2] == 'H') + fprintf(outfile, "</a></h3>\n%s", start_fonts[font]); + else + fprintf(outfile, "</a></h4>\n%s", start_fonts[font]); + } + else if (!strncmp(line, ".LP", 3) || !strncmp(line, ".PP", 3)) + { + /* + * New paragraph... + */ + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("</li>\n</ul>\n", outfile); + blist = 0; + } + + if (list) + { + if (list == 1) + fputs("</dt>\n", outfile); + else if (list) + fputs("</dd>\n", outfile); + + fputs("</dl>\n", outfile); + list = 0; + } + + fputs("<p>", outfile); + font = 0; + } + else if (!strncmp(line, ".TP ", 4)) + { + /* + * Grab list... + */ + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("</li>\n</ul>\n", outfile); + blist = 0; + } + + if (!list) + fputs("<dl>\n", outfile); + else if (list == 1) + fputs("</dt>\n", outfile); + else if (list) + fputs("</dd>\n", outfile); + + fputs("<!-- NEED 3 --><dt>", outfile); + list = 1; + font = 0; + } + else if (!strncmp(line, ".br", 3)) + { + /* + * Grab line break... + */ + + if (list == 1) + { + fputs("</dt>\n<dd>", outfile); + list = 2; + } + else if (list) + fputs("</dd>\n<dd>", outfile); + else if (!pre) + fputs("<br>\n", outfile); + } + else if (!strncmp(line, ".de ", 4)) + { + /* + * Define macro - ignore... + */ + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (!strncmp(line, "..", 2)) + break; + } + } + else if (!strncmp(line, ".RS", 3)) + { + /* + * Indent... + */ + + fputs("<div style='margin-left: 3em;'>\n", outfile); + } + else if (!strncmp(line, ".RE", 3)) + { + /* + * Unindent... + */ + + fputs("</div>\n", outfile); + } + else if (!strncmp(line, ".ds ", 4) || !strncmp(line, ".rm ", 4) || + !strncmp(line, ".tr ", 4) || !strncmp(line, ".hy ", 4) || + !strncmp(line, ".IX ", 4) || !strncmp(line, ".PD", 3) || + !strncmp(line, ".Sp", 3)) + { + /* + * Ignore unused commands... + */ + } + else if (!strncmp(line, ".Vb", 3) || !strncmp(line, ".nf", 3)) + { + /* + * Start preformatted... + */ + + pre = 1; + fputs("<pre>\n", outfile); + } + else if (!strncmp(line, ".Ve", 3) || !strncmp(line, ".fi", 3)) + { + /* + * End preformatted... + */ + + if (pre) + { + pre = 0; + fputs("</pre>\n", outfile); + } + } + else if (!strncmp(line, ".IP \\(bu", 8)) + { + /* + * Bullet list... + */ + + if (blist) + fputs("</li>\n", outfile); + else + { + fputs("<ul>\n", outfile); + blist = 1; + } + + fputs("<li>", outfile); + } + else if (!strncmp(line, ".IP ", 4)) + { + /* + * Indented paragraph... + */ + + if (blist) + { + fputs("</li>\n</ul>\n", outfile); + blist = 0; + } + + fputs("<p style='margin-left: 3em;'>", outfile); + + for (lineptr = line + 4; isspace(*lineptr); lineptr ++); + + if (*lineptr == '\"') + { + strmove(line, lineptr + 1); + + if ((lineptr = strchr(line, '\"')) != NULL) + *lineptr = '\0'; + } + else + { + strmove(line, lineptr); + + if ((lineptr = strchr(line, ' ')) != NULL) + *lineptr = '\0'; + } + + /* + * Process the text as if it was in-line... + */ + + post = "\n<br />\n<br />"; + goto process_text; + } + else if (!strncmp(line, ".\\}", 3)) + { + /* + * Ignore close block... + */ + } + else if (!strncmp(line, ".ie", 3) || !strncmp(line, ".if", 3) || + !strncmp(line, ".el", 3)) + { + /* + * If/else - ignore... + */ + + if (strchr(line, '{') != NULL) + { + /* + * Skip whole block... + */ + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (strchr(line, '}') != NULL) + break; + } + } + } +#if 0 + else if (!strncmp(line, ". ", 4)) + { + /* + * Grab ... + */ + } +#endif /* 0 */ + else if (!strncmp(line, ".B ", 3)) + { + /* + * Grab bold text... + */ + + fprintf(outfile, "%s<b>%s</b>%s", end_fonts[font], line + 3, + start_fonts[font]); + } + else if (!strncmp(line, ".I ", 3)) + { + /* + * Grab italic text... + */ + + fprintf(outfile, "%s<i>%s</i>%s", end_fonts[font], line + 3, + start_fonts[font]); + } + else if (strncmp(line, ".\\\"", 3)) + { + /* + * Unknown... + */ + + if ((lineptr = strchr(line, ' ')) != NULL) + *lineptr = '\0'; + else if ((lineptr = strchr(line, '\n')) != NULL) + *lineptr = '\0'; + + fprintf(stderr, "mantohtml: Unknown man page command \'%s\' on line %d!\n", + line, linenum); + } + + /* + * Skip continuation lines... + */ + + lineptr = line + strlen(line) - 2; + if (lineptr >= line && *lineptr == '\\') + { + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + lineptr = line + strlen(line) - 2; + + if (lineptr < line || *lineptr != '\\') + break; + } + } + } + else + { + /* + * Process man page text... + */ + +process_text: + + for (lineptr = line; *lineptr; lineptr ++) + { + if (!strncmp(lineptr, "http://", 7)) + { + /* + * Embed URL... + */ + + for (endptr = lineptr + 7; + *endptr && !isspace(*endptr & 255); + endptr ++); + + endchar = *endptr; + *endptr = '\0'; + + fprintf(outfile, "<a href='%s'>%s</a>", lineptr, lineptr); + *endptr = endchar; + lineptr = endptr - 1; + } + else if (!strncmp(lineptr, "\\fI", 3) && + (endptr = strstr(lineptr, "\\fR")) != NULL && + (paren = strchr(lineptr, '(')) != NULL && + paren < endptr) + { + /* + * Man page... + */ + + lineptr += 3; + endchar = *endptr; + *endptr = '\0'; + + fputs("<i>", outfile); + while (*lineptr) + putc_entity(*lineptr++, outfile); + fputs("</i>", outfile); + + *endptr = endchar; + lineptr = endptr + 2; + } + else if (*lineptr == '\\') + { + lineptr ++; + if (!*lineptr) + break; + else if (isdigit(lineptr[0]) && isdigit(lineptr[1]) && + isdigit(lineptr[2])) + { + fprintf(outfile, "&#%d;", ((lineptr[0] - '0') * 8 + + lineptr[1] - '0') * 8 + + lineptr[2] - '0'); + lineptr += 2; + } + else if (*lineptr == '&') + continue; + else if (*lineptr == 's') + { + while (lineptr[1] == '-' || isdigit(lineptr[1])) + lineptr ++; + } + else if (*lineptr == '*') + { + lineptr += 2; + } + else if (*lineptr != 'f') + putc_entity(*lineptr, outfile); + else + { + lineptr ++; + if (!*lineptr) + break; + else + { + fputs(end_fonts[font], outfile); + + switch (*lineptr) + { + default : /* Regular */ + font = 0; + break; + case 'B' : /* Bold */ + case 'b' : + font = 1; + break; + case 'I' : /* Italic */ + case 'i' : + font = 2; + break; + } + + fputs(start_fonts[font], outfile); + } + } + } + else + putc_entity(*lineptr, outfile); + } + + if (post) + { + fputs(post, outfile); + post = NULL; + } + } + } + + fprintf(outfile, "%s\n", end_fonts[font]); + + if (blist) + { + fputs("</li>\n</ul>\n", outfile); + blist = 0; + } + + if (list) + { + if (list == 1) + fputs("</dt>\n", outfile); + else if (list) + fputs("</dd>\n", outfile); + + fputs("</dl>\n", outfile); + list = 0; + } + + fputs("</body>\n" + "</html>\n", outfile); + + /* + * Close files... + */ + + if (infile != stdin) + fclose(infile); + + if (outfile != stdout) + fclose(outfile); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'putc_entity()' - Put a single character, using entities as needed. + */ + +static void +putc_entity(int ch, /* I - Character */ + FILE *fp) /* I - File */ +{ + if (ch == '&') + fputs("&", fp); + else if (ch == '<') + fputs("<", fp); + else + putc(ch, fp); +} + + +/* + * 'strmove()' - Move characters within a string. + */ + +static void +strmove(char *d, /* I - Destination */ + const char *s) /* I - Source */ +{ + while (*s) + *d++ = *s++; + + *d = '\0'; +} + + +/* + * End of "$Id: mantohtml.c 667 2006-04-05 03:16:04Z mike $". + */ diff --git a/doc/mkepmlist.man b/doc/mkepmlist.man new file mode 100644 index 0000000..5c8ba54 --- /dev/null +++ b/doc/mkepmlist.man @@ -0,0 +1,74 @@ +.\" +.\" "$Id: mkepmlist.man 753 2007-04-10 18:34:01Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM). +.\" +.\" Copyright 1999-2007 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH mkepmlist 1 "ESP Package Manager" "3 April 2006" "Easy Software Products" +.SH NAME +mkepmlist \- make an epm list file from a directory. +.SH SYNOPSIS +.B mkepmlist +[ \-g +.I group +] [ \-u +.I user +] [ \--prefix +.I directory +] +.I directory +[ ... +.I directory +] +.SH DESCRIPTION +\fBmkepmlist\fR recursively generates file list entries for +files, links, and directories. The file list is send to the +standard output. +.LP +The \fI-g\fR option overrides the group ownership of the files in +the specified directories with the specified group name. +.LP +The \fI-u\fR option overrides the user ownership of the files in +the specified directories with the specified user name. +.LP +The \fI--prefix\fR option adds the specified directory to the +destination path. For example, if you installed files to +"/opt/foo" and wanted to build a distribution that installed the +files in "/usr/local", the following command would generate a file +list that is installed in "/usr/local": +.nf +.br + mkepmlist --prefix=/usr/local /opt/foo >foo.list +.fi +.SH SEE ALSO +epm(1) - create software packages +.br +epminstall(1) - add a directory, file, or symlink to a list file +.br +epm.list(5) - epm list file format +.SH COPYRIGHT +Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: mkepmlist.man 753 2007-04-10 18:34:01Z mike $". +.\" diff --git a/doc/preface.html b/doc/preface.html new file mode 100644 index 0000000..60c8e8b --- /dev/null +++ b/doc/preface.html @@ -0,0 +1,214 @@ +<HTML> +<HEAD> + <TITLE>Software Distribution Using the ESP Package Manager</TITLE> + <META NAME="Author" content="Michael Sweet"> + <META NAME="Copyright" CONTENT="Copyright 1999-2010 by Easy Software Products"> + <META NAME="DocNumber" CONTENT="ESP-004-20101231"> +</HEAD> +<BODY> + +<H1 ALIGN="RIGHT">Preface</H1> + +<P>This book provides a tutorial and reference for the ESP Package Manager ("EPM") software, version 4.2, and is organized into the following chapters and appendices:</P> + +<UL> + + <LI><A HREF="#INTRO">1 - Introduction to EPM</A></LI> + + <LI><A HREF="#BUILDING">2 - Building EPM</A></LI> + + <LI><A HREF="#PACKAGING">3 - Packaging Your Software with EPM</A></LI> + + <LI><A HREF="#ADVANCED">4 - Advanced Packaging with EPM</A></LI> + + <LI><A HREF="#EXAMPLES">5 - EPM Packaging Examples</A></LI> + + <LI><A HREF="#LICENSE">A - Software License Agreement</A></LI> + + <LI><A HREF="#MANPAGES">B - Command Reference</A></LI> + + <LI><A HREF="#REFERENCE">C - List File Reference</A></LI> + + <LI><A HREF="#RELNOTES">D - Release Notes</A></LI> + +</UL> + +<!-- NEED 6in --> +<H2>Notation Conventions</H2> + +<DL> + + <DT>The names of commands; the first mention of a command or function in a + chapter is followed by a manual page section number: + <BR> </DT> + + <DD><CODE>epm</CODE><BR> + <CODE>epm(1)</CODE> + <BR> </DD> + + <DT>File and directory names: + <BR> </DT> + + <DD><VAR>/var</VAR><BR> + <VAR>/usr/bin/epm</VAR> + <BR> </DD> + + <DT>Screen output: + <BR> </DT> + + <DD><TT>Request ID is Printer-123</TT> + <BR> </DD> + + <DT>Literal user input; special keys like <KBD>ENTER</KBD> are in ALL CAPS: + <BR> </DT> + + <DD><KBD>lp -d printer filename ENTER</KBD> + <BR> </DD> + + <DT>Long commands are broken up on multiple lines using the backslash (\) + character; enter the commands without the backslash: + <BR> </DT> + + <DD><KBD>foo start of long command \<BR> + end of long command ENTER</KBD> + <BR> </DD> + + <DT>Numbers in the text are written using the period (.) to indicate the + decimal point: + <BR> </DT> + + <DD>12.3 + <BR> </DD> + +</DL> + +<!-- NEED 3in --> +<H2>Abbreviations</H2> + +<P>The following abbreviations are used throughout this book:</P> + +<DL> + + <DD>kb</DD> + + <DD>Kilobytes, or 1024 bytes + <BR> </DD> + + <DD>Mb</DD> + + <DD>Megabytes, or 1048576 bytes + <BR> </DD> + + <DD>Gb</DD> + + <DD>Gigabytes, or 1073741824 bytes + <BR> </DD> + +</DL> + +<!-- NEED 4in --> +<H2>Other References</H2> + +<DL> + + <DT><A + HREF="http://www.epmhome.org/">http://www.epmhome.org/</A></DT> + + <DD>The official home page of the ESP Package Manager software. + <BR> </DD> + + <DT><A + HREF="http://www.debian.org/devel/">http://www.debian.org/devel/</A></DT> + + <DD>Debian Developers' Corner + <BR> </DD> + + <DT><A HREF="http://techpubs.sgi.com/">http://techpubs.sgi.com/</A></DT> + + <DD>IRIX Documentation On-Line + <BR> </DD> + + <DT><A HREF="http://www.rpm.org/">http://www.rpm.org/</A></DT> + + <DD>The Red Hat Package Manager home page. + <BR> </DD> + + <DT><A HREF="http://docs.sun.com/">http://docs.sun.com/</A></DT> + + <DD>Solaris Documentation On-Line + <BR> </DD> + +</DL> + +<H2>Help Us Improve This Book!</H2> + +<P>We've done our best to ensure that this book is both accurate +and clear. If you find errors or have a suggestion for improving +the book, please send us an email to "<A +HREF="mailto:epm-book@easysw.com">epm-book@easysw.com</A>".</P> + +<H2>Acknowledgments</H2> + +<P>We'd like to thank the following people for their +contributions to EPM:</P> + +<UL> + + <LI>Gareth Armstrong: HP-UX and %release enhancements</LI> + + <LI>Nicolas Bazin: Openserver and Unixware support</LI> + + <LI>Richard Begg: HP-UX fixes</LI> + + <LI>Dirk Datzert: Bug fixes</LI> + + <LI>Alan Eldridge: Makefile and RPM fixes</LI> + + <LI>Vicentini Emanuele: IRIX enhancements</LI> + + <LI>Jeff Harrell: IRIX enhancements</LI> + + <LI>Lars Kellogg-Stedman: Debian fixes</LI> + + <LI>Jochen Kmietsch: mkepmlist fixes</LI> + + <LI>Aneesh Kumar K.V.: Tru64 setld package support</LI> + + <LI>David Lee: Build system improvements</LI> + + <LI>Scott Leerssen: mkepmlist fixes, BSD package support</LI> + + <LI>Jeff Licquia: Debian support/enhancements</LI> + + <LI>David Maltz: AIX fixes</LI> + + <LI>Joel Nordell: SCO fixes</LI> + + <LI>Rok Papez: Bug fixes and absolute output directory support</LI> + + <LI>Holger Paschke: Documentation fixes</LI> + + <LI>Phil Reynolds: OpenBSD fixes</LI> + + <LI>Ganesan Rajagopal: Solaris fixes</LI> + + <LI>Uwe Räsche: AIX support</LI> + + <LI>Ralf Rohm: Solaris fixes</LI> + + <LI>Jochen Schaeuble: epminstall fixes</LI> + + <LI>Jason Shiffer: HP-UX fixes</LI> + + <LI>Andrea Suatoni: IRIX fixes</LI> + + <LI>Andy Walter: QNX support</LI> + + <LI>Geoffrey Wossum: --output-directory option</LI> + + <LI>Jean Yves: BSD package and mkepmlist fixes</LI> + +</UL> + +</BODY> +</HTML> diff --git a/doc/setup.man b/doc/setup.man new file mode 100644 index 0000000..7ce7714 --- /dev/null +++ b/doc/setup.man @@ -0,0 +1,59 @@ +.\" +.\" "$Id: setup.man 753 2007-04-10 18:34:01Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM) setup GUI. +.\" +.\" Copyright 1999-2007 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH setup 1 "ESP Package Manager" "3 April 2006" "Easy Software Products" +.SH NAME +setup \- graphical setup program for the esp package manager +.SH SYNOPSIS +.B setup +[ +.I directory +] +.SH DESCRIPTION +\fBsetup\fR provides a graphical installation interface for +EPM-generated portable installation packages. It presents a +step-by-step dialog for collecting a list of packages to install +and accepting any license agreements for those packages. +.LP +\fBsetup\fR searches for products in the current directory or the +directory specified on the command-line. +.SH INSTALLATION TYPES +The default type of installation is "custom". That is, users will be +able to select from the list of products and install them. +.LP +\fBsetup\fR also supports other types of installations. The +\fIsetup.types\fR file, if present, defines the other +installation types. +.SH SEE ALSO +epm(1) - create software packages. +.br +setup.types(5) - epm gui setup types file format. +.SH COPYRIGHT +Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: setup.man 753 2007-04-10 18:34:01Z mike $". +.\" diff --git a/doc/setup.png b/doc/setup.png Binary files differnew file mode 100644 index 0000000..c4c3cbf --- /dev/null +++ b/doc/setup.png diff --git a/doc/setup.types.man b/doc/setup.types.man new file mode 100644 index 0000000..eef8db1 --- /dev/null +++ b/doc/setup.types.man @@ -0,0 +1,75 @@ +.\" +.\" "$Id: setup.types.man 753 2007-04-10 18:34:01Z mike $" +.\" +.\" Manual page for the ESP Package Manager (EPM) setup types file format. +.\" +.\" Copyright 1999-2007 by Easy Software Products, all rights reserved. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.TH setup.types 5 "ESP Package Manager" "3 April 2006" "Easy Software Products" +.SH NAME +setup.types \- epm gui setup types file format. +.SH DESCRIPTION +The EPM \fBsetup\fR program normally presents the user with a +list of software products to install, which is called a "custom" +software installation. +.LP +If a file called \fIsetup.types\fR is present in the package +directory, the user will instead be presented with a list of +installation types. Each type has an associated product list +which determines the products that are installed by default. If a +type has no products associated with it, then it is treated as a +custom installation and the user is presented with a list of +packages to choose from. +.SH FILE FORMAT +The \fIsetup.types\fR file is an ASCII text file consisting of +type and product lines. Comments can be inserted by starting a +line with the pound sign (#). Each installation type is defined +by a line starting with the word TYPE. Products are defined by a +line starting with the word INSTALL: +.in 5 +.nf + +TYPE Typical End-User Configuration +INSTALL foo +INSTALL foo-help +TYPE Typical Developer Configuration +INSTALL foo +INSTALL foo-help +INSTALL foo-devel +INSTALL foo-examples +TYPE Custom Configuration +.fi +.in +.LP +In the example above, three installation types are defined. Since the last +type includes no products, the user will be presented with the full list +of products to choose from. +.SH SEE ALSO +epm(1) - create software packages +.br +setup(1) - graphical setup program for the esp package manager +.SH COPYRIGHT +Copyright 1999-2007 by Easy Software Products, All Rights Reserved. +.LP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. +.LP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.\" +.\" End of "$Id: setup.types.man 753 2007-04-10 18:34:01Z mike $". +.\" diff --git a/doc/title.html b/doc/title.html new file mode 100644 index 0000000..38c03e3 --- /dev/null +++ b/doc/title.html @@ -0,0 +1,76 @@ +<HTML> +<BODY> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<H1 ALIGN="CENTER">Software Distribution Using the ESP Package +Manager</H1> + +<P ALIGN="CENTER">MICHAEL R. SWEET</P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> </P> + +<P> <IMG SRC="gradient.gif"><BR> +<VAR>ESP Press</VAR><BR> +<SMALL>Easy Software Products, 516 Rio Grand Ct, Morgan Hill, CA 95037 USA</SMALL></P> + +<!-- NEW PAGE --> +<H2>Software Distribution Using the ESP Package Manager</H2> + +<H3>Copyright © 2006-2010 by Easy Software Products</H3> + +<P><SMALL>This book may be redistributed and/or modified under +the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation.</SMALL></P> + +<P><SMALL>This book is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details.</SMALL></P> + +<P><SMALL>You should have received a copy of the GNU General +Public License along with this program; if not, write to the Free +Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA.</SMALL></P> + +<P><SMALL>This book was created solely using free software +tools.</SMALL></P> + +<P><SMALL>International Standard Book Number: +978-1-4116-8913-8</SMALL></P> + +<P><SMALL>First Printing: April 2006<BR> +Second Printing: December 2010</SMALL></P> + +</BODY> +</HTML> @@ -0,0 +1,727 @@ +/* + * "$Id: epm.c 819 2009-02-02 23:24:33Z mike $" + * + * Main program source for the ESP Package Manager (EPM). + * + * Copyright 1999-2008 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * main() - Read a product list and produce a distribution. + * depend() - Show dependencies. + * info() - Show the EPM copyright and license. + * usage() - Show command-line usage instructions. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Globals... + */ + +int CompressFiles = EPM_COMPRESS; +const char *DataDir = EPM_DATADIR; +int KeepFiles = 0; +const char *SetupProgram = EPM_LIBDIR "/setup"; +const char *SoftwareDir = EPM_SOFTWARE; +const char *UninstProgram = EPM_LIBDIR "/uninst"; +int Verbosity = 0; + + +/* + * Local functions... + */ + +static void depend(dist_t *dist); +static void info(void); +static void usage(void); + + +/* + * 'main()' - Read a product list and produce a distribution. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int strip; /* 1 if we should strip executables */ + struct utsname platform; /* UNIX name info */ + char *namefmt, /* Name format to use */ + *custom_name, /* User-supplied system name */ + platname[255], /* Base platform name */ + prodname[256], /* Product name */ + listname[256], /* List file name */ + directory[255], /* Name of install directory */ + *temp, /* Temporary string pointer */ + *setup, /* Setup GUI image */ + *types; /* Setup GUI install types */ + dist_t *dist; /* Software distribution */ + int format; /* Distribution format */ + int show_depend; /* Show dependencies */ + static char *formats[] = /* Distribution format strings */ + { + "portable", + "aix", + "bsd", + "deb", + "inst", + "osx", + "pkg", + "rpm", + "setld", + "slackware", + "swinstall" + }; + + + /* + * Get platform information... + */ + + get_platform(&platform); + + /* + * Check arguments... + */ + + if (argc < 2) + { + puts("epm: Too few arguments!"); + usage(); + } + + strip = 1; + format = PACKAGE_PORTABLE; + setup = NULL; + types = NULL; + namefmt = "srm"; + custom_name = 0; + prodname[0] = '\0'; + listname[0] = '\0'; + directory[0] = '\0'; + show_depend = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + /* + * Process a command-line option... + */ + + switch (argv[i][1]) + { + case 'a' : /* Architecture */ + if (argv[i][2]) + temp = argv[i] + 2; + else + { + i ++; + if (i >= argc) + { + puts("epm: Expected architecture name."); + usage(); + } + + temp = argv[i]; + } + + strlcpy(platform.machine, temp, sizeof(platform.machine)); + break; + + case 'f' : /* Format */ + if (argv[i][2]) + temp = argv[i] + 2; + else + { + i ++; + if (i >= argc) + { + puts("epm: Expected format name."); + usage(); + } + + temp = argv[i]; + } + + if (!strcasecmp(temp, "portable")) + format = PACKAGE_PORTABLE; + else if (!strcasecmp(temp, "aix")) + format = PACKAGE_AIX; + else if (!strcasecmp(temp, "bsd")) + format = PACKAGE_BSD; + else if (!strcasecmp(temp, "deb")) + format = PACKAGE_DEB; + else if (!strcasecmp(temp, "inst") || + !strcasecmp(temp, "tardist")) + format = PACKAGE_INST; + else if (!strcasecmp(temp, "lsb")) + format = PACKAGE_LSB; + else if (!strcasecmp(temp, "lsb-signed")) + format = PACKAGE_LSB_SIGNED; + else if (!strcasecmp(temp, "osx")) + format = PACKAGE_OSX; + else if (!strcasecmp(temp, "pkg")) + format = PACKAGE_PKG; + else if (!strcasecmp(temp, "rpm")) + format = PACKAGE_RPM; + else if (!strcasecmp(temp, "rpm-signed")) + format = PACKAGE_RPM_SIGNED; + else if (!strcasecmp(temp, "setld")) + format = PACKAGE_SETLD; + else if (!strcasecmp(temp, "slackware")) + format = PACKAGE_SLACKWARE; + else if (!strcasecmp(temp, "swinstall") || + !strcasecmp(temp, "depot")) + format = PACKAGE_SWINSTALL; + else if (!strcasecmp(temp, "native")) +#if defined(__linux) + { + /* + * Use dpkg as the native format, if installed... + */ + + if (access("/usr/bin/dpkg", 0)) + format = PACKAGE_RPM; + else + format = PACKAGE_DEB; + } +#elif defined(__sgi) + format = PACKAGE_INST; +#elif defined(__osf__) + format = PACKAGE_SETLD; +#elif defined(__hpux) + format = PACKAGE_SWINSTALL; +#elif defined(_AIX) + format = PACKAGE_AIX; +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + format = PACKAGE_BSD; +#elif defined(__svr4__) || defined(__SVR4) || defined(M_XENIX) + format = PACKAGE_PKG; +#elif defined(__APPLE__) + format = PACKAGE_OSX; +#else + format = PACKAGE_PORTABLE; +#endif + else + { + printf("epm: Unknown format \"%s\".\n", temp); + usage(); + } + break; + + case 'g' : /* Don't strip */ + strip = 0; + break; + + case 'k' : /* Keep intermediate files */ + KeepFiles = 1; + break; + + case 'm' : /* Custom sysname-release-machine string */ + if (argv[i][2]) + custom_name = argv[i] + 2; + else + { + i ++; + if (i >= argc) + { + puts("epm: Expected custom system name string."); + usage(); + } + + custom_name = argv[i]; + } + break; + + case 'n' : /* Name with sysname, machine, and/or release */ + namefmt = argv[i] + 2; + break; + + case 's' : /* Use setup GUI */ + if (argv[i][2]) + setup = argv[i] + 2; + else + { + i ++; + if (i >= argc) + { + puts("epm: Expected setup image."); + usage(); + } + + setup = argv[i]; + } + break; + + case 't' : /* Test scripts */ + fputs("epm: Sorry, the \"test\" option is no longer available!\n", + stderr); + break; + + case 'u' : /* Uncompressed output */ + CompressFiles = 0; + break; + + case 'v' : /* Be verbose */ + Verbosity += strlen(argv[i]) - 1; + break; + + case 'z' : /* Compress output */ + CompressFiles = 1; + break; + + case '-' : /* --option */ + if (!strcmp(argv[i], "--data-dir")) + { + i ++; + if (i < argc) + DataDir = argv[i]; + else + { + puts("epm: Expected data directory."); + usage(); + } + } + else if (!strcmp(argv[i], "--depend")) + show_depend = 1; + else if (!strcmp(argv[i], "--keep-files")) + KeepFiles = 1; + else if (!strcmp(argv[i], "--output-dir")) + { + i ++; + if (i < argc) + strlcpy(directory, argv[i], sizeof(directory)); + else + { + puts("epm: Expected output directory."); + usage(); + } + } + else if (!strcmp(argv[i], "--setup-image")) + { + i ++; + if (i < argc) + setup = argv[i]; + else + { + puts("epm: Expected setup image."); + usage(); + } + } + else if (!strcmp(argv[i], "--setup-program")) + { + i ++; + if (i < argc) + SetupProgram = argv[i]; + else + { + puts("epm: Expected setup program."); + usage(); + } + } + else if (!strcmp(argv[i], "--setup-types")) + { + i ++; + if (i < argc) + types = argv[i]; + else + { + puts("epm: Expected setup.types file."); + usage(); + } + } + else if (!strcmp(argv[i], "--software-dir")) + { + i ++; + if (i < argc) + SoftwareDir = argv[i]; + else + { + puts("epm: Expected software directory."); + usage(); + } + } + else if (!strcmp(argv[i], "--uninstall-program")) + { + i ++; + if (i < argc) + UninstProgram = argv[i]; + else + { + puts("epm: Expected uninstall program."); + usage(); + } + } + else if (!strcmp(argv[i], "--version")) + { + info(); + return (0); + } + else + { + printf("epm: Unknown option \"%s\".\n", argv[i]); + usage(); + } + break; + + default : + printf("epm: Unknown option \"%s\".\n", argv[i]); + usage(); + break; + } + } + else if (strchr(argv[i], '=') != NULL) + putenv(argv[i]); + else if (prodname[0] == '\0') + strcpy(prodname, argv[i]); + else if (listname[0] == '\0') + strcpy(listname, argv[i]); + else + { + printf("epm: Unknown argument \"%s\".\n", argv[i]); + usage(); + } + + /* + * Check for product name and list file... + */ + + if (!prodname[0]) + { + puts("epm: No product name specified!"); + usage(); + } + + for (i = 0; prodname[i]; i ++) + if (!isalnum(prodname[i] & 255)) + { + puts("epm: Product names should only contain letters and numbers!"); + break; + } + + if (!listname[0]) + snprintf(listname, sizeof(listname), "%s.list", prodname); + + /* + * Format the build directory and platform name strings... + */ + + if (!directory[0]) + { + /* + * User did not specify an output directory, so use our default... + */ + + if (custom_name) + sprintf(directory, "%s", custom_name); + else + snprintf(directory, sizeof(directory), "%s-%s-%s", platform.sysname, + platform.release, platform.machine); + } + + platname[0] = '\0'; + + if (custom_name) + strlcat(platname, custom_name, sizeof(platname)); + else + { + for (temp = namefmt; *temp != '\0'; temp ++) + { + if (platname[0]) + strlcat(platname, "-", sizeof(platname)); + + if (*temp == 'm') + strlcat(platname, platform.machine, sizeof(platname)); + else if (*temp == 'r') + strlcat(platname, platform.release, sizeof(platname)); + else if (*temp == 's') + strlcat(platname, platform.sysname, sizeof(platname)); + else + { + printf("epm: Bad name format character \"%c\" in \"%s\".\n", *temp, + namefmt); + usage(); + } + } + } + + /* + * Show program info... + */ + + if (Verbosity) + info(); + + /* + * Read the distribution... + */ + + if ((dist = read_dist(listname, &platform, formats[format])) == NULL) + return (1); + + /* + * Check that all requires info is present! + */ + + if (!dist->product[0] || + !dist->copyright[0] || + !dist->vendor[0] || + (!dist->license[0] && !dist->readme[0]) || + !dist->version[0]) + { + fputs("epm: Error - missing %product, %copyright, %vendor, %license,\n", stderr); + fputs(" %readme, or %version attributes in list file!\n", stderr); + + free_dist(dist); + + return (1); + } + + if (dist->num_files == 0) + { + fputs("epm: Error - no files for installation in list file!\n", stderr); + + free_dist(dist); + + return (1); + } + + /* + * Show dependencies? + */ + + if (show_depend) + { + depend(dist); + + free_dist(dist); + + return (0); + } + + /* + * Strip executables as needed... + */ + + if (strip) + { + if (Verbosity) + puts("Stripping executables in distribution..."); + + strip_execs(dist); + } + + /* + * Make build directory... + */ + + make_directory(directory, 0777, getuid(), getgid()); + + /* + * Make the distribution in the correct format... + */ + + if (access(SetupProgram, 0) && setup) + { + puts("epm: Setup program not installed, creating non-GUI package."); + setup = NULL; + } + + switch (format) + { + case PACKAGE_PORTABLE : + i = make_portable(prodname, directory, platname, dist, &platform, + setup, types); + break; + case PACKAGE_AIX : + i = make_aix(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_BSD : + i = make_bsd(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_SLACKWARE : + i = make_slackware(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_DEB : + if (geteuid()) + fputs("epm: Warning - file permissions and ownership may not be correct\n" + " in Debian packages unless you run EPM as root!\n", stderr); + + i = make_deb(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_INST : + i = make_inst(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_OSX : + i = make_osx(prodname, directory, platname, dist, &platform, setup); + break; + case PACKAGE_PKG : + i = make_pkg(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_LSB : + case PACKAGE_LSB_SIGNED : + case PACKAGE_RPM : + case PACKAGE_RPM_SIGNED : + i = make_rpm(format, prodname, directory, platname, dist, &platform, + setup, types); + break; + case PACKAGE_SETLD : + if (geteuid()) + fputs("epm: Warning - file permissions and ownership may not be correct\n" + " in Tru64 packages unless you run EPM as root!\n", stderr); + + i = make_setld(prodname, directory, platname, dist, &platform); + break; + case PACKAGE_SWINSTALL : + if (geteuid()) + { + fputs("epm: Error - HP-UX packages must be built as root!\n", stderr); + i = 1; + } + else + i = make_swinstall(prodname, directory, platname, dist, &platform); + break; + } + + /* + * All done! + */ + + free_dist(dist); + + if (i) + puts("Packaging failed!"); + else if (Verbosity) + puts("Done!"); + + return (i); +} + + +/* + * 'depend()' - Show dependencies. + */ + +static void +depend(dist_t *dist) /* I - Distribution */ +{ + int i; /* Looping var */ + file_t *file; /* Current file */ + + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + switch (file->type) + { + case 'c' : + case 'f' : + case 'i' : + case 'C' : + case 'F' : + case 'I' : + puts(file->src); + break; + } +} + + +/* + * 'info()' - Show the EPM copyright and license. + */ + +static void +info(void) +{ + puts(EPM_VERSION); + puts("Copyright 1999-2007 by Easy Software Products."); + puts(""); + puts("EPM is free software and comes with ABSOLUTELY NO WARRANTY; for details"); + puts("see the GNU General Public License in the file COPYING or at"); + puts("\"http://www.fsf.org/gpl.html\". Report all problems to \"epm@easysw.com\"."); + puts(""); +} + + +/* + * 'usage()' - Show command-line usage instructions. + */ + +static void +usage(void) +{ + info(); + + puts("Usage: epm [options] [name=value ... name=value] product [list-file]"); + puts("Options:"); + puts("-a arch"); + puts(" Use the named architecture instead of the local one."); + puts("-g"); + puts(" Don't strip executables in distributions."); + puts("-f {aix,bsd,deb,depot,inst,native,pkg,portable,rpm,setld,slackware,swinstall,tardist}"); + puts(" Set distribution format."); + puts("-k"); + puts(" Keep intermediate files (spec files, etc.)"); + puts("-m name"); + puts(" Set distribution filename to include the specified platform name."); + puts(" This overrides \"-n\"."); + puts("-n[mrs]"); + puts(" Set distribution filename to include machine (m), OS release (r),"); + puts(" and/or OS name (s)."); + puts("-s setup.xpm"); + puts(" Enable the setup GUI and use \"setup.xpm\" for the setup image."); + puts("-u"); +#if EPM_COMPRESS == 0 + puts(" Do not compress files in packages (default)."); +#else + puts(" Do not compress files in packages."); +#endif /* EPM_COMPRESS == 0 */ + puts("-v"); + puts(" Be verbose."); + puts("-z"); +#if EPM_COMPRESS == 1 + puts(" Compress files in packages (default)."); +#else + puts(" Compress files in packages."); +#endif /* EPM_COMPRESS == 1 */ + puts("--data-dir /foo/bar/directory"); + puts(" Use the named setup data file directory instead of " EPM_DATADIR "."); + puts("--help"); + puts(" Show this usage message."); + puts("--keep-files"); + puts(" Keep temporary distribution files in the output directory."); + puts("--output-dir /foo/bar/directory"); + puts(" Enable the setup GUI and use \"setup.xpm\" for the setup image."); + puts("--setup-image setup.xpm"); + puts(" Enable the setup GUI and use \"setup.xpm\" for the setup image."); + puts("--setup-program /foo/bar/setup"); + puts(" Use the named setup program instead of " EPM_LIBDIR "/setup."); + puts("--setup-types setup.types"); + puts(" Include the named setup.types file with the distribution."); + puts("--uninstalll-program /foo/bar/uninst"); + puts(" Use the named uninstall program instead of " EPM_LIBDIR "/uninst."); + puts("--version"); + puts(" Show EPM version."); + + exit(1); +} + + +/* + * End of "$Id: epm.c 819 2009-02-02 23:24:33Z mike $". + */ @@ -0,0 +1,349 @@ +/* + * "$Id: epm.h 833 2010-12-30 00:00:50Z mike $" + * + * Definitions for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Include necessary headers... + */ + +#ifndef _EPM_H_ +# define _EPM_H_ + +# include <stdio.h> +# include <stdlib.h> +# include <unistd.h> +# include <limits.h> +# include "epmstring.h" +# include <ctype.h> +# include <errno.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <time.h> +# include <pwd.h> +# include <grp.h> +# include <sys/utsname.h> + +# if HAVE_DIRENT_H +# include <dirent.h> +typedef struct dirent DIRENT; +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +typedef struct direct DIRENT; +# define NAMLEN(dirent) (dirent)->d_namlen +# endif + + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Macro to eliminate "variable was never referenced" errors... + */ + +# define REF(x) (void)(x); + + +/* + * TAR constants... + */ + +# define TAR_BLOCK 512 /* Number of bytes in a block */ +# define TAR_BLOCKS 10 /* Blocking factor */ + +# define TAR_MAGIC "ustar" /* 5 chars and a null */ +# define TAR_VERSION "00" /* POSIX tar version */ + +# define TAR_OLDNORMAL '\0' /* Normal disk file, Unix compat */ +# define TAR_NORMAL '0' /* Normal disk file */ +# define TAR_LINK '1' /* Link to previously dumped file */ +# define TAR_SYMLINK '2' /* Symbolic link */ +# define TAR_CHR '3' /* Character special file */ +# define TAR_BLK '4' /* Block special file */ +# define TAR_DIR '5' /* Directory */ +# define TAR_FIFO '6' /* FIFO special file */ +# define TAR_CONTIG '7' /* Contiguous file */ + +/* + * Package formats... + */ + +enum +{ + PACKAGE_PORTABLE, /* Shell-script based EPM */ + PACKAGE_AIX, /* AIX package format */ + PACKAGE_BSD, /* BSD package format */ + PACKAGE_DEB, /* Debian package format */ + PACKAGE_INST, /* IRIX package format */ + PACKAGE_LSB, /* LSB (RPM) package format */ + PACKAGE_LSB_SIGNED, /* LSB (RPM) package format (signed) */ + PACKAGE_OSX, /* MacOS X package format */ + PACKAGE_PKG, /* AT&T package format (AIX, Solaris) */ + PACKAGE_RPM, /* RedHat package format */ + PACKAGE_RPM_SIGNED, /* RedHat package format (signed) */ + PACKAGE_SETLD, /* Tru64 package format */ + PACKAGE_SLACKWARE, /* Slackware package format */ + PACKAGE_SWINSTALL /* HP-UX package format */ +}; + +/* + * Command types... + */ + +enum +{ + COMMAND_PRE_INSTALL, /* Command to run before install */ + COMMAND_POST_INSTALL, /* Command to run after install */ + COMMAND_PRE_PATCH, /* Command to run before patch */ + COMMAND_POST_PATCH, /* Command to run after patch */ + COMMAND_PRE_REMOVE, /* Command to run before remove */ + COMMAND_POST_REMOVE, /* Command to run after remove */ + COMMAND_LITERAL /* Literal (format-specific) data */ +}; + +/* + * Dependency types... + */ + +enum +{ + DEPEND_REQUIRES, /* This product requires */ + DEPEND_INCOMPAT, /* This product is incompatible with */ + DEPEND_REPLACES, /* This product replaces */ + DEPEND_PROVIDES /* This product provides */ +}; + + +/* + * Structures... + */ + +typedef union /**** TAR record format ****/ +{ + unsigned char all[TAR_BLOCK]; /* Raw data block */ + struct + { + char pathname[100], /* Destination path */ + mode[8], /* Octal file permissions */ + uid[8], /* Octal user ID */ + gid[8], /* Octal group ID */ + size[12], /* Octal size in bytes */ + mtime[12], /* Octal modification time */ + chksum[8], /* Octal checksum value */ + linkflag, /* File type */ + linkname[100], /* Source path for link */ + magic[6], /* Magic string */ + version[2], /* Format version */ + uname[32], /* User name */ + gname[32], /* Group name */ + devmajor[8], /* Octal device major number */ + devminor[8], /* Octal device minor number */ + prefix[155]; /* Prefix for long filenames */ + } header; +} tar_t; + +typedef struct /**** TAR file ****/ +{ + FILE *file; /* File to write to */ + int blocks, /* Number of blocks written */ + compressed; /* Compressed output? */ +} tarf_t; + +typedef struct /**** File to install ****/ +{ + int type; /* Type of file */ + mode_t mode; /* Permissions of file */ + char user[32], /* Owner of file */ + group[32], /* Group of file */ + src[512], /* Source path */ + dst[512], /* Destination path */ + options[256]; /* File options */ + const char *subpackage; /* Sub-package name */ +} file_t; + +typedef struct /**** Install/Patch/Remove Commands ****/ +{ + int type; /* Command type */ + char *command; /* Command string */ + const char *subpackage; /* Sub-package name */ + char *section; /* Literal section */ +} command_t; + +typedef struct /**** Dependencies ****/ +{ + int type; /* Dependency type */ + char product[256]; /* Product name */ + char version[2][256]; /* Product version string */ + int vernumber[2]; /* Product version number */ + const char *subpackage; /* Sub-package name */ +} depend_t; + +typedef struct /**** Description Structure ****/ +{ + char *description; /* Description */ + const char *subpackage; /* Sub-package name */ +} description_t; + +typedef struct /**** Distribution Structure ****/ +{ + char product[256], /* Product name */ + version[256], /* Product version string */ + release[256], /* Product release string */ + copyright[256], /* Product copyright */ + vendor[256], /* Vendor name */ + packager[256], /* Packager name */ + license[256], /* License file to copy */ + readme[256]; /* README file to copy */ + int num_subpackages; /* Number of subpackages */ + char **subpackages; /* Subpackage names */ + int num_descriptions; /* Number of description strings */ + description_t *descriptions; /* Description strings */ + int vernumber, /* Version number */ + epoch; /* Epoch number */ + int num_commands; /* Number of commands */ + command_t *commands; /* Commands */ + int num_depends; /* Number of dependencies */ + depend_t *depends; /* Dependencies */ + int num_files; /* Number of files */ + file_t *files; /* Files */ +} dist_t; + + +/* + * Globals... + */ + +extern int CompressFiles; /* Compress package files? */ +extern const char *DataDir; /* Directory for setup data files */ +extern int KeepFiles; /* Keep intermediate files? */ +extern const char *SetupProgram; /* Setup program */ +extern const char *SoftwareDir; /* Software directory path */ +extern const char *UninstProgram; /* Uninstall program */ +extern int Verbosity; /* Be verbose? */ + + +/* + * Prototypes... + */ + +extern void add_command(dist_t *dist, FILE *fp, int type, + const char *command, const char *subpkg, + const char *section); +extern void add_depend(dist_t *dist, int type, const char *line, + const char *subpkg); +extern void add_description(dist_t *dist, FILE *fp, const char *description, + const char *subpkg); +extern file_t *add_file(dist_t *dist, const char *subpkg); +extern char *add_subpackage(dist_t *dist, const char *subpkg); +extern int copy_file(const char *dst, const char *src, + mode_t mode, uid_t owner, gid_t group); +extern char *find_subpackage(dist_t *dist, const char *subpkg); +extern void free_dist(dist_t *dist); +extern const char *get_option(file_t *file, const char *name, const char *defval); +extern void get_platform(struct utsname *platform); +extern const char *get_runlevels(file_t *file, const char *deflevels); +extern int get_start(file_t *file, int defstart); +extern int get_stop(file_t *file, int defstop); +extern int get_vernumber(const char *version); +extern int make_aix(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_bsd(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_deb(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_directory(const char *directory, mode_t mode, uid_t owner, + gid_t group); +extern int make_inst(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_link(const char *dst, const char *src); +extern int make_osx(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform, const char *setup); +extern int make_pkg(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_portable(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform, const char *setup, + const char *types); +extern int make_rpm(int format, const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform, const char *setup, + const char *types); +extern int make_setld(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_slackware(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern int make_swinstall(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform); +extern dist_t *new_dist(void); +extern int qprintf(FILE *fp, const char *format, ...); +extern dist_t *read_dist(const char *filename, struct utsname *platform, + const char *format); +extern int run_command(const char *directory, const char *command, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +# endif /* __GNUC__ */ +; +extern void sort_dist_files(dist_t *dist); +extern void strip_execs(dist_t *dist); +extern int tar_close(tarf_t *tar); +extern int tar_directory(tarf_t *tar, const char *srcpath, + const char *dstpath); +extern int tar_file(tarf_t *tar, const char *filename); +extern int tar_header(tarf_t *tar, int type, mode_t mode, off_t size, + time_t mtime, const char *user, const char *group, + const char *pathname, const char *linkname); +extern tarf_t *tar_open(const char *filename, int compress); +extern int tar_package(tarf_t *tar, const char *ext, + const char *prodname, const char *directory, + const char *platname, dist_t *dist, + const char *subpackage); +extern int unlink_directory(const char *directory); +extern int unlink_package(const char *ext, const char *prodname, + const char *directory, const char *platname, + dist_t *dist, const char *subpackage); +extern int write_dist(const char *listname, dist_t *dist); + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_EPM_H_ */ + + +/* + * End of "$Id: epm.h 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/epm.list.in b/epm.list.in new file mode 100644 index 0000000..11b9fb2 --- /dev/null +++ b/epm.list.in @@ -0,0 +1,92 @@ +# +# "$Id: epm.list.in 782 2007-12-02 22:46:24Z mike $" +# +# Sample software list file for the ESP Package Manager (EPM). +# +# Please report problems and fixes to "epm@easysw.com". +# +# Copyright 1999-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "COPYING" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: EPM Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636 USA +# +# Voice: (301) 373-9600 +# EMail: epm@easysw.com +# WWW: http://www.easysw.com/epm +# + +# Directories... +$prefix=@prefix@ +$exec_prefix=@exec_prefix@ +$bindir=@bindir@ +$datarootdir=@datarootdir@ +$datadir=@datadir@ +$docdir=@docdir@ +$libdir=@libdir@ +$mandir=@mandir@ +$srcdir=@srcdir@ + +# Product information +%product ESP Package Manager +%copyright 1999-2007 by Easy Software Products, All Rights Reserved. +%vendor Easy Software Products +%license ${srcdir}/COPYING +%readme ${srcdir}/README +%description Universal software packaging tool for UNIX. +%version @VERSION@ @VERNUMBER@ + +# Executables +%system all +f 0555 root sys ${bindir}/epm epm +f 0555 root sys ${bindir}/epminstall epminstall +f 0555 root sys ${bindir}/mkepmlist mkepmlist + +# Documentation +%subpackage documentation +%description Documentation +f 0444 root sys ${docdir}/README $srcdir/README +f 0444 root sys ${docdir}/COPYING $srcdir/COPYING +f 0444 root sys ${docdir}/epm-book.html $srcdir/doc/epm-book.html + +# Man pages +%subpackage man +%description Man pages +f 0444 root sys ${mandir}/man1/epm.1 $srcdir/doc/epm.man +f 0444 root sys ${mandir}/man1/epminstall.1 $srcdir/doc/epminstall.man +f 0444 root sys ${mandir}/man1/mkepmlist.1 $srcdir/doc/mkepmlist.man +f 0444 root sys ${mandir}/man5/epm.list.5 $srcdir/doc/epm.list.man + +# GUI files... +$GUIS=@GUIS@ + +%if GUIS +%subpackage +f 0555 root sys ${libdir}/epm/setup setup +f 0555 root sys ${libdir}/epm/uninst uninst + +%system darwin +f 0444 root sys ${datadir}/epm/setup.icns macosx/setup.icns +f 0444 root sys ${datadir}/epm/setup.info macosx/setup.info + +f 0444 root sys ${datadir}/epm/uninst.icns macosx/uninst.icns +f 0444 root sys ${datadir}/epm/uninst.info macosx/uninst.info +%system all + +%subpackage man +f 0444 root sys ${mandir}/man1/setup.1 $srcdir/doc/setup.man +f 0444 root sys ${mandir}/man5/setup.types.5 $srcdir/doc/setup.types.man + +%endif + +# +# End of "$Id: epm.list.in 782 2007-12-02 22:46:24Z mike $". +# diff --git a/epminstall.c b/epminstall.c new file mode 100644 index 0000000..4f3083f --- /dev/null +++ b/epminstall.c @@ -0,0 +1,415 @@ +/* + * "$Id: epminstall.c 827 2010-12-29 17:32:40Z mike $" + * + * Install program replacement for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * main() - Add or replace files, directories, and symlinks. + * find_file() - Find a file in the distribution... + * info() - Show the EPM copyright and license. + * usage() - Show command-line usage instructions. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Global variable used by dist functions... + */ + +int Verbosity = 0; + + +/* + * Local functions... + */ + +static file_t *find_file(dist_t *dist, const char *dst); +static void info(void); +static void usage(void) +#ifdef __GNUC__ +__attribute__((__noreturn__)) +#endif /* __GNUC__ */ +; + + +/* + * 'main()' - Add or replace files, directories, and symlinks. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int mode, /* Permissions */ + directories; /* Installing directories? */ + char *user, /* Owner */ + *group, /* Group */ + *listname, /* List filename */ + *src, /* Source filename */ + dst[1024], /* Destination filename */ + linkname[1024]; /* Symlink name */ + int linklen; /* Length of symlink */ + int num_files; /* Number of files to install */ + char *files[1000]; /* Files to install */ + struct stat fileinfo; /* File information */ + dist_t *dist; /* Distribution */ + file_t *file; /* File in distribution */ + struct utsname platform; /* Platform information */ + + + /* + * Parse the command-line arguments... + */ + + num_files = 0; + mode = 0; + user = "root"; + group = "sys"; + directories = 0; + + if ((listname = getenv("EPMLIST")) == NULL) + listname = "epm.list"; + + for (i = 1; i < argc; i ++) + if (strcmp(argv[i], "-b") == 0) + continue; + else if (strcmp(argv[i], "-c") == 0) + continue; + else if (strcmp(argv[i], "-d") == 0) + directories = 1; + else if (strcmp(argv[i], "-g") == 0) + { + i ++; + if (i < argc) + group = argv[i]; + else + usage(); + } + else if (strcmp(argv[i], "-m") == 0) + { + i ++; + if (i < argc) + mode = strtol(argv[i], NULL, 8); + else + usage(); + } + else if (strcmp(argv[i], "-o") == 0) + { + i ++; + if (i < argc) + user = argv[i]; + else + usage(); + } + else if (strcmp(argv[i], "-s") == 0) + continue; + else if (strcmp(argv[i], "--list-file") == 0) + { + i ++; + if (i < argc) + listname = argv[i]; + else + usage(); + } + else if (argv[i][0] == '-') + usage(); + else if (num_files < (sizeof(files) / sizeof(files[0]))) + { + files[num_files] = argv[i]; + num_files ++; + } + else + { + fputs("epminstall: Too many filenames on command-line!\n", stderr); + usage(); + } + + if (num_files == 0 || (num_files < 2 && !directories)) + usage(); + + get_platform(&platform); + + if ((dist = read_dist(listname, &platform, "")) == NULL) + { + fprintf(stderr, "epminstall: Unable to read list file \"%s\": %s\n", + listname, strerror(errno)); + return (1); + } + + /* + * Check to see if we are installing files or directories... + */ + + if (directories) + { + if (!mode) + mode = 0755; + + for (i = 0; i < num_files; i ++) + { + /* + * Copy the directory name into a new file entry, which is cleared + * by add_file()... + */ + + if ((file = find_file(dist, files[i])) == NULL) + file = add_file(dist, NULL); + + file->type = 'd'; + file->mode = mode & 07777; + strlcpy(file->user, user, sizeof(file->user)); + strlcpy(file->group, group, sizeof(file->group)); + strlcpy(file->dst, files[i], sizeof(file->dst)); + strcpy(file->src, "-"); + } + } + else + { + /* + * Check to see if we have 1 or more files and a directory or + * a source and destination file... + */ + + if (num_files == 2) + { + file = find_file(dist, files[1]); + + if (file == NULL || file->type != 'd') + { + if (!file) + file = add_file(dist, NULL); + + if (stat(files[0], &fileinfo)) + { + fprintf(stderr, "epminstall: Unable to stat \"%s\": %s\n", + files[0], strerror(errno)); + fileinfo.st_mode = mode; + } + + if (S_ISLNK(fileinfo.st_mode)) + { + file->type = 'l'; + + if ((linklen = readlink(files[0], linkname, sizeof(linkname) - 1)) < 0) + { + fprintf(stderr, "epminstall: Unable to read symlink \"%s\": %s\n", + files[0], strerror(errno)); + files[0] = "BROKEN-LINK"; + } + else + { + linkname[linklen] = '\0'; + files[0] = linkname; + } + } + else + file->type = 'f'; + + if (mode) + file->mode = mode & 07777; + else if (fileinfo.st_mode & 0111) + file->mode = 0755; + else + file->mode = 0644; + + strlcpy(file->user, user, sizeof(file->user)); + strlcpy(file->group, group, sizeof(file->group)); + strlcpy(file->dst, files[1], sizeof(file->dst)); + strlcpy(file->src, files[0], sizeof(file->src)); + } + else + num_files --; + } + + if (num_files != 2) + { + if (num_files > 1) + num_files --; + + if ((file = find_file(dist, files[num_files])) == NULL) + { + /* + * Add the installation directory to the file list... + */ + + file = add_file(dist, NULL); + + file->type = 'd'; + file->mode = 0755; + strlcpy(file->user, user, sizeof(file->user)); + strlcpy(file->group, group, sizeof(file->group)); + strlcpy(file->dst, files[num_files], sizeof(file->dst)); + strcpy(file->src, "-"); + } + else if (file->type != 'd') + { + fprintf(stderr, "epminstall: Destination path \"%s\" is not a directory!\n", + files[num_files]); + return (1); + } + + for (i = 0; i < num_files; i ++) + { + /* + * Add/update the file in the distribution... + */ + + if ((src = strrchr(files[i], '/')) != NULL) + src ++; + else + src = files[i]; + + snprintf(dst, sizeof(dst), "%s/%s", files[num_files], src); + + if ((file = find_file(dist, dst)) == NULL) + file = add_file(dist, NULL); + + if (stat(files[i], &fileinfo)) + { + fprintf(stderr, "epminstall: Unable to stat \"%s\": %s\n", + files[i], strerror(errno)); + fileinfo.st_mode = mode; + } + + if (S_ISLNK(fileinfo.st_mode)) + { + file->type = 'l'; + + if ((linklen = readlink(files[i], linkname, sizeof(linkname) - 1)) < 0) + { + fprintf(stderr, "epminstall: Unable to read symlink \"%s\": %s\n", + files[i], strerror(errno)); + files[i] = "BROKEN-LINK"; + } + else + { + linkname[linklen] = '\0'; + files[i] = linkname; + } + } + else + file->type = 'f'; + + if (mode) + file->mode = mode & 07777; + else if (fileinfo.st_mode & 0111) + file->mode = 0755; + else + file->mode = 0644; + + strlcpy(file->user, user, sizeof(file->user)); + strlcpy(file->group, group, sizeof(file->group)); + strlcpy(file->dst, dst, sizeof(file->dst)); + strlcpy(file->src, files[i], sizeof(file->src)); + } + } + } + + /* + * Sort the files to make the final list file easier to check... + */ + + sort_dist_files(dist); + + /* + * Write the distribution file... + */ + + if (write_dist(listname, dist)) + { + fprintf(stderr, "epminstall: Unable to read list file \"%s\": %s\n", + listname, strerror(errno)); + return (1); + } + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'find_file()' - Find a file in the distribution... + */ + +static file_t * /* O - File entry or NULL */ +find_file(dist_t *dist, /* I - Distribution to search */ + const char *dst) /* I - Destination filename */ +{ + int i; /* Looping var */ + file_t *file; /* Current file */ + + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strcmp(file->dst, dst) == 0) + return (file); + + return (NULL); +} + + +/* + * 'info()' - Show the EPM copyright and license. + */ + +static void +info(void) +{ + puts(EPM_VERSION); + puts("Copyright 1999-2005 by Easy Software Products."); + puts(""); + puts("EPM is free software and comes with ABSOLUTELY NO WARRANTY; for details"); + puts("see the GNU General Public License in the file COPYING or at"); + puts("\"http://www.fsf.org/gpl.html\". Report all problems to \"epm@easysw.com\"."); + puts(""); +} + + +/* + * 'usage()' - Show command-line usage instructions. + */ + +static void +usage(void) +{ + info(); + + puts("Usage: epminstall [options] file1 file2 ... fileN directory"); + puts(" epminstall [options] file1 file2"); + puts(" epminstall [options] -d directory1 directory2 ... directoryN"); + puts("Options:"); + puts("-g group"); + puts(" Set group of installed file(s)."); + puts("-m mode"); + puts(" Set permissions of installed file(s)."); + puts("-u owner"); + puts(" Set owner of installed file(s)."); + + exit(1); +} + + +/* + * End of "$Id: epminstall.c 827 2010-12-29 17:32:40Z mike $". + */ diff --git a/epmsetup.gif b/epmsetup.gif Binary files differnew file mode 100644 index 0000000..817ac30 --- /dev/null +++ b/epmsetup.gif diff --git a/epmstring.h b/epmstring.h new file mode 100644 index 0000000..13d0edb --- /dev/null +++ b/epmstring.h @@ -0,0 +1,90 @@ +/* + * "$Id: epmstring.h 611 2005-01-11 21:37:42Z mike $" + * + * String definitions for the ESP Package Manager (EPM). + * + * Copyright 1999-2005 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _EPM_STRING_H_ +# define _EPM_STRING_H_ + +/* + * Include necessary headers... + */ + +# include "config.h" +# include <string.h> +# include <stdarg.h> + +# ifdef HAVE_STRINGS_H +# include <strings.h> +# endif /* HAVE_STRINGS_H */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Prototypes... + */ + +# ifndef HAVE_STRDUP +extern char *epm_strdup(const char *); +# define strdup epm_strdup +# endif /* !HAVE_STRDUP */ + +# ifndef HAVE_STRCASECMP +extern int epm_strcasecmp(const char *, const char *); +# define strcasecmp epm_strcasecmp +# endif /* !HAVE_STRCASECMP */ + +# ifndef HAVE_STRNCASECMP +extern int epm_strncasecmp(const char *, const char *, size_t n); +# define strncasecmp epm_strncasecmp +# endif /* !HAVE_STRNCASECMP */ + +# ifndef HAVE_STRLCAT +extern size_t epm_strlcat(char *, const char *, size_t); +# define strlcat epm_strlcat +# endif /* !HAVE_STRLCAT */ + +# ifndef HAVE_STRLCPY +extern size_t epm_strlcpy(char *, const char *, size_t); +# define strlcpy epm_strlcpy +# endif /* !HAVE_STRLCPY */ + +# ifndef HAVE_SNPRINTF +extern int epm_snprintf(char *, size_t, const char *, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; +# define snprintf epm_snprintf +# endif /* !HAVE_SNPRINTF */ + +# ifndef HAVE_VSNPRINTF +extern int epm_vsnprintf(char *, size_t, const char *, va_list); +# define vsnprintf epm_vsnprintf +# endif /* !HAVE_VSNPRINTF */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_EPM_STRING_H_ */ + +/* + * End of "$Id: epmstring.h 611 2005-01-11 21:37:42Z mike $". + */ @@ -0,0 +1,445 @@ +/* + * "$Id: file.c 841 2010-12-30 20:34:57Z mike $" + * + * File functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * copy_file() - Copy a file. + * make_directory() - Make a directory. + * make_link() - Make a symbolic link. + * strip_execs() - Strip symbols from executable files in the + * distribution. + * unlink_directory() - Delete a directory and all of its nodes. + * unlink_package() - Delete a package file. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * 'copy_file()' - Copy a file. + */ + +int /* O - 0 on success, -1 on failure */ +copy_file(const char *dst, /* I - Destination file */ + const char *src, /* I - Source file */ + mode_t mode, /* I - Permissions */ + uid_t owner, /* I - Owner ID */ + gid_t group) /* I - Group ID */ +{ + FILE *dstfile, /* Destination file */ + *srcfile; /* Source file */ + char buffer[8192]; /* Copy buffer */ + char *slash; /* Pointer to trailing slash */ + size_t bytes; /* Number of bytes read/written */ + struct stat srcinfo; /* Source file information */ + + + /* + * Check that the destination directory exists... + */ + + strcpy(buffer, dst); + if ((slash = strrchr(buffer, '/')) != NULL) + *slash = '\0'; + + if (access(buffer, F_OK)) + make_directory(buffer, 0755, owner, group); + + /* + * Try doing a hard link instead of a copy... + */ + + unlink(dst); + + if (!stat(src, &srcinfo) && + (!mode || srcinfo.st_mode == mode) && + (owner == (uid_t)-1 || srcinfo.st_uid == owner) && + (group == (gid_t)-1 || srcinfo.st_gid == group) && + !link(src, dst)) + return (0); + + /* + * Open files... + */ + + if ((dstfile = fopen(dst, "wb")) == NULL) + { + fprintf(stderr, "epm: Unable to create \"%s\" -\n %s\n", dst, + strerror(errno)); + return (-1); + } + + if ((srcfile = fopen(src, "rb")) == NULL) + { + fclose(dstfile); + unlink(dst); + + fprintf(stderr, "epm: Unable to open \"%s\" -\n %s\n", src, + strerror(errno)); + return (-1); + } + + /* + * Copy from src to dst... + */ + + while ((bytes = fread(buffer, 1, sizeof(buffer), srcfile)) > 0) + if (fwrite(buffer, 1, bytes, dstfile) < bytes) + { + fprintf(stderr, "epm: Unable to write to \"%s\" -\n %s\n", dst, + strerror(errno)); + + fclose(srcfile); + fclose(dstfile); + unlink(dst); + + return (-1); + } + + /* + * Close files, change permissions, and return... + */ + + fclose(srcfile); + fclose(dstfile); + + if (mode) + chmod(dst, mode); + if (owner != (uid_t)-1 && group != (gid_t)-1) + chown(dst, owner, group); + + return (0); +} + + +/* + * 'make_directory()' - Make a directory. + */ + +int /* O - 0 = success, -1 = error */ +make_directory(const char *directory, /* I - Directory */ + mode_t mode, /* I - Permissions */ + uid_t owner, /* I - Owner ID */ + gid_t group) /* I - Group ID */ +{ + char buffer[8192], /* Filename buffer */ + *bufptr; /* Pointer into buffer */ + + + for (bufptr = buffer; *directory;) + { + if (*directory == '/' && bufptr > buffer) + { + *bufptr = '\0'; + + if (access(buffer, F_OK)) + { + mkdir(buffer, 0755); + if (mode) + chmod(buffer, mode | 0700); + if (owner != (uid_t)-1 && group != (gid_t)-1) + chown(buffer, owner, group); + } + } + + *bufptr++ = *directory++; + } + + *bufptr = '\0'; + + if (access(buffer, F_OK)) + { + mkdir(buffer, 0755); + if (mode) + chmod(buffer, mode | 0700); + if (owner != (uid_t)-1 && group != (gid_t)-1) + chown(buffer, owner, group); + } + + return (0); +} + + +/* + * 'make_link()' - Make a symbolic link. + */ + +int /* O - 0 = success, -1 = error */ +make_link(const char *dst, /* I - Destination file */ + const char *src) /* I - Link */ +{ + char buffer[8192], /* Copy buffer */ + *slash; /* Pointer to trailing slash */ + + + /* + * Check that the destination directory exists... + */ + + strcpy(buffer, dst); + if ((slash = strrchr(buffer, '/')) != NULL) + *slash = '\0'; + + if (access(buffer, F_OK)) + make_directory(buffer, 0755, 0, 0); + + /* + * Make the symlink... + */ + + return (symlink(src, dst)); +} + + +/* + * 'strip_execs()' - Strip symbols from executable files in the distribution. + */ + +void +strip_execs(dist_t *dist) /* I - Distribution to strip... */ +{ + int i; /* Looping var */ + file_t *file; /* Software file */ + FILE *fp; /* File pointer */ + char header[4]; /* File header... */ + + + /* + * Loop through the distribution files and strip any executable + * files. + */ + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'f' && (file->mode & 0111) && + strstr(file->options, "nostrip()") == NULL) + { + /* + * OK, this file has executable permissions; see if it is a + * script... + */ + + if ((fp = fopen(file->src, "rb")) != NULL) + { + /* + * Read the first 3 bytes of the file... + */ + + if (fread(header, 1, sizeof(header) - 1, fp) == 0) + continue; + + header[sizeof(header) - 1] = '\0'; + + fclose(fp); + + /* + * Check for "#!/" or "#" + whitespace at the beginning of the file... + */ + + if (!strncmp(header, "#!/", 3) || + (header[0] == '#' && isspace(header[1] & 255))) + continue; + } + else + { + /* + * File could not be opened; error out... + */ + + fprintf(stderr, "epm: Unable to open file \"%s\" for destination " + "\"%s\" -\n %s\n", + file->src, file->dst, strerror(errno)); + + exit(1); + } + + /* + * Strip executables... + */ + + run_command(NULL, EPM_STRIP " %s", file->src); + } +} + + +/* + * 'unlink_directory()' - Delete a directory and all of its nodes. + */ + +int /* O - 0 on success, -1 on failure */ +unlink_directory(const char *directory) /* I - Directory */ +{ + DIR *dir; /* Directory */ + DIRENT *dent; /* Directory entry */ + char filename[1024]; /* Filename */ + struct stat fileinfo; /* Information on the source file */ + + + /* + * Try opening the source directory... + */ + + if ((dir = opendir(directory)) == NULL) + { + fprintf(stderr, "epm: Unable to open directory \"%s\": %s\n", directory, + strerror(errno)); + + return (-1); + } + + /* + * Read from the directory... + */ + + while ((dent = readdir(dir)) != NULL) + { + /* + * Skip "." and ".."... + */ + + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) + continue; + + /* + * Get file info... + */ + + snprintf(filename, sizeof(filename), "%s/%s", directory, dent->d_name); + + if (stat(filename, &fileinfo)) + { + fprintf(stderr, "epm: Unable to stat \"%s\": %s\n", filename, + strerror(errno)); + continue; + } + + /* + * Process accordingly... + */ + + if (Verbosity) + puts(filename); + + if (S_ISDIR(fileinfo.st_mode)) + { + /* + * Directory... + */ + + if (unlink_directory(filename)) + goto fail; + + if (rmdir(filename)) + { + fprintf(stderr, "epm: Unable to remove \"%s\": %s\n", filename, + strerror(errno)); + goto fail; + } + } + else + { + /* + * Regular file or symlink... + */ + + if (unlink(filename)) + { + fprintf(stderr, "epm: Unable to remove \"%s\": %s\n", filename, + strerror(errno)); + goto fail; + } + } + } + + closedir(dir); + return (0); + + fail: + + closedir(dir); + return (-1); +} + + +/* + * 'unlink_package()' - Delete a package file. + */ + +int /* O - 0 on success, -1 on failure */ +unlink_package(const char *ext, /* I - Package filename extension */ + const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + const char *subpackage) /* I - Subpackage */ +{ + char prodfull[255], /* Full name of product */ + name[1024], /* Full product name */ + filename[1024]; /* File to archive */ + + + /* + * Figure out the full name of the distribution... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + /* + * Then the subdirectory name... + */ + + if (dist->release[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version, + dist->release); + else + snprintf(name, sizeof(name), "%s-%s", prodfull, dist->version); + + if (platname[0]) + { + strlcat(name, "-", sizeof(name)); + strlcat(name, platname, sizeof(name)); + } + + strlcat(name, ".", sizeof(name)); + strlcat(name, ext, sizeof(name)); + + /* + * Remove the package file... + */ + + snprintf(filename, sizeof(filename), "%s/%s", directory, name); + + if (unlink(filename)) + { + fprintf(stderr, "epm: Unable to remove \"%s\" - %s\n", filename, + strerror(errno)); + return (-1); + } + else + return (0); +} + + +/* + * End of "$Id: file.c 841 2010-12-30 20:34:57Z mike $". + */ diff --git a/gui-common.cxx b/gui-common.cxx new file mode 100644 index 0000000..c0afc6b --- /dev/null +++ b/gui-common.cxx @@ -0,0 +1,348 @@ +// +// "$Id: gui-common.cxx 739 2006-12-05 17:20:27Z mike $" +// +// ESP Software Wizard common functions for the ESP Package Manager (EPM). +// +// Copyright 1999-2006 by Easy Software Products. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Contents: +// +// gui_add_depend() - Add a dependency to a distribution. +// gui_add_dist() - Add a distribution. +// gui_find_dist() - Find a distribution. +// gui_get_installed() - Get a list of installed software products. +// gui_load_file() - Load a file into a help widget. +// gui_sort_dists() - Compare two distribution names... +// + +#include "gui-common.h" +#include <FL/filename.H> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + + +// +// 'gui_add_depend()' - Add a dependency to a distribution. +// + +void +gui_add_depend(gui_dist_t *d, // I - Distribution + int type, // I - Dependency type + const char *name, // I - Name of product + int lowver, // I - Lower version number + int hiver) // I - Highre version number +{ + gui_depend_t *temp; // Pointer to dependency + + + if (d->num_depends == 0) + temp = (gui_depend_t *)malloc(sizeof(gui_depend_t)); + else + temp = (gui_depend_t *)realloc(d->depends, + sizeof(gui_depend_t) * (d->num_depends + 1)); + + if (temp == NULL) + { + perror("setup: Unable to allocate memory for dependency"); + exit(1); + } + + d->depends = temp; + temp += d->num_depends; + d->num_depends ++; + + memset(temp, 0, sizeof(gui_depend_t)); + strncpy(temp->product, name, sizeof(temp->product) - 1); + temp->type = type; + temp->vernumber[0] = lowver; + temp->vernumber[1] = hiver; +} + + +// +// 'gui_add_dist()' - Add a distribution. +// + +gui_dist_t * // O - New distribution +gui_add_dist(int *num_d, // IO - Number of distributions + gui_dist_t **d) // IO - Distributions +{ + gui_dist_t *temp; // Pointer to current distribution + + + // Add a new distribution entry... + if (*num_d == 0) + temp = (gui_dist_t *)malloc(sizeof(gui_dist_t)); + else + temp = (gui_dist_t *)realloc(*d, sizeof(gui_dist_t) * (*num_d + 1)); + + if (temp == NULL) + { + perror("setup: Unable to allocate memory for distribution"); + exit(1); + } + + *d = temp; + temp += *num_d; + (*num_d) ++; + + memset(temp, 0, sizeof(gui_dist_t)); + + return (temp); +} + + +// +// 'gui_find_dist()' - Find a distribution. +// + +gui_dist_t * // O - Pointer to distribution or NULL +gui_find_dist(const char *name, // I - Distribution name + int num_d, // I - Number of distributions + gui_dist_t *d) // I - Distributions +{ + while (num_d > 0) + { + if (!strcmp(name, d->product)) + return (d); + + d ++; + num_d --; + } + + return (NULL); +} + + +// +// 'gui_get_installed()' - Get a list of installed software products. +// + +void +gui_get_installed(void) +{ + int i; // Looping var + int num_files; // Number of files + dirent **files; // Files + const char *ext; // Extension + gui_dist_t *temp; // Pointer to current distribution + FILE *fp; // File to read from + char line[1024]; // Line from file... + + + // See if there are any installed files... + NumInstalled = 0; + Installed = (gui_dist_t *)0; + + if ((num_files = fl_filename_list(EPM_SOFTWARE, &files)) > 0) + { + // Build a distribution list... + for (i = 0; i < num_files; i ++) + { + ext = fl_filename_ext(files[i]->d_name); + + if (!strcmp(ext, ".remove")) + { + // Found a .remove script... + snprintf(line, sizeof(line), EPM_SOFTWARE "/%s", files[i]->d_name); + if ((fp = fopen(line, "r")) == NULL) + { + perror("setup: Unable to open removal script"); + exit(1); + } + + // Add a new distribution entry... + temp = gui_add_dist(&NumInstalled, &Installed); + temp->type = PACKAGE_PORTABLE; + + strncpy(temp->product, files[i]->d_name, sizeof(temp->product) - 1); + *strrchr(temp->product, '.') = '\0'; // Drop .remove + + // Read info from the removal script... + while (fgets(line, sizeof(line), fp)) + { + // Only read distribution info lines... + if (strncmp(line, "#%", 2)) + continue; + + // Drop the trailing newline... + line[strlen(line) - 1] = '\0'; + + // Copy data as needed... + if (!strncmp(line, "#%product ", 10)) + strncpy(temp->name, line + 10, sizeof(temp->name) - 1); + else if (!strncmp(line, "#%version ", 10)) + sscanf(line + 10, "%31s%d", temp->version, &(temp->vernumber)); + else if (!strncmp(line, "#%rootsize ", 11)) + temp->rootsize = atoi(line + 11); + else if (!strncmp(line, "#%usrsize ", 10)) + temp->usrsize = atoi(line + 10); + } + + fclose(fp); + } + + free(files[i]); + } + + free(files); + } + + // Get a list of RPM packages that are installed... + if (!access("/bin/rpm", 0) && + (fp = popen("/bin/rpm -qa --qf " + "'%{NAME}|%{VERSION}|%{SIZE}|%{SUMMARY}\\n'", "r")) != NULL) + { + char *version, // Version number + *size, // Size of package + *description; // Summary string + + + while (fgets(line, sizeof(line), fp)) + { + // Drop the trailing newline... + line[strlen(line) - 1] = '\0'; + + // Grab the different fields... + if ((version = strchr(line, '|')) == NULL) + continue; + *version++ = '\0'; + + if ((size = strchr(version, '|')) == NULL) + continue; + *size++ = '\0'; + + if ((description = strchr(size, '|')) == NULL) + continue; + *description++ = '\0'; + + // Add a new distribution entry... + temp = gui_add_dist(&NumInstalled, &Installed); + temp->type = PACKAGE_RPM; + + strlcpy(temp->product, line, sizeof(temp->product)); + strlcpy(temp->name, description, sizeof(temp->name)); + strlcpy(temp->version, version, sizeof(temp->version)); + temp->vernumber = get_vernumber(version); + temp->rootsize = (int)(atof(size) / 1024.0 + 0.5); + } + + pclose(fp); + } + + if (NumInstalled > 1) + qsort(Installed, NumInstalled, sizeof(gui_dist_t), + (compare_func_t)gui_sort_dists); +} + + +// +// 'gui_load_file()' - Load a file into a help widget. +// + +void +gui_load_file(Fl_Help_View *hv, // I - Help widget + const char *filename) // I - File to load +{ + FILE *fp; // File pointer + struct stat info; // Info about file + int ch; // Character from file + char *buffer, // File buffer + *ptr; // Pointer into buffer + + + // Try opening the file and getting the file size... + if ((fp = fopen(filename, "r")) == NULL) + { + hv->value(strerror(errno)); + return; + } + + if (stat(filename, &info)) + { + hv->value(strerror(errno)); + return; + } + + // Allocate a buffer that is more than big enough to the hold the file... + buffer = new char[info.st_size * 2]; + + // See if we have a HTML file... + if ((ch = getc(fp)) == '<') + { + // Yes, just read it in... + buffer[0] = ch; + fread(buffer + 1, 1, info.st_size - 1, fp); + buffer[info.st_size] = '\0'; + } + else + { + // No, treat it as plain text... + ungetc(ch, fp); + + strcpy(buffer, "<pre>"); + + ptr = buffer + 5; + + while ((ch = getc(fp)) != EOF) + { + if (ch == '&') + { + strcpy(ptr, "&"); + ptr += 5; + } + else if (ch == '<') + { + strcpy(ptr, "<"); + ptr += 4; + } + else + *ptr++ = ch; + } + + strcpy(ptr, "</pre>\n"); + + // Preformatted text will be too large without a reduction in the + // base size... + hv->textsize(10); + } + + // Save the loaded buffer to the help widget... + hv->value(buffer); + + // Free memory and close the file... + delete[] buffer; + fclose(fp); +} + + +// +// 'gui_sort_dists()' - Compare two distribution names... +// + +int // O - Result of comparison +gui_sort_dists(const gui_dist_t *d0, // I - First distribution + const gui_dist_t *d1) // I - Second distribution +{ + return (strcmp(d0->name, d1->name)); +} + + +// +// End of "$Id: gui-common.cxx 739 2006-12-05 17:20:27Z mike $". +// diff --git a/gui-common.h b/gui-common.h new file mode 100644 index 0000000..77f99da --- /dev/null +++ b/gui-common.h @@ -0,0 +1,107 @@ +// +// "$Id: gui-common.h 733 2006-11-30 21:59:27Z mike $" +// +// ESP Software Wizard common header file for the ESP Package Manager (EPM). +// +// Copyright 1999-2006 by Easy Software Products. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// + +// +// Include necessary headers... +// + +#include "epmstring.h" +#include "epm.h" +#include <stdio.h> +#include <stdlib.h> +#include <FL/Fl_Help_View.H> + + +// +// Distribution structures... +// + +struct gui_depend_t //// Dependencies +{ + int type; // Type of dependency + char product[64]; // Name of product or file + int vernumber[2]; // Version number(s) +}; + +struct gui_dist_t //// Distributions +{ + int type; // Package type + char product[64]; // Product name + char name[256]; // Product long name + char version[32]; // Product version + int vernumber; // Version number + int num_depends; // Number of dependencies + gui_depend_t *depends; // Dependencies + int rootsize, // Size of root partition files in kbytes + usrsize; // Size of /usr partition files in kbytes + char *filename; // Name of package file +}; + +struct gui_intype_t //// Installation types +{ + char name[80]; // Type name + char label[80]; // Type label + int num_products; // Number of products to install (0 = select) + int products[200]; // Products to install + int size; // Size of products in kbytes +}; + + +// +// Define a C API function type for comparisons... +// + +extern "C" { +typedef int (*compare_func_t)(const void *, const void *); +} + + +// +// Globals... +// + +#ifdef _DEFINE_GLOBALS_ +# define VAR +#else +# define VAR extern +#endif // _DEFINE_GLOBALS_ + +VAR int NumDists; // Number of distributions in directory +VAR gui_dist_t *Dists; // Distributions in directory +VAR int NumInstalled; // Number of distributions installed +VAR gui_dist_t *Installed; // Distributions installed +VAR int NumInstTypes; // Number of installation types +VAR gui_intype_t InstTypes[8]; // Installation types + + +// +// Prototypes... +// + +void gui_add_depend(gui_dist_t *d, int type, const char *name, + int lowver, int hiver); +gui_dist_t *gui_add_dist(int *num_d, gui_dist_t **d); +gui_dist_t *gui_find_dist(const char *name, int num_d, gui_dist_t *d); +void gui_get_installed(void); +void gui_load_file(Fl_Help_View *hv, const char *filename); +int gui_sort_dists(const gui_dist_t *d0, const gui_dist_t *d1); + + +// +// End of "$Id: gui-common.h 733 2006-11-30 21:59:27Z mike $". +// @@ -0,0 +1,706 @@ +/* + * "$Id: inst.c 670 2006-04-05 15:08:08Z mike $" + * + * IRIX package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2006 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_inst() - Make an IRIX software distribution package. + * inst_subsys() - Write a subsystem definition for the product. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +void inst_subsys(FILE *fp, const char *prodname, dist_t *dist, + const char *subpackage, const char *category, + const char *section); + + +/* + * 'make_inst()' - Make an IRIX software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_inst(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec/IDB/script file */ + tarf_t *tarfile; /* .tardist file */ + char name[1024]; /* Full product name */ + char specname[1024]; /* Spec filename */ + char idbname[1024]; /* IDB filename */ + char filename[1024], /* Destination filename */ + srcname[1024], /* Name of source file in distribution */ + dstname[1024]; /* Name of destination file in distribution */ + char preinstall[1024], /* Pre install script */ + postinstall[1024], /* Post install script */ + preremove[1024], /* Pre remove script */ + postremove[1024]; /* Post remove script */ + char subsys[255]; /* Subsystem name */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + struct stat fileinfo; /* File information */ + const char *runlevels; /* Run levels */ + static const char *extensions[] = /* INST file extensions */ + { + "", + ".idb", + ".man", + ".sw" + }; + + + REF(platform); + + if (Verbosity) + puts("Creating inst distribution..."); + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodname, dist->version, dist->release, + platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + /* + * Write the spec file for gendist... + */ + + if (Verbosity) + puts("Creating spec file..."); + + snprintf(specname, sizeof(specname), "%s/spec", directory); + + if ((fp = fopen(specname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create spec file \"%s\" - %s\n", specname, + strerror(errno)); + return (1); + } + + fprintf(fp, "product %s\n", prodname); + qprintf(fp, " id \"%s, %s\"\n", dist->product, dist->version); + + fputs(" image sw\n", fp); + qprintf(fp, " id \"%s, Software, %s\"\n", dist->product, + dist->version); + fprintf(fp, " version %d\n", dist->vernumber); + + inst_subsys(fp, prodname, dist, NULL, "Software", "sw"); + for (i = 0; i < dist->num_subpackages; i ++) + inst_subsys(fp, prodname, dist, dist->subpackages[i], "Software", "sw"); + + fputs(" endimage\n", fp); + + fputs(" image man\n", fp); + qprintf(fp, " id \"%s, Man Pages, %s\"\n", dist->product, + dist->version); + fprintf(fp, " version %d\n", dist->vernumber); + + inst_subsys(fp, prodname, dist, NULL, "Man Pages", "man"); + for (i = 0; i < dist->num_subpackages; i ++) + inst_subsys(fp, prodname, dist, dist->subpackages[i], "Man Pages", "man"); + + fputs(" endimage\n", fp); + + fputs("endproduct\n", fp); + + fclose(fp); + + /* + * Add symlinks for init scripts... + */ + + for (i = 0; i < dist->num_files; i ++) + if (tolower(dist->files[i].type) == 'i') + { + /* + * Make symlinks for all of the selected run levels... + */ + + for (runlevels = get_runlevels(dist->files + i, "02"); + isdigit(*runlevels & 255); + runlevels ++) + { + file = add_file(dist, dist->files[i].subpackage); + file->type = 'l'; + file->mode = 0; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "../init.d/%s", + dist->files[i].dst); + + if (*runlevels == '0') + snprintf(file->dst, sizeof(file->dst), "/etc/rc0.d/K%02d%s", + get_stop(dist->files + i, 0), dist->files[i].dst); + else + snprintf(file->dst, sizeof(file->dst), "/etc/rc%c.d/S%02d%s", + *runlevels, get_start(dist->files + i, 99), + dist->files[i].dst); + } + + /* + * Then send the original file to /etc/init.d... + */ + + file = dist->files + i; + + snprintf(filename, sizeof(filename), "/etc/init.d/%s", file->dst); + strcpy(file->dst, filename); + } + + /* + * Add preinstall script as needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + break; + + if (i) + { + /* + * Add the preinstall script file to the list... + */ + + file = add_file(dist, NULL); + file->type = '1'; + file->mode = 0555; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "%s/%s.preinstall", directory, + prodname); + snprintf(file->dst, sizeof(file->dst), "%s/%s.preinstall", SoftwareDir, + prodname); + + /* + * Then create the install script... + */ + + if (Verbosity) + puts("Creating preinstall script..."); + + snprintf(preinstall, sizeof(preinstall), "%s/%s.preinstall", directory, prodname); + + if ((fp = fopen(preinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + preinstall[0] = '\0'; + + /* + * Add postinstall script as needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + break; + + if (i) + { + /* + * Add the postinstall script file to the list... + */ + + file = add_file(dist, NULL); + file->type = '2'; + file->mode = 0555; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "%s/%s.postinstall", directory, + prodname); + snprintf(file->dst, sizeof(file->dst), "%s/%s.postinstall", SoftwareDir, + prodname); + + /* + * Then create the install script... + */ + + if (Verbosity) + puts("Creating postinstall script..."); + + snprintf(postinstall, sizeof(postinstall), "%s/%s.postinstall", directory, prodname); + + if ((fp = fopen(postinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + postinstall[0] = '\0'; + + /* + * Add preremove script as needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + break; + + if (i) + { + /* + * Add the preremove script file to the list... + */ + + file = add_file(dist, NULL); + file->type = '3'; + file->mode = 0555; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "%s/%s.preremove", directory, + prodname); + snprintf(file->dst, sizeof(file->dst), "%s/%s.preremove", SoftwareDir, + prodname); + + /* + * Then create the install script... + */ + + if (Verbosity) + puts("Creating preremove script..."); + + snprintf(preremove, sizeof(preremove), "%s/%s.preremove", directory, prodname); + + if ((fp = fopen(preremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + fprintf(fp, "%s\n", c->command); + + qprintf(fp, "/bin/rm -f %s.copy\n", file->dst); + + fclose(fp); + } + else + preremove[0] = '\0'; + + /* + * Add postremove script as needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + break; + + if (i) + { + /* + * Add the postremove script file to the list... + */ + + file = add_file(dist, NULL); + file->type = '4'; + file->mode = 0555; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "%s/%s.postremove", directory, + prodname); + snprintf(file->dst, sizeof(file->dst), "%s/%s.postremove", SoftwareDir, + prodname); + + /* + * Then create the remove script... + */ + + if (Verbosity) + puts("Creating postremove script..."); + + snprintf(postremove, sizeof(postremove), "%s/%s.postremove", directory, prodname); + + if ((fp = fopen(postremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + fprintf(fp, "%s\n", c->command); + + qprintf(fp, "/bin/rm -f %s.copy\n", file->dst); + + fclose(fp); + } + else + postremove[0] = '\0'; + + /* + * Sort the file list by the destination name, since gendist needs a sorted + * list... + */ + + sort_dist_files(dist); + + /* + * Write the idb file for gendist... + */ + + if (Verbosity) + puts("Creating idb file..."); + + snprintf(idbname, sizeof(idbname), "%s/idb", directory); + + if ((fp = fopen(idbname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create idb file \"%s\" - %s\n", idbname, + strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + if (strstr(file->dst, "/man/") != NULL || + strstr(file->dst, "/catman/") != NULL) + snprintf(subsys, sizeof(subsys), "%s.man.%s", prodname, + file->subpackage ? file->subpackage : "eoe"); + else + snprintf(subsys, sizeof(subsys), "%s.sw.%s", prodname, + file->subpackage ? file->subpackage : "eoe"); + + switch (tolower(file->type)) + { + case '1' : + qprintf(fp, "f %04o %s %s %s %s %s postop($rbase/%s)\n", file->mode, + file->user, file->group, file->dst + 1, file->src, subsys, + file->dst + 1); + break; + case '2' : + qprintf(fp, "f %04o %s %s %s %s %s exitop($rbase/%s)\n", file->mode, + file->user, file->group, file->dst + 1, file->src, subsys, + file->dst + 1); + break; + case '3' : + case '4' : + qprintf(fp, "f %04o %s %s %s %s %s " + "postop(cp $rbase/%s $rbase/%s.copy) " + "removeop($rbase/%s.copy; rm -f $rbase/%s.copy)\n", + file->mode, file->user, file->group, file->dst + 1, + file->src, subsys, file->dst + 1, file->dst + 1, + file->dst + 1); + break; + case 'c' : + qprintf(fp, "f %04o %s %s %s %s %s config(suggest)\n", file->mode, + file->user, file->group, file->dst + 1, file->src, subsys); + break; + case 'd' : + qprintf(fp, "d %04o %s %s %s - %s\n", file->mode, + file->user, file->group, file->dst + 1, subsys); + break; + case 'f' : + qprintf(fp, "f %04o %s %s %s %s %s\n", file->mode, + file->user, file->group, file->dst + 1, file->src, subsys); + break; + case 'i' : + qprintf(fp, "f %04o %s %s %s %s %s " + "postop(cp $rbase/etc/init.d/%s $rbase/etc/init.d/%s.copy) " + "exitop($rbase/etc/init.d/%s start) " + "removeop($rbase/etc/init.d/%s.copy stop; rm -f $rbase/etc/init.d/%s.copy)\n", + file->mode, file->user, file->group, file->dst + 1, + file->src, subsys, + file->dst + 12, file->dst + 12, + file->dst + 12, + file->dst + 12, file->dst + 12); + break; + case 'l' : + qprintf(fp, "l %04o %s %s %s - %s symval(%s)\n", file->mode, + file->user, file->group, file->dst + 1, subsys, file->src); + break; + } + } + + fclose(fp); + + /* + * Build the distribution from the spec file... + */ + + if (Verbosity) + puts("Building INST binary distribution..."); + + if (run_command(NULL, "gendist %s -dist %s -sbase . -idb %s -spec %s", + Verbosity == 0 ? "" : "-v", directory, idbname, specname)) + return (1); + + /* + * Build the tardist file... + */ + + if (Verbosity) + printf("Writing tardist file:"); + + snprintf(filename, sizeof(filename), "%s/%s.tardist", directory, name); + if ((tarfile = tar_open(filename, 0)) == NULL) + { + if (Verbosity) + puts(""); + + fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = 0; i < 4; i ++) + { + snprintf(srcname, sizeof(srcname), "%s/%s%s", directory, prodname, extensions[i]); + snprintf(dstname, sizeof(dstname), "%s%s", prodname, extensions[i]); + + stat(srcname, &fileinfo); + if (tar_header(tarfile, TAR_NORMAL, fileinfo.st_mode, fileinfo.st_size, + fileinfo.st_mtime, "root", "sys", dstname, NULL) < 0) + { + if (Verbosity) + puts(""); + + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + return (-1); + } + + if (tar_file(tarfile, srcname) < 0) + { + if (Verbosity) + puts(""); + + fprintf(stderr, "epm: Error writing file data for %s -\n %s\n", + dstname, strerror(errno)); + return (-1); + } + + if (Verbosity) + { + printf(" %s%s", prodname, extensions[i]); + fflush(stdout); + } + } + + tar_close(tarfile); + + if (Verbosity) + { + stat(filename, &fileinfo); + if (fileinfo.st_size > (1024 * 1024)) + printf(" size=%.1fM\n", fileinfo.st_size / 1024.0 / 1024.0); + else + printf(" size=%.0fk\n", fileinfo.st_size / 1024.0); + } + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + if (preinstall[0]) + unlink(preinstall); + if (postinstall[0]) + unlink(postinstall); + if (preremove[0]) + unlink(preremove); + if (postremove[0]) + unlink(postremove); + + unlink(idbname); + unlink(specname); + } + + return (0); +} + + +/* + * 'inst_subsys()' - Write a subsystem definition for the product. + */ + +void +inst_subsys(FILE *fp, /* I - File to write to */ + const char *prodname, /* I - Product short name */ + dist_t *dist, /* I - Distribution */ + const char *subpackage, /* I - Subpackage name or NULL */ + const char *category, /* I - "Software" or "Man Pages" */ + const char *section) /* I - "sw" or "man" */ +{ + int i; /* Looping var */ + depend_t *d; /* Current dependency */ + const char *product; /* Product for dependency */ + char selfname[1024]; /* Self product name */ + char title[1024]; /* Product description/title */ + + + snprintf(selfname, sizeof(selfname), "%s.%s.eoe", prodname, section); + + if (subpackage) + { + fprintf(fp, " subsys %s\n", subpackage); + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + snprintf(title, sizeof(title), "%s %s", dist->product, + dist->descriptions[i].description); + else + strlcpy(title, dist->product, sizeof(title)); + } + else + { + fputs(" subsys eoe default\n", fp); + + strlcpy(title, dist->product, sizeof(title)); + } + + qprintf(fp, " id \"%s, %s, %s\"\n", title, category, + dist->version); + fprintf(fp, " exp \"%s.%s.%s\"\n", prodname, section, + subpackage ? subpackage : "eoe"); + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REQUIRES && d->subpackage == subpackage) + break; + + if (i) + { + fputs(" prereq\n", fp); + fputs(" (\n", fp); + for (; i > 0; i --, d ++) + if (d->type == DEPEND_REQUIRES && d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + product = selfname; + else + product = d->product; + + if (strchr(product, '.') != NULL) + fprintf(fp, " %s %d %d\n", + product, d->vernumber[0], d->vernumber[1]); + else if (product[0] != '/') + fprintf(fp, " %s.%s.* %d %d\n", + product, section, d->vernumber[0], d->vernumber[1]); + } + fputs(" )\n", fp); + } + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REPLACES && d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + product = selfname; + else + product = d->product; + + if (strchr(product, '.') != NULL) + { + fprintf(fp, " replaces %s %d %d\n", + product, d->vernumber[0], d->vernumber[1]); + fprintf(fp, " updates %s %d %d\n", + product, d->vernumber[0], d->vernumber[1]); + } + else if (product[0] != '/') + { + fprintf(fp, " replaces %s.%s.* %d %d\n", + product, section, d->vernumber[0], d->vernumber[1]); + fprintf(fp, " updates %s.%s.* %d %d\n", + product, section, d->vernumber[0], d->vernumber[1]); + } + } + else if (d->type == DEPEND_INCOMPAT && d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + product = selfname; + else + product = d->product; + + if (strchr(product, '.') != NULL) + fprintf(fp, " incompat %s %d %d\n", + product, d->vernumber[0], d->vernumber[1]); + else if (product[0] != '/') + fprintf(fp, " incompat %s.%s.* %d %d\n", + product, section, d->vernumber[0], d->vernumber[1]); + } + + fputs(" endsubsys\n", fp); +} + + +/* + * End of "$Id: inst.c 670 2006-04-05 15:08:08Z mike $". + */ diff --git a/macosx/setup.icns b/macosx/setup.icns Binary files differnew file mode 100644 index 0000000..a2fe965 --- /dev/null +++ b/macosx/setup.icns diff --git a/macosx/setup.info b/macosx/setup.info new file mode 100644 index 0000000..02ff08b --- /dev/null +++ b/macosx/setup.info @@ -0,0 +1 @@ +FLTKFltk diff --git a/macosx/setup.xcf.gz b/macosx/setup.xcf.gz Binary files differnew file mode 100644 index 0000000..593f39f --- /dev/null +++ b/macosx/setup.xcf.gz diff --git a/macosx/setup128.png b/macosx/setup128.png Binary files differnew file mode 100644 index 0000000..90f056d --- /dev/null +++ b/macosx/setup128.png diff --git a/macosx/setup16.png b/macosx/setup16.png Binary files differnew file mode 100644 index 0000000..2bbf043 --- /dev/null +++ b/macosx/setup16.png diff --git a/macosx/setup32.png b/macosx/setup32.png Binary files differnew file mode 100644 index 0000000..50178fa --- /dev/null +++ b/macosx/setup32.png diff --git a/macosx/setup48.png b/macosx/setup48.png Binary files differnew file mode 100644 index 0000000..4a5de8e --- /dev/null +++ b/macosx/setup48.png diff --git a/macosx/uninst.icns b/macosx/uninst.icns Binary files differnew file mode 100644 index 0000000..9eb7b8d --- /dev/null +++ b/macosx/uninst.icns diff --git a/macosx/uninst.info b/macosx/uninst.info new file mode 100644 index 0000000..02ff08b --- /dev/null +++ b/macosx/uninst.info @@ -0,0 +1 @@ +FLTKFltk diff --git a/macosx/uninst.xcf.gz b/macosx/uninst.xcf.gz Binary files differnew file mode 100644 index 0000000..93bf1a1 --- /dev/null +++ b/macosx/uninst.xcf.gz diff --git a/macosx/uninst128.png b/macosx/uninst128.png Binary files differnew file mode 100644 index 0000000..c45f13c --- /dev/null +++ b/macosx/uninst128.png diff --git a/macosx/uninst16.png b/macosx/uninst16.png Binary files differnew file mode 100644 index 0000000..a88f3c0 --- /dev/null +++ b/macosx/uninst16.png diff --git a/macosx/uninst32.png b/macosx/uninst32.png Binary files differnew file mode 100644 index 0000000..7c9775e --- /dev/null +++ b/macosx/uninst32.png diff --git a/macosx/uninst48.png b/macosx/uninst48.png Binary files differnew file mode 100644 index 0000000..5e46dda --- /dev/null +++ b/macosx/uninst48.png diff --git a/mkepmlist.c b/mkepmlist.c new file mode 100644 index 0000000..8c4dbd6 --- /dev/null +++ b/mkepmlist.c @@ -0,0 +1,625 @@ +/* + * "$Id: mkepmlist.c 611 2005-01-11 21:37:42Z mike $" + * + * List file generation utility for the ESP Package Manager (EPM). + * + * Copyright 2003-2005 by Easy Software Products + * Copyright 2003 Andreas Voegele + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * main() - Scan directories to produce a distribution list. + * get_group() - Get a group name for the given group ID. + * get_user() - Get a user name for the given user ID. + * hash_deinit() - Deinitialize a hash table. + * hash_id() - Generate a hash for a user or group ID. + * hash_init() - Initialize a hash table. + * hash_insert() - Insert a new entry in a hash table. + * hash_search() - Find a user or group ID in the hash table... + * info() - Show the EPM copyright and license. + * process_dir() - Process a directory... + * process_file() - Process a file... + * usage() - Show command-line usage instructions. + */ + +#include "epm.h" + + +/* + * Lookup hash table structure... + */ + +#define HASH_M 101 + +struct node +{ + unsigned id; /* User or group ID */ + char *name; /* User or group name */ +}; + + +/* + * Globals... + */ + +char *DefaultUser = NULL, /* Default user for entries */ + *DefaultGroup = NULL; /* Default group for entries */ +struct node Users[HASH_M]; /* Hash table for users */ +struct node Groups[HASH_M]; /* Hash table for groups */ + + +/* + * Functions... + */ + +char *get_group(gid_t gid); +char *get_user(uid_t uid); +void hash_deinit(struct node *a); +unsigned hash_id(unsigned id); +void hash_init(struct node *a); +char *hash_insert(struct node *a, unsigned id, + const char *name); +char *hash_search(struct node *a, unsigned id); +void info(void); +int process_dir(const char *srcpath, const char *dstpath); +int process_file(const char *src, const char *dstpath); +void usage(void); + + +/* + * 'main()' - Scan directories to produce a distribution list. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + const char *prefix, /* Installation prefix */ + *dstpath; /* Destination path */ + char dst[1024], /* Destination */ + *ptr; /* Pointer into filename */ + struct stat info; /* File information */ + + + /* + * Initialize the hash tables... + */ + + hash_init(Users); + hash_init(Groups); + + /* + * Loop through the command-line arguments, processing directories as + * needed... + */ + + prefix = NULL; + + for (i = 1; i < argc; i ++) + if (strcmp(argv[i], "-u") == 0) + { + /* + * -u username + */ + + i ++; + + if (i >= argc) + usage(); + + DefaultUser = argv[i]; + } + else if (strcmp(argv[i], "-g") == 0) + { + /* + * -g groupname + */ + + i ++; + + if (i >= argc) + usage(); + + DefaultGroup = argv[i]; + } + else if (strcmp(argv[i], "--prefix") == 0) + { + i ++; + + if (i >= argc) + usage(); + + prefix = argv[i]; + } + else if (argv[i][0] == '-') + { + /* + * Unknown option... + */ + + fprintf(stderr, "Unknown option \"%s\"!\n", argv[i]); + usage(); + } + else + { + /* + * Directory name... + */ + + if (prefix) + dstpath = prefix; + else + { + if (argv[i][0] == '/') + dstpath = argv[i]; + else + { + if (argv[i][0] == '.') + { + for (dstpath = argv[i]; *dstpath == '.';) + { + if (strncmp(dstpath, "./", 2) == 0) + dstpath += 2; + else if (strncmp(dstpath, "../", 3) == 0) + dstpath += 3; + else + break; + } + + if (strcmp(dstpath, ".") == 0) + dstpath = ""; + } + else + dstpath = argv[i]; + + if (dstpath[0]) + { + snprintf(dst, sizeof(dst), "/%s", dstpath); + dstpath = dst; + } + } + } + + if (!lstat(argv[i], &info)) + { + if (!S_ISDIR(info.st_mode)) + { + if (!prefix) + { + /* + * Remove trailing filename component from destination... + */ + + if (dstpath != dst) + { + strlcpy(dst, dstpath, sizeof(dst)); + dstpath = dst; + } + + if ((ptr = strrchr(dstpath, '/')) != NULL) + *ptr = '\0'; + } + + process_file(argv[i], dstpath); + } + else + process_dir(argv[i], dstpath); + } + } + + /* + * Free any memory we have left allocated... + */ + + hash_deinit(Users); + hash_deinit(Groups); + + return (0); +} + + +/* + * 'get_group()' - Get a group name for the given group ID. + */ + +char * /* O - Name of group or NULL */ +get_group(gid_t gid) /* I - Group ID */ +{ + char *name; /* Name of group */ + struct group *gr; /* Group entry for group */ + char buf[16]; /* Temporary string buffer for group numbers */ + + + /* + * Always return the default group if set... + */ + + if (DefaultGroup) + return (DefaultGroup); + + /* + * See if the group ID is already in the hash table... + */ + + if ((name = hash_search(Groups, gid)) != NULL) + return (name); + + /* + * Lookup the group ID in the password file... + */ + + setgrent(); + + if ((gr = getgrgid(gid)) != NULL) + name = gr->gr_name; + else + { + /* + * Unable to find group ID; just return the number... + */ + + sprintf(buf, "%u", (unsigned)gid); + name = buf; + } + + /* + * Add the name to the hash table and return it... + */ + + return (hash_insert(Groups, gid, name)); +} + + +/* + * 'get_user()' - Get a user name for the given user ID. + */ + +char * /* O - Name of user or NULL */ +get_user(uid_t uid) /* I - User ID */ +{ + char *name; /* Name of user */ + struct passwd *pw; /* Password entry for user */ + char buf[16]; /* Temporary string buffer for user numbers */ + + + /* + * Always return the default user if set... + */ + + if (DefaultUser) + return (DefaultUser); + + /* + * See if the user ID is already in the hash table... + */ + + if ((name = hash_search(Users, uid)) != NULL) + return (name); + + /* + * Lookup the user ID in the password file... + */ + + setpwent(); + + if ((pw = getpwuid(uid)) != NULL) + name = pw->pw_name; + else + { + /* + * Unable to find user ID; just return the number... + */ + + sprintf(buf, "%u", (unsigned)uid); + name = buf; + } + + /* + * Add the name to the hash table and return it... + */ + + return (hash_insert(Users, uid, name)); +} + + +/* + * 'hash_deinit()' - Deinitialize a hash table. + */ + +void +hash_deinit(struct node *a) /* I - Hash table */ +{ + unsigned h; /* Looping var */ + + + for (h = 0; h < HASH_M; h ++) + if (a[h].name) + { + free(a[h].name); + memset(a, 0, sizeof(struct node)); + } +} + + +/* + * 'hash_id()' - Generate a hash for a user or group ID. + */ + +unsigned /* O - Hash number */ +hash_id(unsigned id) /* I - User or group ID */ +{ + return (id % HASH_M); +} + + +/* + * 'hash_init()' - Initialize a hash table. + */ + +void +hash_init(struct node *a) /* I - Hash table to initialize */ +{ + /* + * Zero out the hash table... + */ + + memset(a, 0, HASH_M * sizeof(struct node)); +} + + +/* + * 'hash_insert()' - Insert a new entry in a hash table. + */ + +char * /* O - New user or group name or NULL */ +hash_insert(struct node *a, /* I - Hash table */ + unsigned id, /* I - User or group ID */ + const char *name) /* I - User or group name */ +{ + unsigned h, /* Current hash value */ + start; /* Starting hash value */ + + + for (h = start = hash_id(id); a[h].name;) + { + h = (h + 1) % HASH_M; + if (h == start) + return (NULL); + } + + a[h].id = id; + a[h].name = strdup(name); + + return (a[h].name); +} + + +/* + * 'hash_search()' - Find a user or group ID in the hash table... + */ + +char * /* O - User or group name, or NULL */ +hash_search(struct node *a, /* I - Hash table */ + unsigned id) /* I - User or group ID */ +{ + unsigned h, /* Current hash value */ + start; /* Starting hash value */ + + + for (h = start = hash_id(id); a[h].name;) + { + h = (h + 1) % HASH_M; + + if (a[h].id == id) + return (a[h].name); + + if (h == start) + break; + } + + return (NULL); +} + + +/* + * 'info()' - Show the EPM copyright and license. + */ + +void +info(void) +{ + puts(EPM_VERSION); + puts("Copyright 1999-2005 by Easy Software Products."); + puts(""); + puts("EPM is free software and comes with ABSOLUTELY NO WARRANTY; for details"); + puts("see the GNU General Public License in the file COPYING or at"); + puts("\"http://www.fsf.org/gpl.html\". Report all problems to \"epm@easysw.com\"."); + puts(""); +} + + +/* + * 'process_dir()' - Process a directory... + */ + +int /* O - 0 on success, -1 on error */ +process_dir(const char *srcpath,/* I - Source path */ + const char *dstpath)/* I - Destination path */ +{ + DIR *dir; /* Directory to read from */ + struct dirent *dent; /* Current directory entry */ + int srclen; /* Length of source path */ + char src[1024]; /* Temporary source path */ + + + /* + * Try opening the source directory... + */ + + if ((dir = opendir(srcpath)) == NULL) + { + fprintf(stderr, "mkepmlist: Unable to open directory \"%s\" - %s.\n", + srcpath, strerror(errno)); + + return (-1); + } + + /* + * Read from the directory... + */ + + srclen = strlen(srcpath); + + while ((dent = readdir(dir)) != NULL) + { + /* + * Skip "." and ".."... + */ + + if (strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) + continue; + + /* + * Process file... + */ + + if (srclen > 0 && srcpath[srclen - 1] == '/') + snprintf(src, sizeof(src), "%s%s", srcpath, dent->d_name); + else + snprintf(src, sizeof(src), "%s/%s", srcpath, dent->d_name); + + if (process_file(src, dstpath)) + { + closedir(dir); + return (-1); + } + } + + closedir(dir); + return (0); +} + + +/* + * 'process_file()' - Process a file... + */ + +int /* O - 0 on success, -1 on error */ +process_file(const char *src, /* I - Source path */ + const char *dstpath)/* I - Destination path */ +{ + const char *srcptr; /* Pointer into source path */ + struct stat srcinfo; /* Information on the source file */ + int linklen, /* Length of link path */ + dstlen; /* Length of destination path */ + char link[1024], /* Link for source */ + dst[1024]; /* Temporary destination path */ + + + /* + * Get source file info... + */ + + dstlen = strlen(dstpath); + + if ((srcptr = strrchr(src, '/')) != NULL) + srcptr ++; + else + srcptr = src; + + if (dstlen > 0 && dstpath[dstlen - 1] == '/') + snprintf(dst, sizeof(dst), "%s%s", dstpath, srcptr); + else + snprintf(dst, sizeof(dst), "%s/%s", dstpath, srcptr); + + if (lstat(src, &srcinfo)) + { + fprintf(stderr, "mkepmlist: Unable to stat \"%s\" - %s.\n", src, + strerror(errno)); + return (-1); + } + + /* + * Process accordingly... + */ + + if (S_ISDIR(srcinfo.st_mode)) + { + /* + * Directory... + */ + + qprintf(stdout, "d %o %s %s %s -\n", (unsigned)(srcinfo.st_mode & 07777), + get_user(srcinfo.st_uid), get_group(srcinfo.st_gid), dst); + + if (process_dir(src, dst)) + return (-1); + } + else if (S_ISLNK(srcinfo.st_mode)) + { + /* + * Symlink... + */ + + if ((linklen = readlink(src, link, sizeof(link) - 1)) < 0) + { + fprintf(stderr, "mkepmlist: Unable to read symlink \"%s\" - %s.\n", + src, strerror(errno)); + return (-1); + } + + link[linklen] = '\0'; + + qprintf(stdout, "l %o %s %s %s %s\n", + (unsigned)(srcinfo.st_mode & 07777), get_user(srcinfo.st_uid), + get_group(srcinfo.st_gid), dst, link); + } + else if (S_ISREG(srcinfo.st_mode)) + { + /* + * Regular file... + */ + + qprintf(stdout, "f %o %s %s %s %s\n", + (unsigned)(srcinfo.st_mode & 07777), get_user(srcinfo.st_uid), + get_group(srcinfo.st_gid), dst, src); + } + + return (0); +} + + +/* + * 'usage()' - Show command-line usage instructions. + */ + +void +usage(void) +{ + info(); + + puts("Usage: mkepmlist [options] directory [... directory] >filename.list"); + puts("Options:"); + puts("-g group Set group name for files."); + puts("-u user Set user name for files."); + puts("--prefix directory Set directory prefix for files."); + + exit(1); +} + + +/* + * End of "$Id: mkepmlist.c 611 2005-01-11 21:37:42Z mike $". + */ @@ -0,0 +1,870 @@ +/* + * "$Id: osx.c 833 2010-12-30 00:00:50Z mike $" + * + * Mac OS X package gateway for the ESP Package Manager (EPM). + * + * Copyright 2002-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_osx() - Make a MacOS X software distribution package. + * make_subpackage() - Make a OSX subpackage. + * write_rtf() - Write an RTF welcome file. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local globals... + */ + +static const char * const pm_paths[] = /* Paths to PackageMaker program */ + { + "/Developer/Applications/PackageMaker.app", + "/Developer/Applications/Utilities/PackageMaker.app", + NULL + }; + + +/* + * Local functions... + */ + +static int make_subpackage(const char *prodname, const char *directory, + dist_t *dist, const char *subpackage, + const char *setup); +static int write_rtf(dist_t *dist, const char *title, + const char *subpackage, const char *welcome); + + +/* + * 'make_osx()' - Make a Red Hat software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_osx(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform, /* I - Platform information */ + const char *setup) /* I - Setup GUI image */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec file */ + char filename[1024]; /* Destination filename */ + char current[1024]; /* Current directory */ + const char *ext; /* Filename extension */ + + + REF(platname); + REF(platform); + + /* + * Create the main package and subpackages (if any)... + */ + + if (make_subpackage(prodname, directory, dist, NULL, setup)) + return (1); + + for (i = 0; i < dist->num_subpackages; i ++) + if (make_subpackage(prodname, directory, dist, dist->subpackages[i], setup)) + return (1); + + if (dist->num_subpackages) + { + /* + * Create a meta package for the whole shebang... + */ + + if (Verbosity) + puts("Creating MacOS X metapackage..."); + + getcwd(current, sizeof(current)); + + /* + * Copy the resources for the license, readme, and welcome (description) + * stuff... + */ + + if (Verbosity) + puts("Copying temporary resource files..."); + + snprintf(filename, sizeof(filename), "%s/MetaPackage", directory); + make_directory(filename, 0777, 0, 0); + + snprintf(filename, sizeof(filename), "%s/MetaResources", directory); + make_directory(filename, 0777, 0, 0); + + if (dist->license[0]) + { + if ((ext = strrchr(dist->license, '.')) == NULL || strcmp(ext, ".rtf")) + ext = ".txt"; + + snprintf(filename, sizeof(filename), "%s/MetaResources/License%s", + directory, ext); + copy_file(filename, dist->license, 0644, 0, 0); + } + + if (dist->readme[0]) + { + if ((ext = strrchr(dist->readme, '.')) == NULL || strcmp(ext, ".rtf")) + ext = ".txt"; + + snprintf(filename, sizeof(filename), "%s/MetaResources/ReadMe%s", + directory, ext); + copy_file(filename, dist->readme, 0644, 0, 0); + } + + if (setup && (ext = strrchr(setup, '.')) != NULL && + (!strcmp(ext, ".gif") || !strcmp(ext, ".jpg") || !strcmp(ext, ".tif"))) + { + snprintf(filename, sizeof(filename), "%s/MetaResources/background%s", + directory, ext); + copy_file(filename, setup, 0644, 0, 0); + } + + snprintf(filename, sizeof(filename), "%s/MetaResources/Welcome.rtf", + directory); + if (write_rtf(dist, dist->product, NULL, filename)) + return (1); + + snprintf(filename, sizeof(filename), "%s/%s-metadesc.plist", directory, + prodname); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create description file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); + fputs("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n", fp); + fputs("<plist version=\"1.0\">\n", fp); + fputs("<dict>\n", fp); + fputs(" <key>IFPkgDescriptionDeleteWarning</key>\n", fp); + fputs(" <string></string>\n", fp); + fputs(" <key>IFPkgDescriptionDescription</key>\n", fp); + fputs(" <string>", fp); + for (i = 0; i < dist->num_descriptions; i ++) + if (!dist->descriptions[i].subpackage) + fprintf(fp, "%s\n", dist->descriptions[i].description); + fputs("</string>\n", fp); + fputs(" <key>IFPkgDescriptionTitle</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->product); + fputs(" <key>IFPkgDescriptionVersion</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->version); + fputs("</dict>\n", fp); + fputs("</plist>\n", fp); + + fclose(fp); + + /* + * Do the info file for the packager... + */ + + snprintf(filename, sizeof(filename), "%s/%s-metainfo.plist", directory, + prodname); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create package information file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); + fputs("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n", fp); + fputs("<plist version=\"1.0\">\n", fp); + fputs("<dict>\n", fp); + fputs(" <key>IFPkgFormatVersion</key>\n", fp); + fputs(" <real>0.1</real>\n", fp); + fputs(" <key>IFPkgFlagAuthorizationAction</key>\n", fp); + fputs(" <string>RootAuthorization</string>\n", fp); + fputs(" <key>IFPkgFlagBackgroundAlignment</key>\n", fp); + fputs(" <string>bottomleft</string>\n", fp); + fputs(" <key>IFPkgFlagBackgroundScaling</key>\n", fp); + fputs(" <string>none</string>\n", fp); + fputs(" <key>IFPkgFlagAllowBackRev</key>\n", fp); + fputs(" <true/>\n", fp); + fputs(" <key>IFPkgFlagComponentDirectory</key>\n", fp); + fputs(" <string>Contents/Packages</string>\n", fp); + fputs(" <key>IFPkgFlagPackageList</key>\n", fp); + fputs(" <array>\n", fp); + fputs(" <dict>\n", fp); + fputs(" <key>IFPkgFlagPackageLocation</key>\n", fp); + fprintf(fp, " <string>%s.pkg</string>\n", prodname); + fputs(" <key>IFPkgFlagPackageSelection</key>\n", fp); + fputs(" <string>selected</string>\n", fp); + fputs(" </dict>\n", fp); + for (i = 0; i < dist->num_subpackages; i ++) + { + fputs(" <dict>\n", fp); + fputs(" <key>IFPkgFlagPackageLocation</key>\n", fp); + fprintf(fp, " <string>%s-%s.pkg</string>\n", + prodname, dist->subpackages[i]); + fputs(" <key>IFPkgFlagPackageSelection</key>\n", fp); + fputs(" <string>selected</string>\n", fp); + fputs(" </dict>\n", fp); + } + fputs(" </array>\n", fp); + fputs(" <key>CFBundleIdentifier</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", prodname); + fputs(" <key>CFBundleName</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->product); + fputs(" <key>CFBundleGetInfoString</key>\n", fp); + fprintf(fp, " <string>%s %s</string>\n", dist->product, dist->version); + fputs(" <key>CFBundleShortVersionString</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->version); + fputs("</dict>\n", fp); + fputs("</plist>\n", fp); + + fclose(fp); + + /* + * Build the distribution... + */ + + if (Verbosity) + puts("Building OSX package..."); + + if (directory[0] == '/') + strlcpy(filename, directory, sizeof(filename)); + else + snprintf(filename, sizeof(filename), "%s/%s", current, directory); + + for (i = 0; pm_paths[i]; i ++) + if (!access(pm_paths[i], 0)) + break; + + if (pm_paths[i]) + run_command(NULL, "%s/Contents/MacOS/PackageMaker -build " + "-p %s/%s.mpkg " +// "-mi %s/Packages " + "-f %s/MetaPackage " + "-r %s/MetaResources " + "-d %s/%s-metadesc.plist " + "-i %s/%s-metainfo.plist", + pm_paths[i], + filename, prodname, +// filename, + filename, + filename, + filename, prodname, + filename, prodname); + else + { + fputs("epm: Unable to find \"PackageMaker\" program!\n", stderr); + return (1); + } + + snprintf(filename, sizeof(filename), "%s/%s.mpkg", directory, prodname); + if (access(filename, 0)) + return (1); + + /* + * Move subpackages into the .mpkg directory... + */ + + run_command(directory, "/bin/mv Packages %s.mpkg/Contents", prodname); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/MetaPackage", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/MetaResources", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/%s-metadesc.plist", directory, + prodname); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s-metainfo.plist", directory, + prodname); + unlink(filename); + } + } + + /* + * Create a disk image of the package... + */ + + if (Verbosity) + puts("Creating disk image..."); + + if (dist->release[0]) + snprintf(filename, sizeof(filename), "%s-%s-%s", prodname, dist->version, + dist->release); + else + snprintf(filename, sizeof(filename), "%s-%s", prodname, dist->version); + + if (platname[0]) + { + strlcat(filename, "-", sizeof(filename)); + strlcat(filename, platname, sizeof(filename)); + } + + if (run_command(NULL, "hdiutil create -ov -srcfolder %s/%s.%s %s/%s.dmg", + directory, prodname, dist->num_subpackages ? "mpkg" : "pkg", + directory, filename)) + { + fputs("epm: Unable to create disk image!\n", stderr); + return (1); + } + + return (0); +} + + +/* + * 'make_subpackage()' - Make an OSX subpackage. + */ + +static int +make_subpackage(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + dist_t *dist, /* I - Distribution information */ + const char *subpackage, /* I - Subpackage */ + const char *setup) /* I - Setup GUI image */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec file */ + char prodfull[1024], /* Full product name */ + title[1024], /* Software title */ + filename[1024], /* Destination filename */ + pkgdir[1024], /* Package directory */ + pkgname[1024]; /* Package name */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + char current[1024]; /* Current directory */ + const char *option; /* Init script option */ + const char *ext; /* Filename extension */ + + + if (subpackage) + { + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + snprintf(title, sizeof(title), "%s - %s", dist->product, + dist->descriptions[i].description); + else + strlcpy(title, dist->product, sizeof(title)); + } + else + { + strlcpy(prodfull, prodname, sizeof(prodfull)); + strlcpy(title, dist->product, sizeof(title)); + } + + if (Verbosity) + printf("Creating %s MacOS X package...\n", prodfull); + + getcwd(current, sizeof(current)); + + /* + * Copy the resources for the license, readme, and welcome (description) + * stuff... + */ + + if (Verbosity) + puts("Copying temporary resource files..."); + + snprintf(filename, sizeof(filename), "%s/%s/Resources", directory, prodfull); + make_directory(filename, 0777, 0, 0); + + if (dist->license[0]) + { + if ((ext = strrchr(dist->license, '.')) == NULL || strcmp(ext, ".rtf")) + ext = ".txt"; + + snprintf(filename, sizeof(filename), "%s/%s/Resources/License%s", + directory, prodfull, ext); + copy_file(filename, dist->license, 0644, 0, 0); + } + + if (dist->readme[0]) + { + if ((ext = strrchr(dist->readme, '.')) == NULL || strcmp(ext, ".rtf")) + ext = ".txt"; + + snprintf(filename, sizeof(filename), "%s/%s/Resources/ReadMe%s", + directory, prodfull, ext); + copy_file(filename, dist->readme, 0644, 0, 0); + } + + if (setup && (ext = strrchr(setup, '.')) != NULL && + (!strcmp(ext, ".gif") || !strcmp(ext, ".jpg") || !strcmp(ext, ".tif"))) + { + snprintf(filename, sizeof(filename), "%s/%s/Resources/background%s", + directory, prodfull, ext); + copy_file(filename, setup, 0644, 0, 0); + } + + snprintf(filename, sizeof(filename), "%s/%s/Resources/Welcome.rtf", + directory, prodfull); + if (write_rtf(dist, title, subpackage, filename)) + return (1); + + snprintf(filename, sizeof(filename), "%s/%s-desc.plist", directory, prodfull); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create description file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); + fputs("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n", fp); + fputs("<plist version=\"1.0\">\n", fp); + fputs("<dict>\n", fp); + fputs(" <key>IFPkgDescriptionDeleteWarning</key>\n", fp); + fputs(" <string></string>\n", fp); + fputs(" <key>IFPkgDescriptionDescription</key>\n", fp); + fputs(" <string>", fp); + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + fprintf(fp, "%s\n", dist->descriptions[i].description); + fputs("</string>\n", fp); + fputs(" <key>IFPkgDescriptionTitle</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", title); + fputs(" <key>IFPkgDescriptionVersion</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->version); + fputs("</dict>\n", fp); + fputs("</plist>\n", fp); + + fclose(fp); + + /* + * Do the info file for the packager... + */ + + snprintf(filename, sizeof(filename), "%s/%s-info.plist", directory, prodfull); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create package information file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); + fputs("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n", fp); + fputs("<plist version=\"1.0\">\n", fp); + fputs("<dict>\n", fp); + fputs(" <key>IFPkgFormatVersion</key>\n", fp); + fputs(" <real>0.1</real>\n", fp); + fputs(" <key>IFPkgFlagAuthorizationAction</key>\n", fp); + fputs(" <string>RootAuthorization</string>\n", fp); + if (dist->num_subpackages && !subpackage) + { + fputs(" <key>IFPkgFlagIsRequired</key>\n", fp); + fputs(" <true/>\n", fp); + } + fputs(" <key>IFPkgFlagAllowBackRev</key>\n", fp); + fputs(" <true/>\n", fp); + fputs(" <key>IFPkgFlagBackgroundAlignment</key>\n", fp); + fputs(" <string>bottomleft</string>\n", fp); + fputs(" <key>IFPkgFlagBackgroundScaling</key>\n", fp); + fputs(" <string>none</string>\n", fp); + fputs(" <key>CFBundleIdentifier</key>\n", fp); + fprintf(fp, " <string>%s.%s</string>\n", prodname, + subpackage ? subpackage : "base"); + fputs(" <key>CFBundleName</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", title); + fputs(" <key>CFBundleGetInfoString</key>\n", fp); + fprintf(fp, " <string>%s %s</string>\n", title, dist->version); + fputs(" <key>CFBundleShortVersionString</key>\n", fp); + fprintf(fp, " <string>%s</string>\n", dist->version); + fputs("</dict>\n", fp); + fputs("</plist>\n", fp); + + fclose(fp); + + /* + * Do pre/post install commands... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + break; + + if (i) + { + snprintf(filename, sizeof(filename), "%s/%s/Resources/preflight", + directory, prodfull); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create preinstall script \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("#!/bin/sh\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + chmod(filename, 0755); + } + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + break; + + if (!i) + { + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + } + + if (i) + { + snprintf(filename, sizeof(filename), "%s/%s/Resources/postflight", + directory, prodfull); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create postinstall script \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("#!/bin/sh\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(fp, "/Library/StartupItems/%s/%s start\n", + file->dst, file->dst); + + fclose(fp); + chmod(filename, 0755); + } + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + /* + * Only add files in this subpackage... + */ + + if (file->subpackage != subpackage) + continue; + + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + if (strncmp(file->dst, "/etc/", 5) == 0) + snprintf(filename, sizeof(filename), "%s/%s/Package/private%s", + directory, prodfull, file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/Package%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + case 'i' : + snprintf(filename, sizeof(filename), + "%s/%s/Package/Library/StartupItems/%s/%s", + directory, prodfull, file->dst, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + + snprintf(filename, sizeof(filename), + "%s/%s/Package/Library/StartupItems/%s/StartupParameters.plist", + directory, prodfull, file->dst); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create init data file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("{\n", fp); + fprintf(fp, " Description = \"%s\";\n", dist->product); + qprintf(fp, " Provides = (%s);\n", + get_option(file, "provides", file->dst)); + if ((option = get_option(file, "requires", NULL)) != NULL) + qprintf(fp, " Requires = (%s);\n", option); + if ((option = get_option(file, "uses", NULL)) != NULL) + qprintf(fp, " Uses = (%s);\n", option); + if ((option = get_option(file, "order", NULL)) != NULL) + qprintf(fp, " OrderPreference = \"%s\";\n", option); + fputs("}\n", fp); + + fclose(fp); + + snprintf(filename, sizeof(filename), + "%s/%s/Package/Library/StartupItems/%s/Resources/English.lproj", + directory, prodfull, file->dst); + make_directory(filename, 0777, 0, 0); + + snprintf(filename, sizeof(filename), + "%s/%s/Package/Library/StartupItems/%s/Resources/English.lproj/Localizable.strings", + directory, prodfull, file->dst); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create init strings file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp); + fputs("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n", fp); + fputs("<plist version=\"0.9\">\n", fp); + fputs("<dict>\n", fp); + fprintf(fp, " <key>Starting %s</key>\n", dist->product); + fprintf(fp, " <string>Starting %s</string>\n", dist->product); + fputs("</dict>\n", fp); + fputs("</plist>\n", fp); + + fclose(fp); + break; + case 'd' : + if (strncmp(file->dst, "/etc/", 5) == 0 || + strcmp(file->dst, "/etc") == 0) + snprintf(filename, sizeof(filename), "%s/%s/Package/private%s", + directory, prodfull, file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/Package%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + case 'l' : + if (strncmp(file->dst, "/etc/", 5) == 0) + snprintf(filename, sizeof(filename), "%s/%s/Package/private%s", + directory, prodfull, file->dst); + else + snprintf(filename, sizeof(filename), "%s/%s/Package%s", + directory, prodfull, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution... + */ + + if (Verbosity) + puts("Building OSX package..."); + + if (directory[0] == '/') + strlcpy(filename, directory, sizeof(filename)); + else + snprintf(filename, sizeof(filename), "%s/%s", current, directory); + + if (dist->num_subpackages) + { + /* + * Place the individual packages in the "Packages" subdirectory; + * a metapackage will handle the whole shebang... + */ + + snprintf(pkgdir, sizeof(pkgdir), "%s/Packages", filename); + make_directory(pkgdir, 0777, 0, 0); + + snprintf(pkgname, sizeof(pkgname), "%s/Packages/%s.pkg", filename, + prodfull); + } + else + { + /* + * The package stands alone - just put it in the output directory... + */ + + snprintf(pkgname, sizeof(pkgname), "%s/%s.pkg", filename, prodfull); + } + + for (i = 0; pm_paths[i]; i ++) + if (!access(pm_paths[i], 0)) + break; + + if (pm_paths[i]) + run_command(NULL, "%s/Contents/MacOS/PackageMaker -build " + "-p %s " + "-f %s/%s/Package " + "-r %s/%s/Resources " + "-d %s/%s-desc.plist " + "-i %s/%s-info.plist", + pm_paths[i], + pkgname, + filename, prodfull, + filename, prodfull, + filename, prodfull, + filename, prodfull); + else + { + fputs("epm: Unable to find \"PackageMaker\" program!\n", stderr); + return (1); + } + + /* + * Verify that the package was created... + */ + + if (access(pkgname, 0)) + return (1); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodfull); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/%s-desc.plist", directory, + prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s-info.plist", directory, + prodfull); + unlink(filename); + } + + return (0); +} + + +/* + * 'write_rtf()' - Write an RTF welcome file. + */ + +static int /* O - 0 on success, 1 on failure */ +write_rtf(dist_t *dist, /* I - Distribution information */ + const char *title, /* I - Title of package */ + const char *subpackage, /* I - Subpackage */ + const char *welcome) /* I - Welcome file */ +{ + int i; /* Looping var */ + FILE *fp; /* Welcome file */ + int newpar; /* New paragraph needed */ + const char *desc; /* Description text */ + + + if ((fp = fopen(welcome, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create welcome file \"%s\" - %s\n", + welcome, strerror(errno)); + return (1); + } + + fputs("{\\rtf\n", fp); + fprintf(fp, "\\par %s version %s\n", title, dist->version); + fprintf(fp, "\\par Copyright %s\n", dist->copyright); + + for (i = 0, newpar = 1; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + { + for (desc = dist->descriptions[i].description; *desc; desc ++) + { + if (newpar) + { + fputs("\\par ", fp); + newpar = 0; + } + + if (*desc == '\\') + fputs("\\\\", fp); + else + { + putc(*desc, fp); + + if (*desc == '\n' && desc[1] == '\n') + { + newpar = 1; + desc ++; + } + } + } + } + else + newpar = 1; + + fputs("}\n", fp); + + fclose(fp); + + return (0); +} + +/* + * End of "$Id: osx.c 833 2010-12-30 00:00:50Z mike $". + */ @@ -0,0 +1,595 @@ +/* + * "$Id: pkg.c 833 2010-12-30 00:00:50Z mike $" + * + * AT&T package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_pkg() - Make an AT&T software distribution package. + * pkg_path() - Return an absolute path for the prototype file. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static const char *pkg_path(const char *filename, const char *dirname); + + +/* + * 'make_pkg()' - Make an AT&T software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_pkg(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i; /* Looping var */ + FILE *fp; /* Control file */ + char name[1024]; /* Full product name */ + char filename[1024], /* Destination filename */ + preinstall[1024], /* Pre install script */ + postinstall[1024], /* Post install script */ + preremove[1024], /* Pre remove script */ + postremove[1024], /* Post remove script */ + request[1024]; /* Request script */ + char current[1024]; /* Current directory */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + depend_t *d; /* Current dependency */ + tarf_t *tarfile; /* Distribution file */ + time_t curtime; /* Current time info */ + struct tm *curdate; /* Current date info */ + const char *runlevels; /* Run levels */ + + + if (Verbosity) + puts("Creating PKG distribution..."); + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodname, dist->version, dist->release, + platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + getcwd(current, sizeof(current)); + + /* + * Write the pkginfo file for pkgmk... + */ + + if (Verbosity) + puts("Creating package information file..."); + + snprintf(filename, sizeof(filename), "%s/%s.pkginfo", directory, prodname); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create package information file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + curtime = time(NULL); + curdate = gmtime(&curtime); + + fprintf(fp, "PKG=%s\n", prodname); + fprintf(fp, "NAME=%s\n", dist->product); + fprintf(fp, "VERSION=%s\n", dist->version); + fprintf(fp, "VENDOR=%s\n", dist->vendor); + fprintf(fp, "PSTAMP=epm%04d%02d%02d%02d%02d%02d\n", + curdate->tm_year + 1900, curdate->tm_mon + 1, curdate->tm_mday, + curdate->tm_hour, curdate->tm_min, curdate->tm_sec); + + if (dist->num_descriptions > 0) + fprintf(fp, "DESC=%s\n", dist->descriptions[0].description); + + fputs("CATEGORY=application\n", fp); + fputs("CLASSES=none", fp); + for (i = 0; i < dist->num_subpackages; i ++) + fprintf(fp, " %s", dist->subpackages[i]); + putc('\n', fp); + + if (strcmp(platform->machine, "intel") == 0) + fputs("ARCH=i86pc\n", fp); + else + fputs("ARCH=sparc\n", fp); + + fclose(fp); + + /* + * Write the depend file for pkgmk... + */ + + if (Verbosity) + puts("Creating package dependency file..."); + + snprintf(filename, sizeof(filename), "%s/%s.depend", directory, prodname); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create package dependency file \"%s\" - %s\n", filename, + strerror(errno)); + return (1); + } + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (!strcmp(d->product, "_self")) + continue; + else if (d->type == DEPEND_REQUIRES) + fprintf(fp, "P %s\n", d->product); + else + fprintf(fp, "I %s\n", d->product); + + fclose(fp); + + /* + * Write the preinstall file for pkgmk... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + break; + + if (i) + { + /* + * Write the preinstall file for pkgmk... + */ + + if (Verbosity) + puts("Creating preinstall script..."); + + snprintf(preinstall, sizeof(preinstall), "%s/%s.preinstall", directory, + prodname); + + if ((fp = fopen(preinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + preinstall[0] = '\0'; + + /* + * Write the postinstall file for pkgmk... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + break; + + if (i) + { + /* + * Write the postinstall file for pkgmk... + */ + + if (Verbosity) + puts("Creating postinstall script..."); + + snprintf(postinstall, sizeof(postinstall), "%s/%s.postinstall", directory, + prodname); + + if ((fp = fopen(postinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "/etc/init.d/%s start\n", file->dst); + + fclose(fp); + } + else + postinstall[0] = '\0'; + + /* + * Write the preremove script... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + break; + + if (i) + { + /* + * Write the preremove file for pkgmk... + */ + + if (Verbosity) + puts("Creating preremove script..."); + + snprintf(preremove, sizeof(preremove), "%s/%s.preremove", directory, prodname); + + if ((fp = fopen(preremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "/etc/init.d/%s stop\n", file->dst); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + preremove[0] = '\0'; + + /* + * Write the postremove file for pkgmk... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + break; + + if (i) + { + /* + * Write the postremove file for pkgmk... + */ + + if (Verbosity) + puts("Creating postremove script..."); + + snprintf(postremove, sizeof(postremove), "%s/%s.postremove", directory, + prodname); + + if ((fp = fopen(postremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + postremove[0] = '\0'; + + /* + * Write the request file for pkgmk... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_LITERAL && !strcmp(c->section, "request")) + break; + + if (i) + { + /* + * Write the request file for pkgmk... + */ + + if (Verbosity) + puts("Creating request script..."); + + snprintf(request, sizeof(request), "%s/%s.request", directory, + prodname); + + if ((fp = fopen(request, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", + request, strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_LITERAL && !strcmp(c->section, "request")) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + request[0] = '\0'; + + /* + * Add symlinks for init scripts... + */ + + for (i = 0; i < dist->num_files; i ++) + if (tolower(dist->files[i].type) == 'i') + { + /* + * Make symlinks for all of the selected run levels... + */ + + for (runlevels = get_runlevels(dist->files + i, "023"); + isdigit(*runlevels & 255); + runlevels ++) + { + file = add_file(dist, dist->files[i].subpackage); + file->type = 'l'; + file->mode = 0; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "../init.d/%s", + dist->files[i].dst); + + if (*runlevels == '0') + snprintf(file->dst, sizeof(file->dst), "/etc/rc0.d/K%02d%s", + get_stop(dist->files + i, 0), dist->files[i].dst); + else + snprintf(file->dst, sizeof(file->dst), "/etc/rc%c.d/S%02d%s", + *runlevels, get_start(dist->files + i, 99), + dist->files[i].dst); + } + + /* + * Then send the original file to /etc/init.d... + */ + + file = dist->files + i; + + snprintf(filename, sizeof(filename), "/etc/init.d/%s", file->dst); + strcpy(file->dst, filename); + } + + /* + * Write the prototype file for pkgmk... + */ + + if (Verbosity) + puts("Creating prototype file..."); + + snprintf(filename, sizeof(filename), "%s/%s.prototype", directory, prodname); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create prototype file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + +#if 0 /* apparently does not work on Solaris 7... */ + fprintf(fp, "!search %s\n", current); +#endif /* 0 */ + + if (dist->license[0]) + fprintf(fp, "i copyright=%s\n", pkg_path(dist->license, current)); + fprintf(fp, "i depend=%s/%s.depend\n", pkg_path(directory, current), prodname); + fprintf(fp, "i pkginfo=%s/%s.pkginfo\n", pkg_path(directory, current), + prodname); + + if (preinstall[0]) + fprintf(fp, "i preinstall=%s\n", pkg_path(preinstall, current)); + if (postinstall[0]) + fprintf(fp, "i postinstall=%s\n", pkg_path(postinstall, current)); + if (preremove[0]) + fprintf(fp, "i preremove=%s\n", pkg_path(preremove, current)); + if (postremove[0]) + fprintf(fp, "i postremove=%s\n", pkg_path(postremove, current)); + if (request[0]) + fprintf(fp, "i request=%s\n", pkg_path(request, current)); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + switch (tolower(file->type)) + { + case 'c' : + qprintf(fp, "e %s %s=%s %04o %s %s\n", + file->subpackage ? file->subpackage : "none", + file->dst, pkg_path(file->src, current), + file->mode, file->user, file->group); + break; + case 'd' : + qprintf(fp, "d %s %s %04o %s %s\n", + file->subpackage ? file->subpackage : "none", + file->dst, file->mode, file->user, file->group); + break; + case 'f' : + case 'i' : + qprintf(fp, "f %s %s=%s %04o %s %s\n", + file->subpackage ? file->subpackage : "none", + file->dst, pkg_path(file->src, current), + file->mode, file->user, file->group); + break; + case 'l' : + qprintf(fp, "s %s %s=%s\n", + file->subpackage ? file->subpackage : "none", + file->dst, file->src); + break; + } + + fclose(fp); + + /* + * Build the distribution from the prototype file... + */ + + if (Verbosity) + puts("Building PKG binary distribution..."); + + if (run_command(NULL, "pkgmk -o -f %s/%s.prototype -d %s/%s", + directory, prodname, current, directory)) + return (1); + + /* + * Tar and compress the distribution... + */ + + if (Verbosity) + puts("Creating .pkg.tgz file for distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s.pkg.tgz", directory, name); + + if ((tarfile = tar_open(filename, 1)) == NULL) + return (1); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + + if (tar_directory(tarfile, filename, prodname)) + { + tar_close(tarfile); + return (1); + } + + tar_close(tarfile); + + /* + * Make a package stream file... + */ + + if (Verbosity) + puts("Copying into package stream file..."); + + if (run_command(directory, "pkgtrans -s %s/%s %s.pkg %s", + current, directory, name, prodname)) + return (1); + + /* + * Compress the package stream file... + */ + + snprintf(filename, sizeof(filename), "%s.pkg.gz", name); + unlink(filename); + + if (run_command(directory, EPM_GZIP " -vf9 %s.pkg", name)) + return (1); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/%s.pkginfo", directory, prodname); + unlink(filename); + snprintf(filename, sizeof(filename), "%s/%s.depend", directory, prodname); + unlink(filename); + snprintf(filename, sizeof(filename), "%s/%s.prototype", directory, prodname); + unlink(filename); + if (preinstall[0]) + unlink(preinstall); + if (postinstall[0]) + unlink(postinstall); + if (preremove[0]) + unlink(preremove); + if (postremove[0]) + unlink(postremove); + if (request[0]) + unlink(request); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + unlink_directory(filename); + } + + return (0); +} + + +/* + * 'pkg_path()' - Return an absolute path for the prototype file. + */ + +static const char * /* O - Absolute filename */ +pkg_path(const char *filename, /* I - Source filename */ + const char *dirname) /* I - Source directory */ +{ + static char absname[1024]; /* Absolute filename */ + + + if (filename[0] == '/') + return (filename); + + snprintf(absname, sizeof(absname), "%s/%s", dirname, filename); + return (absname); +} + + +/* + * End of "$Id: pkg.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/portable.c b/portable.c new file mode 100644 index 0000000..6fba96d --- /dev/null +++ b/portable.c @@ -0,0 +1,2965 @@ +/* + * "$Id: portable.c 833 2010-12-30 00:00:50Z mike $" + * + * Portable package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_portable() - Make a portable software distribution package. + * clean_distfiles() - Remove temporary software distribution files... + * write_combined() - Write all of the distribution files in tar files. + * write_commands() - Write commands. + * write_common() - Write the common shell script header. + * write_confcheck() - Write the echo check to find the right echo options. + * write_depends() - Write dependencies. + * write_distfiles() - Write a software distribution... + * write_install() - Write the installation script. + * write_instfiles() - Write the installer files to the tar file... + * write_patch() - Write the patch script. + * write_remove() - Write the removal script. + * write_space_checks() - Write disk space checks for the installer. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static void clean_distfiles(const char *directory, const char *prodname, + const char *platname, dist_t *dist, + const char *subpackage); +static int write_combined(const char *title, const char *directory, + const char *prodname, const char *platname, + dist_t *dist, const char **files, + time_t deftime, const char *setup, + const char *types); +static int write_commands(dist_t *dist, FILE *fp, int type, + const char *subpackage); +static FILE *write_common(dist_t *dist, const char *title, + int rootsize, int usrsize, + const char *filename, const char *subpackage); +static int write_confcheck(FILE *fp); +static int write_depends(const char *prodname, dist_t *dist, FILE *fp, + const char *subpackage); +static int write_distfiles(const char *directory, const char *prodname, + const char *platname, dist_t *dist, + time_t deftime, const char *subpackage); +static int write_install(dist_t *dist, const char *prodname, + int rootsize, int usrsize, + const char *directory, + const char *subpackage); +static int write_instfiles(tarf_t *tarfile, const char *directory, + const char *prodname, const char *platname, + const char **files, const char *destdir, + const char *subpackage); +static int write_patch(dist_t *dist, const char *prodname, + int rootsize, int usrsize, + const char *directory, + const char *subpackage); +static int write_remove(dist_t *dist, const char *prodname, + int rootsize, int usrsize, + const char *directory, + const char *subpackage); +static int write_space_checks(const char *prodname, FILE *fp, + const char *sw, const char *ss, + int rootsize, int usrsize); + + +/* + * 'make_portable()' - Make a portable software distribution package. + */ + +int /* O - 1 = success, 0 = fail */ +make_portable(const char *prodname, /* I - Product short name */ + const char *directory,/* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform, /* I - Platform information */ + const char *setup, /* I - Setup GUI image */ + const char *types) /* I - Setup GUI install types */ +{ + int i; /* Looping var */ + int havepatchfiles; /* 1 if we have patch files, 0 otherwise */ + time_t deftime; /* File creation time */ + file_t *file; /* Software file */ + static const char *distfiles[] = /* Distribution files */ + { + "install", + "license", + "readme", + "remove", + "ss", + "sw", + NULL + }; + static const char *patchfiles[] = /* Patch files */ + { + "patch", + "license", + "pss", + "psw", + "readme", + "remove", + NULL + }; + + + REF(platform); + + if (Verbosity) + puts("Creating PORTABLE distribution..."); + + /* + * See if we need to make a patch distribution... + */ + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (isupper((int)file->type)) + break; + + havepatchfiles = i > 0; + + deftime = time(NULL); + + /* + * Build the main package and all of the subpackages... + */ + + if (write_distfiles(directory, prodname, platname, dist, deftime, NULL)) + return (1); + + for (i = 0; i < dist->num_subpackages; i ++) + if (write_distfiles(directory, prodname, platname, dist, deftime, + dist->subpackages[i])) + return (1); + + /* + * Create the distribution archives... + */ + + if (write_combined("distribution", directory, prodname, platname, dist, + distfiles, deftime, setup, types)) + return (1); + + if (havepatchfiles) + if (write_combined("patch", directory, prodname, platname, dist, + patchfiles, deftime, setup, types)) + return (1); + + /* + * Cleanup... + */ + + if (!KeepFiles) + { + clean_distfiles(directory, prodname, platname, dist, NULL); + + for (i = 0; i < dist->num_subpackages; i ++) + clean_distfiles(directory, prodname, platname, dist, + dist->subpackages[i]); + } + + /* + * Return! + */ + + return (0); +} + + +/* + * 'clean_distfiles()' - Remove temporary software distribution files... + */ + +static void +clean_distfiles(const char *directory, /* I - Directory */ + const char *prodname, /* I - Product name */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution */ + const char *subpackage) /* I - Subpackage */ +{ + char prodfull[255], /* Full name of product */ + filename[1024]; /* Name of temporary file */ + + + /* + * Figure out the full name of the distribution... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + /* + * Remove the distribution files... + */ + + if (Verbosity) + printf("Removing %s temporary files...\n", prodfull); + + snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.ss", directory, prodfull); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.sw", directory, prodfull); + unlink(filename); +} + + +/* + * 'write_combined()' - Write all of the distribution files in tar files. + */ + +static int /* O - 0 on success, -1 on failure */ +write_combined(const char *title, /* I - Title */ + const char *directory, /* I - Output directory */ + const char *prodname, /* I - Base product name */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution */ + const char **files, /* I - Files */ + time_t deftime, /* I - Default timestamp */ + const char *setup, /* I - Setup program */ + const char *types) /* I - Setup types file */ +{ + int i; /* Looping var */ + tarf_t *tarfile; /* Distribution tar file */ + char tarfilename[1024], /* Name of tar file */ + filename[1024]; /* Name of temporary file */ +#ifdef __APPLE__ + FILE *fp; /* Plist file... */ +#endif /* __APPLE__ */ + struct stat srcstat; /* Source file information */ + const char *destdir; /* Destination directory */ + const char *setup_img; /* Setup image name */ + + + /* + * Figure out the filename... + */ + + if (dist->release[0]) + snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s-%s", directory, + prodname, dist->version, dist->release); + else + snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s", directory, prodname, + dist->version); + + if (!strcmp(title, "patch")) + strlcat(tarfilename, "-patch", sizeof(tarfilename)); + + if (platname[0]) + { + strlcat(tarfilename, "-", sizeof(tarfilename)); + strlcat(tarfilename, platname, sizeof(tarfilename)); + } + + strlcat(tarfilename, ".tar.gz", sizeof(tarfilename)); + + /* + * Open output file... + */ + + if ((tarfile = tar_open(tarfilename, 1)) == NULL) + { + fprintf(stderr, "epm: Unable to create output pipe to gzip -\n %s\n", + strerror(errno)); + return (-1); + } + + if (Verbosity) + printf("Writing %s archive:\n", title); + +#ifdef __APPLE__ + if (setup) + { + /* + * Create directories for the setup application... + */ + + if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", + "Install.app", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", + "Install.app/Contents", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", + "Install.app/Contents/MacOS", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", + "Install.app/Contents/Resources", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + /* + * Then copy the data files... + */ + + snprintf(filename, sizeof(filename), "%s/setup.icns", DataDir); + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Install.app/Contents/Resources/setup.icns", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + fprintf(stderr, "epm: Error writing file data for setup.icns -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk setup.icns\n", (srcstat.st_size + 1023) / 1024.0); + + snprintf(filename, sizeof(filename), "%s/setup.info", DataDir); + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Install.app/Contents/PkgInfo", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + fprintf(stderr, "epm: Error writing file data for PkgInfo -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk PkgInfo\n", (srcstat.st_size + 1023) / 1024.0); + + snprintf(filename, sizeof(filename), "%s/%s.setup.plist", directory, + prodname); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Error writing %s -\n %s\n", filename, + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<plist version=\"0.9\">\n" + " <dict>\n" + " <key>CFBundleInfoDictionaryVersion</key>\n" + " <string>6.0</string>\n" + " <key>CFBundleExecutable</key>\n" + " <string>setup</string>\n" + " <key>CFBundleIdentifier</key>\n" + " <string>com.easysw.epm.setup</string>\n" + " <key>CFBundleVersion</key>\n" + " <string>%s</string>\n" + " <key>CFBundleDevelopmentRegion</key>\n" + " <string>English</string>\n" + " <key>NSHumanReadableCopyright</key>\n" + " <string>Copyright %s</string>\n" + " <key>CFAppleHelpAnchor</key>\n" + " <string>help</string>\n" + " <key>CFBundleName</key>\n" + " <string>Installer for %s</string>\n" + " <key>CFBundlePackageType</key>\n" + " <string>APPL</string>\n" + " <key>CFBundleSignature</key>\n" + " <string>FLTK</string>\n" + " <key>CFBundleIconFile</key>\n" + " <string>setup.icns</string>\n" + " <key>CFBundleShortVersionString</key>\n" + " <string>%s</string>\n" + " <key>CFBundleGetInfoString</key>\n" + " <string>%s, Copyright %s</string>\n" + " </dict>\n" + "</plist>\n", + dist->version, + dist->copyright, + dist->product, + dist->version, + dist->version, dist->copyright); + fclose(fp); + + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Install.app/Contents/Info.plist", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + fprintf(stderr, "epm: Error writing file data for Info.plist -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (!KeepFiles) + unlink(filename); + + if (Verbosity) + printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0); + } + + destdir = "Install.app/Contents/Resources/"; + +#else /* !__APPLE__ */ + destdir = ""; +#endif /* __APPLE__ */ + + /* + * Write installer files... + */ + + if (write_instfiles(tarfile, directory, prodname, platname, files, destdir, + NULL)) + { + tar_close(tarfile); + return (-1); + } + + for (i = 0; i < dist->num_subpackages; i ++) + if (write_instfiles(tarfile, directory, prodname, platname, files, destdir, + dist->subpackages[i])) + { + tar_close(tarfile); + return (-1); + } + + /* + * Now the setup files... + */ + + if (setup) + { + /* + * Include the ESP Software Installation Wizard (setup)... + */ + + if (stat(SetupProgram, &srcstat)) + { + fprintf(stderr, "epm: Unable to stat GUI setup program %s - %s\n", + SetupProgram, strerror(errno)); + tar_close(tarfile); + return (-1); + } + +#ifdef __APPLE__ + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", + "Install.app/Contents/MacOS/setup", NULL) < 0) +#else + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", "setup", NULL) < 0) +#endif /* __APPLE__ */ + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, SetupProgram) < 0) + { + fprintf(stderr, "epm: Error writing file data for setup -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk setup\n", (srcstat.st_size + 1023) / 1024.0); + + /* + * And the image file... + */ + + stat(setup, &srcstat); + + if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".gif")) + setup_img = "setup.gif"; + else + setup_img = "setup.xpm"; + + snprintf(filename, sizeof(filename), "%s%s", destdir, setup_img); + + if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, + srcstat.st_mtime, "root", "root", filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, setup) < 0) + { + fprintf(stderr, "epm: Error writing file data for %s -\n %s\n", + setup_img, strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img); + + /* + * And the types file... + */ + + if (types) + { + stat(types, &srcstat); + snprintf(filename, sizeof(filename), "%ssetup.types", destdir); + + if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, + srcstat.st_mtime, "root", "root", filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, types) < 0) + { + fprintf(stderr, "epm: Error writing file data for setup.types -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk setup.types\n", (srcstat.st_size + 1023) / 1024.0); + } + + /* + * And finally the uninstall stuff... + */ + +#ifdef __APPLE__ + if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", + "Uninstall.app", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", + "Uninstall.app/Contents", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", + "Uninstall.app/Contents/MacOS", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", + "Uninstall.app/Contents/Resources", NULL) < 0) + { + fprintf(stderr, "epm: Error writing directory header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + /* + * Then copy the data files... + */ + + snprintf(filename, sizeof(filename), "%s/uninst.icns", DataDir); + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Uninstall.app/Contents/Resources/uninst.icns", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + fprintf(stderr, "epm: Error writing file data for uninst.icns -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk uninst.icns\n", (srcstat.st_size + 1023) / 1024.0); + + snprintf(filename, sizeof(filename), "%s/uninst.info", DataDir); + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Uninstall.app/Contents/PkgInfo", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + fprintf(stderr, "epm: Error writing file data for PkgInfo -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk PkgInfo\n", (srcstat.st_size + 1023) / 1024.0); + + snprintf(filename, sizeof(filename), "%s/%s.uninst.plist", directory, + prodname); + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Error writing %s -\n %s\n", filename, + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<plist version=\"0.9\">\n" + " <dict>\n" + " <key>CFBundleInfoDictionaryVersion</key>\n" + " <string>6.0</string>\n" + " <key>CFBundleExecutable</key>\n" + " <string>uninst</string>\n" + " <key>CFBundleIdentifier</key>\n" + " <string>com.easysw.epm.uninst</string>\n" + " <key>CFBundleVersion</key>\n" + " <string>%s</string>\n" + " <key>CFBundleDevelopmentRegion</key>\n" + " <string>English</string>\n" + " <key>NSHumanReadableCopyright</key>\n" + " <string>Copyright %s</string>\n" + " <key>CFAppleHelpAnchor</key>\n" + " <string>help</string>\n" + " <key>CFBundleName</key>\n" + " <string>Uninstaller for %s</string>\n" + " <key>CFBundlePackageType</key>\n" + " <string>APPL</string>\n" + " <key>CFBundleSignature</key>\n" + " <string>FLTK</string>\n" + " <key>CFBundleIconFile</key>\n" + " <string>uninst.icns</string>\n" + " <key>CFBundleShortVersionString</key>\n" + " <string>%s</string>\n" + " <key>CFBundleGetInfoString</key>\n" + " <string>%s, Copyright %s</string>\n" + " </dict>\n" + "</plist>\n", + dist->version, + dist->copyright, + dist->product, + dist->version, + dist->version, dist->copyright); + fclose(fp); + + stat(filename, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), + srcstat.st_size, srcstat.st_mtime, "root", "root", + "Uninstall.app/Contents/Info.plist", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, filename) < 0) + { + tar_close(tarfile); + fprintf(stderr, "epm: Error writing file data for Info.plist -\n %s\n", + strerror(errno)); + return (-1); + } + + if (!KeepFiles) + unlink(filename); + + if (Verbosity) + printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0); +#endif /* __APPLE__ */ + + /* + * Include the ESP Software Removal Wizard (uninst)... + */ + + if (stat(UninstProgram, &srcstat)) + { + fprintf(stderr, "epm: Unable to stat GUI uninstall program %s - %s\n", + UninstProgram, strerror(errno)); + tar_close(tarfile); + return (-1); + } + +#ifdef __APPLE__ + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", + "Uninstall.app/Contents/MacOS/uninst", NULL) < 0) +#else + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", "uninst", NULL) < 0) +#endif /* __APPLE__ */ + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, UninstProgram) < 0) + { + fprintf(stderr, "epm: Error writing file data for uninst -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk uninst\n", (srcstat.st_size + 1023) / 1024.0); + +#ifdef __APPLE__ + /* + * And the image file... + */ + + stat(setup, &srcstat); + + snprintf(filename, sizeof(filename), "Uninstall.app/Contents/Resources/%s", + setup_img); + + if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, + srcstat.st_mtime, "root", "root", filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, setup) < 0) + { + fprintf(stderr, "epm: Error writing file data for %s -\n %s\n", + setup_img, strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img); +#endif /* __APPLE__ */ + } + + if (Verbosity) + { + puts(" ------- ----------------------------------------"); + printf(" %7.0fk %s-%s", tarfile->blocks * 0.5f, prodname, dist->version); + if (dist->release[0]) + printf("-%s", dist->release); + if (!strcmp(title, "patch")) + fputs("-patch", stdout); + if (platname[0]) + printf("-%s", platname); + puts(".tar"); + } + + tar_close(tarfile); + + if (Verbosity) + { + stat(tarfilename, &srcstat); + + puts(" ------- ----------------------------------------"); + printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, + tarfilename); + } + +#ifdef __APPLE__ + { + char dmgfilename[1024]; /* Disk image filename */ + + + /* + * Make a disk image containing the package files... + */ + + if (dist->release[0]) + snprintf(filename, sizeof(filename), "%s/%s-%s-%s", directory, prodname, + dist->version, dist->release); + else + snprintf(filename, sizeof(filename), "%s/%s-%s", directory, prodname, + dist->version); + + if (!strcmp(title, "patch")) + strlcat(filename, "-patch", sizeof(filename)); + + if (platname[0]) + { + strlcat(filename, "-", sizeof(filename)); + strlcat(filename, platname, sizeof(filename)); + } + + snprintf(dmgfilename, sizeof(dmgfilename), "%s.dmg", filename); + + mkdir(filename, 0777); + + if (run_command(filename, "tar xvzf ../%s", strrchr(tarfilename, '/') + 1)) + { + fputs("epm: Unable to create disk image template folder!\n", stderr); + return (1); + } + + if (run_command(NULL, "hdiutil create -ov -srcfolder %s %s", + filename, dmgfilename)) + { + fputs("epm: Unable to create disk image!\n", stderr); + return (1); + } + + if (!KeepFiles) + unlink_directory(filename); + + if (Verbosity) + { + stat(dmgfilename, &srcstat); + + printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, + dmgfilename); + } + } +#endif /* __APPLE__ */ + + return (0); +} + + +/* + * 'write_commands()' - Write commands. + */ + +static int /* O - 0 on success, -1 on failure */ +write_commands(dist_t *dist, /* I - Distribution */ + FILE *fp, /* I - File pointer */ + int type, /* I - Type of commands to write */ + const char *subpackage) /* I - Subsystem */ +{ + int i; /* Looping var */ + command_t *c; /* Current command */ + static const char *commands[] = /* Command strings */ + { + "pre-install", + "post-install", + "pre-patch", + "post-patch", + "pre-remove", + "post-remove" + }; + + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == type && c->subpackage == subpackage) + break; + + if (i) + { + fprintf(fp, "echo Running %s commands...\n", commands[type]); + + for (; i > 0; i --, c ++) + if (c->type == type && c->subpackage == subpackage) + if (fprintf(fp, "%s\n", c->command) < 1) + { + perror("epm: Error writing command"); + return (-1); + } + } + + return (0); +} + + +/* + * 'write_common()' - Write the common shell script header. + */ + +static FILE * /* O - File pointer */ +write_common(dist_t *dist, /* I - Distribution */ + const char *title, /* I - "Installation", etc... */ + int rootsize, /* I - Size of root files in kbytes */ + int usrsize, /* I - Size of /usr files in kbytes */ + const char *filename, /* I - Script to create */ + const char *subpackage) /* I - Subpackage name */ +{ + int i; /* Looping var */ + FILE *fp; /* File pointer */ + char line[1024], /* Line buffer */ + *start, /* Start of line */ + *ptr; /* Pointer into line */ + + + /* + * Remove any existing copy of the file... + */ + + unlink(filename); + + /* + * Create the script file... + */ + + if ((fp = fopen(filename, "w")) == NULL) + return (NULL); + + /* + * Update the permissions on the file... + */ + + fchmod(fileno(fp), 0755); + + /* + * Write the standard header... + */ + + fputs("#!/bin/sh\n", fp); + fprintf(fp, "# %s script for %s version %s.\n", title, + dist->product, dist->version); + fputs("# Produced using " EPM_VERSION "; report problems to epm@easysw.com.\n", + fp); + fprintf(fp, "#%%product %s", dist->product); + if (subpackage) + { + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + { + strlcpy(line, dist->descriptions[i].description, sizeof(line)); + if ((ptr = strchr(line, '\n')) != NULL) + *ptr = '\0'; + + fprintf(fp, " - %s", line); + } + } + fputs("\n", fp); + fprintf(fp, "#%%vendor %s\n", dist->vendor); + fprintf(fp, "#%%copyright %s\n", dist->copyright); + fprintf(fp, "#%%version %s %d\n", dist->version, dist->vernumber); + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + { + /* + * Just do descriptions for this subpackage... + */ + + for (; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + { + strlcpy(line, dist->descriptions[i].description, sizeof(line)); + + for (start = line; start; start = ptr) + { + if ((ptr = strchr(start, '\n')) != NULL) + *ptr++ = '\0'; + + fprintf(fp, "#%%description %s\n", start); + } + } + } + else + { + /* + * Just do descriptions for the main package... + */ + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == NULL) + { + strlcpy(line, dist->descriptions[i].description, sizeof(line)); + + for (start = line; start; start = ptr) + { + if ((ptr = strchr(start, '\n')) != NULL) + *ptr++ = '\0'; + + fprintf(fp, "#%%description %s\n", start); + } + } + } + + fprintf(fp, "#%%rootsize %d\n", rootsize); + fprintf(fp, "#%%usrsize %d\n", usrsize); + fputs("#\n", fp); + + fputs("PATH=/usr/xpg4/bin:/bin:/usr/bin:/usr/ucb:${PATH}\n", fp); + fputs("SHELL=/bin/sh\n", fp); + fputs("case \"`uname`\" in\n", fp); + fputs("\tDarwin*)\n", fp); + fputs("\tcase \"`id -un`\" in\n", fp); + fputs("\t\troot)\n", fp); + fputs("\t\t;;\n", fp); + fputs("\t\t*)\n", fp); + fprintf(fp, "\t\techo Sorry, you must have administrative priviledges to %s this software.\n", + title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); + fputs("\t\texit 1\n", fp); + fputs("\t\t;;\n", fp); + fputs("\tesac\n", fp); + fputs("\t;;\n", fp); + fputs("\t*)\n", fp); + fputs("\tcase \"`id`\" in\n", fp); + fputs("\t\tuid=0*)\n", fp); + fputs("\t\t;;\n", fp); + fputs("\t\t*)\n", fp); + fprintf(fp, "\t\techo Sorry, you must be root to %s this software.\n", + title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); + fputs("\t\texit 1\n", fp); + fputs("\t\t;;\n", fp); + fputs("\tesac\n", fp); + fputs("\t;;\n", fp); + fputs("esac\n", fp); + + qprintf(fp, "echo Copyright %s\n", dist->copyright); + fprintf(fp, "# Reset umask for %s...\n", + title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); + fputs("umask 002\n", fp); + + write_confcheck(fp); + + /* + * Return the file pointer... + */ + + return (fp); +} + + +/* + * 'write_confcheck()' - Write the echo check to find the right echo options. + */ + +static int /* O - -1 on error, 0 on success */ +write_confcheck(FILE *fp) /* I - Script file */ +{ + /* + * This is a simplified version of the autoconf test for echo; basically + * we ignore the Stardent Vistra SVR4 case, since 1) we've never heard of + * this OS, and 2) it doesn't provide the same functionality, specifically + * the omission of a newline when prompting the user for some text. + */ + + fputs("# Determine correct echo options...\n", fp); + fputs("if (echo \"testing\\c\"; echo 1,2,3) | grep c >/dev/null; then\n", fp); + fputs(" ac_n=-n\n", fp); + fputs(" ac_c=\n", fp); + fputs("else\n", fp); + fputs(" ac_n=\n", fp); + fputs(" ac_c='\\c'\n", fp); + fputs("fi\n", fp); + + /* + * This is a check for the correct options to use with the "tar" + * command. + */ + + fputs("# Determine correct extract options for the tar command...\n", fp); + fputs("if test `uname` = Darwin; then\n", fp); + fputs(" ac_tar=\"tar -xpPf\"\n", fp); + fputs("else if test \"`tar --help 2>&1 | grep GNU`\" = \"\"; then\n", fp); + fputs(" ac_tar=\"tar -xpf\"\n", fp); + fputs("else\n", fp); + fputs(" ac_tar=\"tar -xpPf\"\n", fp); + fputs("fi fi\n", fp); + + return (0); +} + + +/* + * 'write_depends()' - Write dependencies. + */ + +static int /* O - 0 on success, - 1 on failure */ +write_depends(const char *prodname, /* I - Product name */ + dist_t *dist, /* I - Distribution */ + FILE *fp, /* I - File pointer */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + depend_t *d; /* Current dependency */ + const char *product; /* Product/file to depend on */ + static const char *depends[] = /* Dependency strings */ + { + "requires", + "incompat", + "replaces", + "provides" + }; + + + for (i = 0, d = dist->depends; i < dist->num_depends; i ++, d ++) + if (d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + product = prodname; + else + product = d->product; + + fprintf(fp, "#%%%s %s %d %d\n", depends[(int)d->type], product, + d->vernumber[0], d->vernumber[1]); + + switch (d->type) + { + case DEPEND_REQUIRES : + if (product[0] == '/') + { + /* + * Require a file... + */ + + qprintf(fp, "if test ! -r %s -a ! -h %s; then\n", + product, product); + qprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n", + product); + fputs(" exit 1\n", fp); + fputs("fi\n", fp); + } + else + { + /* + * Require a product... + */ + + fprintf(fp, "if test ! -x %s/%s.remove; then\n", + SoftwareDir, product); + fprintf(fp, " if test -x %s.install; then\n", + product); + fprintf(fp, " echo Installing required %s software...\n", + product); + fprintf(fp, " ./%s.install now\n", product); + fputs(" else\n", fp); + fprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n", + product); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + fputs("fi\n", fp); + + if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) + { + /* + * Do version number checking... + */ + + fprintf(fp, "installed=`grep \'^#%%version\' " + "%s/%s.remove | awk \'{print $3}\'`\n", + SoftwareDir, product); + + fputs("if test x$installed = x; then\n", fp); + fputs(" installed=0\n", fp); + fputs("fi\n", fp); + + fprintf(fp, "if test $installed -lt %d -o $installed -gt %d; then\n", + d->vernumber[0], d->vernumber[1]); + fprintf(fp, " if test -x %s.install; then\n", + product); + fprintf(fp, " echo Installing required %s software...\n", + product); + fprintf(fp, " ./%s.install now\n", product); + fputs(" else\n", fp); + fprintf(fp, " echo Sorry, you must first install \\'%s\\' version %s to %s!\n", + product, d->version[0], d->version[1]); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + fputs("fi\n", fp); + } + } + break; + + case DEPEND_INCOMPAT : + if (product[0] == '/') + { + /* + * Incompatible with a file... + */ + + qprintf(fp, "if test -r %s -o -h %s; then\n", + product, product); + qprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n", + product); + fputs(" echo Please remove it first.\n", fp); + fputs(" exit 1\n", fp); + fputs("fi\n", fp); + } + else + { + /* + * Incompatible with a product... + */ + + fprintf(fp, "if test -x %s/%s.remove; then\n", + SoftwareDir, product); + + if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) + { + /* + * Do version number checking... + */ + + fprintf(fp, " installed=`grep \'^#%%version\' " + "%s/%s.remove | awk \'{print $3}\'`\n", + SoftwareDir, product); + + fputs(" if test x$installed = x; then\n", fp); + fputs(" installed=0\n", fp); + fputs(" fi\n", fp); + + fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n", + d->vernumber[0], d->vernumber[1]); + fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\' version %s to %s!\n", + product, d->version[0], d->version[1]); + fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n", + SoftwareDir, product); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + } + else + { + fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n", + product); + fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n", + SoftwareDir, product); + fputs(" exit 1\n", fp); + } + + fputs("fi\n", fp); + } + break; + + case DEPEND_REPLACES : + fprintf(fp, "if test -x %s/%s.remove; then\n", SoftwareDir, + product); + + if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) + { + /* + * Do version number checking... + */ + + fprintf(fp, " installed=`grep \'^#%%version\' " + "%s/%s.remove | awk \'{print $3}\'`\n", + SoftwareDir, product); + + fputs(" if test x$installed = x; then\n", fp); + fputs(" installed=0\n", fp); + fputs(" fi\n", fp); + + fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n", + d->vernumber[0], d->vernumber[1]); + fprintf(fp, " echo Automatically replacing \\'%s\\'...\n", + product); + fprintf(fp, " %s/%s.remove now\n", + SoftwareDir, product); + fputs(" fi\n", fp); + } + else + { + fprintf(fp, " echo Automatically replacing \\'%s\\'...\n", + product); + fprintf(fp, " %s/%s.remove now\n", + SoftwareDir, product); + } + + fputs("fi\n", fp); + break; + } + } + + return (0); +} + + +/* + * 'write_distfiles()' - Write a software distribution... + */ + +static int /* O - -1 on error, 0 on success */ +write_distfiles(const char *directory, /* I - Directory */ + const char *prodname, /* I - Product name */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution */ + time_t deftime, /* I - Default file time */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + int havepatchfiles; /* 1 if we have patch files, 0 otherwise */ + tarf_t *tarfile; /* Distribution tar file */ + char prodfull[255], /* Full name of product */ + swname[255], /* Name of distribution tar file */ + pswname[255], /* Name of patch tar file */ + filename[1024]; /* Name of temporary file */ + struct stat srcstat; /* Source file information */ + file_t *file; /* Software file */ + int rootsize, /* Size of files in root partition */ + usrsize; /* Size of files in /usr partition */ + int prootsize, /* Size of patch files in root partition */ + pusrsize; /* Size of patch files in /usr partition */ + + + /* + * Figure out the full name of the distribution... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + /* + * See if we need to make a patch distribution... + */ + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (isupper((int)file->type) && file->subpackage == subpackage) + break; + + havepatchfiles = i > 0; + + /* + * Copy the license and readme files... + */ + + if (Verbosity) + printf("Copying %s license and readme files...\n", prodfull); + + if (dist->license[0]) + { + snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull); + if (copy_file(filename, dist->license, 0444, getuid(), getgid())) + return (1); + } + + if (dist->readme[0]) + { + snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull); + if (copy_file(filename, dist->readme, 0444, getuid(), getgid())) + return (1); + } + + /* + * Create the non-shared software distribution file... + */ + + if (Verbosity) + puts("Creating non-shared software distribution file..."); + + snprintf(swname, sizeof(swname), "%s.sw", prodfull); + snprintf(filename, sizeof(filename), "%s/%s", directory, swname); + + unlink(filename); + if ((tarfile = tar_open(filename, CompressFiles)) == NULL) + { + fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files, rootsize = 0, prootsize = 0; + i > 0; + i --, file ++) + if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'f' : /* Regular file */ + case 'c' : /* Config file */ + case 'i' : /* Init script */ + if (stat(file->src, &srcstat)) + { + fprintf(stderr, "epm: Cannot stat %s - %s\n", file->src, + strerror(errno)); + tar_close(tarfile); + return (1); + } + + rootsize += (srcstat.st_size + 1023) / 1024; + + if (isupper(file->type & 255)) + prootsize += (srcstat.st_size + 1023) / 1024; + + /* + * Configuration files are extracted to the config file name with + * .N appended; add a bit of script magic to check if the config + * file already exists, and if not we copy the .N to the config + * file location... + */ + + if (tolower(file->type) == 'c') + snprintf(filename, sizeof(filename), "%s.N", file->dst); + else if (tolower(file->type) == 'i') + snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, + file->dst); + else + strcpy(filename, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, + srcstat.st_mtime, file->user, file->group, + filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + if (tar_file(tarfile, file->src) < 0) + { + fprintf(stderr, "epm: Error writing file data - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + + case 'd' : /* Create directory */ + if (Verbosity > 1) + printf("Directory %s...\n", file->dst); + + rootsize ++; + + if (isupper(file->type & 255)) + prootsize ++; + break; + + case 'l' : /* Link file */ + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, file->dst); + + if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, + file->user, file->group, file->dst, file->src) < 0) + { + fprintf(stderr, "epm: Error writing link header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + rootsize ++; + + if (isupper(file->type & 255)) + prootsize ++; + break; + } + + tar_close(tarfile); + + /* + * Create the shared software distribution file... + */ + + if (Verbosity) + puts("Creating shared software distribution file..."); + + snprintf(swname, sizeof(swname), "%s.ss", prodfull); + snprintf(filename, sizeof(filename), "%s/%s", directory, swname); + + unlink(filename); + if ((tarfile = tar_open(filename, CompressFiles)) == NULL) + { + fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files, usrsize = 0, pusrsize = 0; + i > 0; + i --, file ++) + if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'f' : /* Regular file */ + case 'c' : /* Config file */ + case 'i' : /* Init script */ + if (stat(file->src, &srcstat)) + { + fprintf(stderr, "epm: Cannot stat %s - %s\n", file->src, + strerror(errno)); + tar_close(tarfile); + return (1); + } + + usrsize += (srcstat.st_size + 1023) / 1024; + + if (isupper(file->type & 255)) + pusrsize += (srcstat.st_size + 1023) / 1024; + + /* + * Configuration files are extracted to the config file name with + * .N appended; add a bit of script magic to check if the config + * file already exists, and if not we copy the .N to the config + * file location... + */ + + if (tolower(file->type) == 'c') + snprintf(filename, sizeof(filename), "%s.N", file->dst); + else if (tolower(file->type) == 'i') + snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, + file->dst); + else + strcpy(filename, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, + srcstat.st_mtime, file->user, file->group, + filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + if (tar_file(tarfile, file->src) < 0) + { + fprintf(stderr, "epm: Error writing file data - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + + case 'd' : /* Create directory */ + if (Verbosity > 1) + printf("%s...\n", file->dst); + + usrsize ++; + + if (isupper(file->type & 255)) + pusrsize ++; + break; + + case 'l' : /* Link file */ + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, file->dst); + + if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, + file->user, file->group, file->dst, file->src) < 0) + { + fprintf(stderr, "epm: Error writing link header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + usrsize ++; + + if (isupper(file->type & 255)) + pusrsize ++; + break; + } + + tar_close(tarfile); + + /* + * Create the patch distribution files... + */ + + if (havepatchfiles) + { + if (Verbosity) + puts("Creating non-shared software patch file..."); + + snprintf(pswname, sizeof(pswname), "%s.psw", prodfull); + snprintf(filename, sizeof(filename), "%s/%s", directory, pswname); + + unlink(filename); + if ((tarfile = tar_open(filename, CompressFiles)) == NULL) + { + fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + switch (file->type) + { + case 'C' : /* Config file */ + case 'F' : /* Regular file */ + case 'I' : /* Init script */ + if (stat(file->src, &srcstat)) + { + fprintf(stderr, "epm: Cannot stat %s - %s\n", file->src, + strerror(errno)); + tar_close(tarfile); + return (1); + } + + /* + * Configuration files are extracted to the config file name with + * .N appended; add a bit of script magic to check if the config + * file already exists, and if not we copy the .N to the config + * file location... + */ + + if (file->type == 'C') + snprintf(filename, sizeof(filename), "%s.N", file->dst); + else if (file->type == 'I') + snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, + file->dst); + else + strcpy(filename, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, + srcstat.st_mtime, file->user, file->group, + filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + if (tar_file(tarfile, file->src) < 0) + { + fprintf(stderr, "epm: Error writing file data - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + + case 'd' : /* Create directory */ + if (Verbosity > 1) + printf("%s...\n", file->dst); + break; + + case 'L' : /* Link file */ + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, file->dst); + + if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, + file->user, file->group, file->dst, file->src) < 0) + { + fprintf(stderr, "epm: Error writing link header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + } + + tar_close(tarfile); + + if (Verbosity) + puts("Creating shared software patch file..."); + + snprintf(pswname, sizeof(pswname), "%s.pss", prodfull); + snprintf(filename, sizeof(filename), "%s/%s", directory, pswname); + + unlink(filename); + if ((tarfile = tar_open(filename, CompressFiles)) == NULL) + { + fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", + filename, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + switch (file->type) + { + case 'C' : /* Config file */ + case 'F' : /* Regular file */ + case 'I' : /* Init script */ + if (stat(file->src, &srcstat)) + { + fprintf(stderr, "epm: Cannot stat %s - %s\n", file->src, + strerror(errno)); + tar_close(tarfile); + return (1); + } + + /* + * Configuration files are extracted to the config file name with + * .N appended; add a bit of script magic to check if the config + * file already exists, and if not we copy the .N to the config + * file location... + */ + + if (file->type == 'C') + snprintf(filename, sizeof(filename), "%s.N", file->dst); + else if (file->type == 'I') + snprintf(filename, sizeof(filename), "%s/init.d/%s", + SoftwareDir, file->dst); + else + strcpy(filename, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, + srcstat.st_mtime, file->user, file->group, + filename, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + + if (tar_file(tarfile, file->src) < 0) + { + fprintf(stderr, "epm: Error writing file data - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + + case 'd' : /* Create directory */ + if (Verbosity > 1) + printf("%s...\n", file->dst); + break; + + case 'L' : /* Link file */ + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, file->dst); + + if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, + file->user, file->group, file->dst, file->src) < 0) + { + fprintf(stderr, "epm: Error writing link header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (1); + } + break; + } + + tar_close(tarfile); + } + + /* + * Create the scripts... + */ + + if (write_install(dist, prodname, rootsize, usrsize, directory, subpackage)) + return (1); + + if (havepatchfiles) + if (write_patch(dist, prodname, prootsize, pusrsize, directory, subpackage)) + return (1); + + if (write_remove(dist, prodname, rootsize, usrsize, directory, subpackage)) + return (1); + + /* + * Return... + */ + + return (0); +} + + +/* + * 'write_install()' - Write the installation script. + */ + +static int /* O - -1 on error, 0 on success */ +write_install(dist_t *dist, /* I - Software distribution */ + const char *prodname, /* I - Product name */ + int rootsize, /* I - Size of root files in kbytes */ + int usrsize, /* I - Size of /usr files in kbytes */ + const char *directory, /* I - Directory */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + int col; /* Column in the output */ + FILE *scriptfile; /* Install script */ + char prodfull[255]; /* Full product name */ + char filename[1024]; /* Name of temporary file */ + file_t *file; /* Software file */ + const char *runlevels; /* Run levels */ + int number; /* Start/stop number */ + + + if (Verbosity) + puts("Writing installation script..."); + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull); + + if ((scriptfile = write_common(dist, "Installation", rootsize, usrsize, + filename, subpackage)) == NULL) + { + fprintf(stderr, "epm: Unable to create installation script \"%s\" -\n" + " %s\n", filename, strerror(errno)); + return (-1); + } + + fputs("if test \"$*\" = \"now\"; then\n", scriptfile); + fputs(" echo Software license silently accepted via command-line option.\n", scriptfile); + fputs("else\n", scriptfile); + fputs(" echo \"\"\n", scriptfile); + qprintf(scriptfile, " echo This installation script will install the %s\n", + dist->product); + qprintf(scriptfile, " echo software version %s on your system.\n", + dist->version); + fputs(" echo \"\"\n", scriptfile); + fputs(" while true ; do\n", scriptfile); + fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); + fputs(" read yesno\n", scriptfile); + fputs(" case \"$yesno\" in\n", scriptfile); + fputs(" y | yes | Y | Yes | YES)\n", scriptfile); + fputs(" break\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" n | no | N | No | NO)\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" *)\n", scriptfile); + fputs(" echo Please enter yes or no.\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" esac\n", scriptfile); + fputs(" done\n", scriptfile); + + if (dist->license[0]) + { + fprintf(scriptfile, " more %s.license\n", prodfull); + fputs(" echo \"\"\n", scriptfile); + fputs(" while true ; do\n", scriptfile); + fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile); + fputs(" read yesno\n", scriptfile); + fputs(" case \"$yesno\" in\n", scriptfile); + fputs(" y | yes | Y | Yes | YES)\n", scriptfile); + fputs(" break\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" n | no | N | No | NO)\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" *)\n", scriptfile); + fputs(" echo Please enter yes or no.\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" esac\n", scriptfile); + fputs(" done\n", scriptfile); + } + + fputs("fi\n", scriptfile); + fprintf(scriptfile, "if test -x %s/%s.remove; then\n", SoftwareDir, prodfull); + fprintf(scriptfile, " echo Removing old versions of %s software...\n", + prodfull); + fprintf(scriptfile, " %s/%s.remove now\n", SoftwareDir, prodfull); + fputs("fi\n", scriptfile); + + write_space_checks(prodfull, scriptfile, rootsize ? "sw" : NULL, + usrsize ? "ss" : NULL, rootsize, usrsize); + write_depends(prodname, dist, scriptfile, subpackage); + write_commands(dist, scriptfile, COMMAND_PRE_INSTALL, subpackage); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Backing up old versions of non-shared files to be installed...\n", scriptfile); + + col = fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile); + fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + break; + + if (i) + { + fputs("if test -w /usr ; then\n", scriptfile); + fputs(" echo Backing up old versions of shared files to be installed...\n", scriptfile); + + col = fputs(" for file in", scriptfile); + for (; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile); + fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs(" done\n", scriptfile); + fputs("fi\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Creating installation directories...\n", scriptfile); + + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + { + qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n", + file->dst, file->dst, file->dst); + qprintf(scriptfile, " mkdir -p %s\n", file->dst); + fputs("else\n", scriptfile); + qprintf(scriptfile, " if test -f %s; then\n", file->dst); + qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n", + file->dst); + fputs(" exit 1\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("fi\n", scriptfile); + qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); + qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst); + } + } + + fputs("echo Installing software...\n", scriptfile); + + if (rootsize) + { + if (CompressFiles) + fprintf(scriptfile, "gzip -dc %s.sw | $ac_tar -\n", prodfull); + else + fprintf(scriptfile, "$ac_tar %s.sw\n", prodfull); + } + + if (usrsize) + { + fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile); + if (CompressFiles) + fprintf(scriptfile, " gzip -dc %s.ss | $ac_tar -\n", prodfull); + else + fprintf(scriptfile, " $ac_tar %s.ss\n", prodfull); + fputs("fi\n", scriptfile); + } + + fprintf(scriptfile, "if test -d %s; then\n", SoftwareDir); + fprintf(scriptfile, " rm -f %s/%s.remove\n", SoftwareDir, prodfull); + fputs("else\n", scriptfile); + fprintf(scriptfile, " mkdir -p %s\n", SoftwareDir); + fputs("fi\n", scriptfile); + fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir); + fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Checking configuration files...\n", scriptfile); + + col = fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" if test ! -f \"$file\"; then\n", scriptfile); + fputs(" cp \"$file.N\" \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + } + + fputs("echo Updating file permissions...\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) != 0 && + strcmp(file->user, "root") != 0 && file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'c' : + qprintf(scriptfile, "chown %s %s.N\n", file->user, file->dst); + qprintf(scriptfile, "chgrp %s %s.N\n", file->group, file->dst); + case 'f' : + qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); + break; + } + + fputs("if test -f /usr/.writetest; then\n", scriptfile); + fputs(" rm -f /usr/.writetest\n", scriptfile); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) == 0 && + strcmp(file->user, "root") != 0 && file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'c' : + qprintf(scriptfile, " chown %s %s.N\n", file->user, file->dst); + qprintf(scriptfile, " chgrp %s %s.N\n", file->group, file->dst); + case 'f' : + qprintf(scriptfile, " chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst); + break; + } + fputs("fi\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Setting up init scripts...\n", scriptfile); + + /* + * Find where the frigging init scripts go... + */ + + fputs("rcdir=\"\"\n", scriptfile); + fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); + fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " + "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); + fputs(" rcdir=\"$dir\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); + fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); + fputs(" for file in", scriptfile); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, " %s", file->dst); + fputs("; do\n", scriptfile); + fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); + qprintf(scriptfile, " ln -s %s/init.d/$file " + "/usr/local/etc/rc.d/$file.sh\n", + SoftwareDir); + fputs(" done\n", scriptfile); + fputs(" else\n", scriptfile); + fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("else\n", scriptfile); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fputs(" if test -d $rcdir/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" else\n", scriptfile); + fputs(" if test -d /etc/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" fi\n", scriptfile); + fputs(" fi\n", scriptfile); + + for (runlevels = get_runlevels(dist->files + i, "0235"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + number = get_stop(file, 0); + else + number = get_start(file, 99); + + fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); + qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", + *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "$rcdir/rc%c.d/%c%02d%s\n", + SoftwareDir, file->dst, *runlevels, + *runlevels == '0' ? 'K' : 'S', number, file->dst); + fputs(" fi\n", scriptfile); + } + +#ifdef __sgi + fputs(" if test -x /etc/chkconfig; then\n", scriptfile); + qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst); + fputs(" fi\n", scriptfile); +#endif /* __sgi */ + + } + + fputs("fi\n", scriptfile); + } + + write_commands(dist, scriptfile, COMMAND_POST_INSTALL, subpackage); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst); + + fputs("echo Installation is complete.\n", scriptfile); + + fclose(scriptfile); + + return (0); +} + + +/* + * 'write_instfiles()' - Write the installer files to the tar file... + */ + +static int /* O - 0 = success, -1 on failure */ +write_instfiles(tarf_t *tarfile, /* I - Distribution tar file */ + const char *directory, /* I - Output directory */ + const char *prodname, /* I - Base product name */ + const char *platname, /* I - Platform name */ + const char **files, /* I - Files */ + const char *destdir, /* I - Destination directory in tar file */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + char srcname[1024], /* Name of source file in distribution */ + dstname[1024], /* Name of destination file in distribution */ + prodfull[255]; /* Full name of product */ + struct stat srcstat; /* Source file information */ + + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + for (i = 0; files[i] != NULL; i ++) + { + snprintf(srcname, sizeof(srcname), "%s/%s.%s", directory, prodfull, files[i]); + snprintf(dstname, sizeof(dstname), "%s%s.%s", destdir, prodfull, files[i]); + + if (stat(srcname, &srcstat)) + { + if (!i) + break; + else + continue; + } + + if (srcstat.st_size == 0) + continue; + + if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & 07555, + srcstat.st_size, srcstat.st_mtime, "root", "root", + dstname, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + return (-1); + } + + if (tar_file(tarfile, srcname) < 0) + { + fprintf(stderr, "epm: Error writing file data for %s -\n %s\n", + dstname, strerror(errno)); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk %s.%s\n", (srcstat.st_size + 1023) / 1024.0, + prodfull, files[i]); + } + + return (0); +} + + +/* + * 'write_patch()' - Write the patch script. + */ + +static int /* O - -1 on error, 0 on success */ +write_patch(dist_t *dist, /* I - Software distribution */ + const char *prodname, /* I - Product name */ + int rootsize, /* I - Size of root files in kbytes */ + int usrsize, /* I - Size of /usr files in kbytes */ + const char *directory, /* I - Directory */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + FILE *scriptfile; /* Patch script */ + char filename[1024]; /* Name of temporary file */ + char prodfull[255]; /* Full product name */ + file_t *file; /* Software file */ + const char *runlevels; /* Run levels */ + int number; /* Start/stop number */ + + + if (Verbosity) + puts("Writing patch script..."); + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull); + + if ((scriptfile = write_common(dist, "Patch", rootsize, usrsize, + filename, subpackage)) == NULL) + { + fprintf(stderr, "epm: Unable to create patch script \"%s\" -\n" + " %s\n", filename, strerror(errno)); + return (-1); + } + + fputs("if test \"$*\" = \"now\"; then\n", scriptfile); + fputs(" echo Software license silently accepted via command-line option.\n", scriptfile); + fputs("else\n", scriptfile); + fputs(" echo \"\"\n", scriptfile); + qprintf(scriptfile, " echo This installation script will patch the %s\n", + dist->product); + qprintf(scriptfile, " echo software to version %s on your system.\n", dist->version); + fputs(" echo \"\"\n", scriptfile); + fputs(" while true ; do\n", scriptfile); + fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); + fputs(" read yesno\n", scriptfile); + fputs(" case \"$yesno\" in\n", scriptfile); + fputs(" y | yes | Y | Yes | YES)\n", scriptfile); + fputs(" break\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" n | no | N | No | NO)\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" *)\n", scriptfile); + fputs(" echo Please enter yes or no.\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" esac\n", scriptfile); + fputs(" done\n", scriptfile); + + if (dist->license[0]) + { + fprintf(scriptfile, " more %s.license\n", prodfull); + fputs(" echo \"\"\n", scriptfile); + fputs(" while true ; do\n", scriptfile); + fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile); + fputs(" read yesno\n", scriptfile); + fputs(" case \"$yesno\" in\n", scriptfile); + fputs(" y | yes | Y | Yes | YES)\n", scriptfile); + fputs(" break\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" n | no | N | No | NO)\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" *)\n", scriptfile); + fputs(" echo Please enter yes or no.\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" esac\n", scriptfile); + fputs(" done\n", scriptfile); + } + + fputs("fi\n", scriptfile); + + write_space_checks(prodfull, scriptfile, rootsize ? "psw" : NULL, + usrsize ? "pss" : NULL, rootsize, usrsize); + write_depends(prodname, dist, scriptfile, subpackage); + + fprintf(scriptfile, "if test ! -x %s/%s.remove; then\n", + SoftwareDir, prodfull); + fputs(" echo You do not appear to have the base software installed!\n", + scriptfile); + fputs(" echo Please install the full distribution instead.\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs("fi\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst); + + write_commands(dist, scriptfile, COMMAND_PRE_PATCH, subpackage); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->type == 'D' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Creating new installation directories...\n", scriptfile); + + for (; i > 0; i --, file ++) + if (file->type == 'D' && file->subpackage == subpackage) + { + qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n", + file->dst, file->dst, file->dst); + qprintf(scriptfile, " mkdir -p %s\n", file->dst); + fputs("else\n", scriptfile); + qprintf(scriptfile, " if test -f %s; then\n", file->dst); + qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n", + file->dst); + fputs(" exit 1\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("fi\n", scriptfile); + qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); + qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst); + } + } + + fputs("echo Patching software...\n", scriptfile); + + if (rootsize) + { + if (CompressFiles) + fprintf(scriptfile, "gzip -dc %s.psw | $ac_tar -\n", prodfull); + else + fprintf(scriptfile, "$ac_tar %s.psw\n", prodfull); + } + + if (usrsize) + { + fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile); + if (CompressFiles) + fprintf(scriptfile, " gzip -dc %s.pss | $ac_tar -\n", prodfull); + else + fprintf(scriptfile, " $ac_tar %s.pss\n", prodfull); + fputs("fi\n", scriptfile); + } + + fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull); + fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir); + fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull); + + fputs("echo Updating file permissions...\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) != 0 && + strcmp(file->user, "root") != 0 && file->subpackage == subpackage) + switch (file->type) + { + case 'C' : + case 'F' : + qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); + break; + } + + fputs("if test -f /usr/.writetest; then\n", scriptfile); + fputs(" rm -f /usr/.writetest\n", scriptfile); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (strncmp(file->dst, "/usr", 4) == 0 && + strcmp(file->user, "root") != 0 && file->subpackage == subpackage) + switch (file->type) + { + case 'C' : + case 'F' : + qprintf(scriptfile, " chown %s %s\n", file->user, file->dst); + qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst); + break; + } + fputs("fi\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->type == 'C' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Checking configuration files...\n", scriptfile); + + fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if (file->type == 'C' && file->subpackage == subpackage) + qprintf(scriptfile, " %s", file->dst); + + fputs("; do\n", scriptfile); + fputs(" if test ! -f \"$file\"; then\n", scriptfile); + fputs(" cp \"$file.N\" \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->type == 'R' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Removing files that are no longer used...\n", scriptfile); + + fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if (file->type == 'R' && file->subpackage == subpackage) + qprintf(scriptfile, " %s", file->dst); + + fputs("; do\n", scriptfile); + fputs(" rm -f \"$file\"\n", scriptfile); + fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); + fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->type == 'I' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Setting up init scripts...\n", scriptfile); + + /* + * Find where the frigging init scripts go... + */ + + fputs("rcdir=\"\"\n", scriptfile); + fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); + fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " + "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); + fputs(" rcdir=\"$dir\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); + fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); + fputs(" for file in", scriptfile); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'I' && file->subpackage == subpackage) + qprintf(scriptfile, " %s", file->dst); + fputs("; do\n", scriptfile); + fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); + qprintf(scriptfile, " ln -s %s/init.d/$file " + "/usr/local/etc/rc.d/$file.sh\n", + SoftwareDir); + fputs(" done\n", scriptfile); + fputs(" else\n", scriptfile); + fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("else\n", scriptfile); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fputs(" if test -d $rcdir/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" else\n", scriptfile); + fputs(" if test -d /etc/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" fi\n", scriptfile); + fputs(" fi\n", scriptfile); + + for (runlevels = get_runlevels(dist->files + i, "0235"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + number = get_stop(file, 0); + else + number = get_start(file, 99); + + fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); + qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", + *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); + qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " + "$rcdir/rc%c.d/%c%02d%s\n", + SoftwareDir, file->dst, *runlevels, + *runlevels == '0' ? 'K' : 'S', number, file->dst); + fputs(" fi\n", scriptfile); + } + +#ifdef __sgi + fputs(" if test -x /etc/chkconfig; then\n", scriptfile); + qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst); + fputs(" fi\n", scriptfile); +#endif /* __sgi */ + } + + fputs("fi\n", scriptfile); + } + + write_commands(dist, scriptfile, COMMAND_POST_PATCH, subpackage); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst); + + fputs("echo Patching is complete.\n", scriptfile); + + fclose(scriptfile); + + return (0); +} + + +/* + * 'write_remove()' - Write the removal script. + */ + +static int /* O - -1 on error, 0 on success */ +write_remove(dist_t *dist, /* I - Software distribution */ + const char *prodname, /* I - Product name */ + int rootsize, /* I - Size of root files in kbytes */ + int usrsize, /* I - Size of /usr files in kbytes */ + const char *directory, /* I - Directory */ + const char *subpackage) /* I - Subpackage */ +{ + int i; /* Looping var */ + int col; /* Current column */ + FILE *scriptfile; /* Remove script */ + char filename[1024]; /* Name of temporary file */ + char prodfull[255]; /* Full product name */ + file_t *file; /* Software file */ + const char *runlevels; /* Run levels */ + int number; /* Start/stop number */ + + + if (Verbosity) + puts("Writing removal script..."); + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull); + + if ((scriptfile = write_common(dist, "Removal", rootsize, usrsize, + filename, subpackage)) == NULL) + { + fprintf(stderr, "epm: Unable to create removal script \"%s\" -\n" + " %s\n", filename, strerror(errno)); + return (-1); + } + + fputs("if test ! \"$*\" = \"now\"; then\n", scriptfile); + fputs(" echo \"\"\n", scriptfile); + qprintf(scriptfile, " echo This removal script will remove the %s\n", + dist->product); + qprintf(scriptfile, " echo software version %s from your system.\n", + dist->version); + fputs(" echo \"\"\n", scriptfile); + fputs(" while true ; do\n", scriptfile); + fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); + fputs(" read yesno\n", scriptfile); + fputs(" case \"$yesno\" in\n", scriptfile); + fputs(" y | yes | Y | Yes | YES)\n", scriptfile); + fputs(" break\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" n | no | N | No | NO)\n", scriptfile); + fputs(" exit 1\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" *)\n", scriptfile); + fputs(" echo Please enter yes or no.\n", scriptfile); + fputs(" ;;\n", scriptfile); + fputs(" esac\n", scriptfile); + fputs(" done\n", scriptfile); + fputs("fi\n", scriptfile); + + /* + * Find any removal commands in the list file... + */ + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst); + + write_commands(dist, scriptfile, COMMAND_PRE_REMOVE, subpackage); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Cleaning up init scripts...\n", scriptfile); + + /* + * Find where the frigging init scripts go... + */ + + fputs("rcdir=\"\"\n", scriptfile); + fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); + fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " + "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); + fputs(" rcdir=\"$dir\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); + fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); + fputs(" for file in", scriptfile); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + qprintf(scriptfile, " %s", file->dst); + fputs("; do\n", scriptfile); + fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); + fputs(" done\n", scriptfile); + fputs(" else\n", scriptfile); + fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("else\n", scriptfile); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + qprintf(scriptfile, " %s/init.d/%s stop\n", SoftwareDir, file->dst); + + fputs(" if test -d $rcdir/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); + fputs(" else\n", scriptfile); + fputs(" if test -d /etc/init.d; then\n", scriptfile); + qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); + fputs(" fi\n", scriptfile); + fputs(" fi\n", scriptfile); + + for (runlevels = get_runlevels(dist->files + i, "0235"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + number = get_stop(file, 0); + else + number = get_start(file, 99); + + fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); + qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", + *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); + fputs(" fi\n", scriptfile); + } + +#ifdef __sgi + fputs(" if test -x /etc/chkconfig; then\n", scriptfile); + qprintf(scriptfile, " rm -f /etc/config/%s\n", file->dst); + fputs(" fi\n", scriptfile); +#endif /* __sgi */ + } + + fputs("fi\n", scriptfile); + } + + fputs("echo Removing/restoring installed files...\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + break; + + if (i) + { + col = fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" rm -f \"$file\"\n", scriptfile); + fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); + fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs("done\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + break; + + if (i) + { + fputs("if test -w /usr ; then\n", scriptfile); + col = fputs(" for file in", scriptfile); + for (; i > 0; i --, file ++) + if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && + strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" rm -f \"$file\"\n", scriptfile); + fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); + fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs(" done\n", scriptfile); + fputs("fi\n", scriptfile); + } + + fputs("echo Checking configuration files...\n", scriptfile); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage) + break; + + if (i) + { + col = fputs("for file in", scriptfile); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'c' && file->subpackage == subpackage) + { + if (col > 80) + col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; + else + col += qprintf(scriptfile, " %s", file->dst); + } + + fputs("; do\n", scriptfile); + fputs(" if cmp -s \"$file\" \"$file.N\"; then\n", scriptfile); + fputs(" # Config file not changed\n", scriptfile); + fputs(" rm -f \"$file\"\n", scriptfile); + fputs(" fi\n", scriptfile); + fputs(" rm -f \"$file.N\"\n", scriptfile); + fputs("done\n", scriptfile); + } + + for (i = dist->num_files, file = dist->files + i - 1; i > 0; i --, file --) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + break; + + if (i) + { + fputs("echo Removing empty installation directories...\n", scriptfile); + + for (; i > 0; i --, file --) + if (tolower(file->type) == 'd' && file->subpackage == subpackage) + { + qprintf(scriptfile, "if test -d %s; then\n", file->dst); + qprintf(scriptfile, " rmdir %s >/dev/null 2>&1\n", file->dst); + fputs("fi\n", scriptfile); + } + } + + write_commands(dist, scriptfile, COMMAND_POST_REMOVE, subpackage); + + fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull); + + fputs("echo Removal is complete.\n", scriptfile); + + fclose(scriptfile); + + return (0); +} + + +/* + * 'write_space_checks()' - Write disk space checks for the installer. + */ + +static int /* O - 0 on success, -1 on error */ +write_space_checks(const char *prodname,/* I - Distribution name */ + FILE *fp, /* I - File to write to */ + const char *sw, /* I - / archive */ + const char *ss, /* I - /usr archive */ + int rootsize, /* I - / install size in kbytes */ + int usrsize) /* I - /usr install size in kbytes */ +{ + fputs("case `uname` in\n", fp); + fputs(" AIX)\n", fp); + fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); + fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); + fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp); + fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); + fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp); + fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); + fputs(" ;;\n\n", fp); + fputs(" HP-UX)\n", fp); + fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); + fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); + fputs(" fsroot=`echo $dfroot | awk '{print $1}'`\n", fp); + fputs(" sproot=`echo $dfroot | awk '{print $9}'`\n", fp); + fputs(" fsusr=`echo $dfusr | awk '{print $1}'`\n", fp); + fputs(" spusr=`echo $dfusr | awk '{print $9}'`\n", fp); + fputs(" ;;\n\n", fp); + fputs(" IRIX*)\n", fp); + fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); + fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); + fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp); + fputs(" sproot=`echo $dfroot | awk '{print $13}'`\n", fp); + fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp); + fputs(" spusr=`echo $dfusr | awk '{print $13}'`\n", fp); + fputs(" ;;\n\n", fp); + fputs(" SCO*)\n", fp); + fputs(" dfroot=`df -k -B / | tr '\\n' ' '`\n", fp); + fputs(" dfusr=`df -k -B /usr | tr '\\n' ' '`\n", fp); + fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp); + fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); + fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp); + fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); + fputs(" ;;\n\n", fp); + fputs(" *)\n", fp); + fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); + fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); + fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp); + fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); + fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp); + fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); + fputs(" ;;\n", fp); + fputs("esac\n", fp); + fputs("\n", fp); + + fputs("if test x$sproot = x -o x$spusr = x; then\n", fp); + fputs(" echo WARNING: Unable to determine available disk space\\; " + "installing blindly...\n", fp); + fputs("else\n", fp); + fputs(" if test x$fsroot = x$fsusr; then\n", fp); + fprintf(fp, " if test %d -gt $sproot; then\n", rootsize + usrsize); + fputs(" echo Not enough free disk space for " + "software:\n", fp); + fprintf(fp, " echo You need %d kbytes but only have " + "$sproot kbytes available.\n", rootsize + usrsize); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + fputs(" else\n", fp); + fprintf(fp, " if test %d -gt $sproot; then\n", rootsize); + fputs(" echo Not enough free disk space for " + "software:\n", fp); + fprintf(fp, " echo You need %d kbytes in / but only have " + "$sproot kbytes available.\n", rootsize); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + fputs("\n", fp); + fprintf(fp, " if test %d -gt $spusr; then\n", usrsize); + fputs(" echo Not enough free disk space for " + "software:\n", fp); + fprintf(fp, " echo You need %d kbytes in /usr but only have " + "$spusr kbytes available.\n", usrsize); + fputs(" exit 1\n", fp); + fputs(" fi\n", fp); + fputs(" fi\n", fp); + fputs("fi\n", fp); + + return (0); +} + + +/* + * End of "$Id: portable.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/qprintf.c b/qprintf.c new file mode 100644 index 0000000..dd8c833 --- /dev/null +++ b/qprintf.c @@ -0,0 +1,218 @@ +/* + * "$Id: qprintf.c 826 2010-12-29 17:29:19Z mike $" + * + * Quoted fprintf function for the ESP Package Manager (EPM). + * + * Copyright 1999-2009 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * qprintf() - Do formatted output to a file. + */ + +/* + * Include necessary headers... + */ + +#include <stdio.h> +#include <ctype.h> +#include "epmstring.h" + + +/* + * 'qprintf()' - Do formatted output to a file. + */ + +int /* O - Number of bytes formatted */ +qprintf(FILE *fp, /* I - File to write to */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional args as needed... */ +{ + va_list ap; /* Pointer to additional arguments */ + int bytes; /* Bytes written */ + char sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + const char *bufformat; /* Start of format */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100]; /* Temporary format string for fprintf() */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int i; /* Looping var */ + + + /* + * Loop through the format string, formatting as needed... + */ + + va_start(ap, format); + + bytes = 0; + + while (*format) + { + if (*format == '%') + { + bufformat = format; + format ++; + + if (*format == '%') + { + putc(*format++, fp); + bytes ++; + continue; + } + else if (strchr(" -+#\'", *format)) + sign = *format++; + else + sign = 0; + + width = 0; + while (isdigit(*format & 255)) + width = width * 10 + *format++ - '0'; + + if (*format == '.') + { + format ++; + prec = 0; + + while (isdigit(*format & 255)) + prec = prec * 10 + *format++ - '0'; + } + else + prec = -1; + + if (*format == 'l') + size = *format++; + else + size = '\0'; + + if (!*format) + break; + + type = *format++; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((format - bufformat + 1) > sizeof(tformat)) + break; + + strlcpy(tformat, bufformat, (size_t)(format - bufformat + 1)); + + bytes += fprintf(fp, tformat, va_arg(ap, double)); + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((format - bufformat + 1) > sizeof(tformat)) + break; + + strlcpy(tformat, bufformat, (size_t)(format - bufformat + 1)); + + if (size == 'l') + bytes += fprintf(fp, tformat, va_arg(ap, long)); + else + bytes += fprintf(fp, tformat, va_arg(ap, int)); + break; + + case 'p' : /* Pointer value */ + if ((format - bufformat + 1) > sizeof(tformat)) + break; + + strlcpy(tformat, bufformat, (size_t)(format - bufformat + 1)); + + bytes += fprintf(fp, tformat, va_arg(ap, void *)); + break; + + case 'c' : /* Character or character array */ + if (width <= 1) + { + bytes ++; + putc(va_arg(ap, int), fp); + } + else + { + fwrite(va_arg(ap, char *), 1, (size_t)width, fp); + bytes += width; + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + + if (slen > width) + slen = width; + + if (sign != '-') + { + for (i = width - slen; i > 0; i --, bytes ++) + putc(' ', fp); + } + + for (i = slen; i > 0; i --, s ++, bytes ++) + { + if (strchr("`~#$%^&*()[{]}\\|;\'\"<>? ", *s)) + { + putc('\\', fp); + bytes ++; + } + + putc(*s, fp); + } + + if (sign == '-') + { + for (i = width - slen; i > 0; i --, bytes ++) + putc(' ', fp); + } + break; + } + } + else + { + putc(*format++, fp); + bytes ++; + } + } + + va_end(ap); + + /* + * Return the number of characters written. + */ + + return (bytes); +} + + +/* + * End of "$Id: qprintf.c 826 2010-12-29 17:29:19Z mike $". + */ + @@ -0,0 +1,956 @@ +/* + * "$Id: rpm.c 840 2010-12-30 20:30:03Z mike $" + * + * Red Hat package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_rpm() - Make a Red Hat software distribution package. + * move_rpms() - Move RPM packages to the build directory... + * write_spec() - Write the subpackage-specific parts of the RPM spec file. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static int move_rpms(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + struct utsname *platform, + const char *rpmdir, const char *subpackage, + const char *release); +static int write_spec(int format, const char *prodname, dist_t *dist, + FILE *fp, const char *subpackage); + + +/* + * 'make_rpm()' - Make a Red Hat software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_rpm(int format, /* I - Subformat */ + const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform, /* I - Platform information */ + const char *setup, /* I - Setup GUI image */ + const char *types) /* I - Setup GUI install types */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec file */ + tarf_t *tarfile; /* Distribution tar file */ + char specname[1024]; /* Spec filename */ + char name[1024], /* Product filename */ + filename[1024]; /* Destination filename */ + file_t *file; /* Current distribution file */ + char absdir[1024]; /* Absolute directory */ + char rpmdir[1024]; /* RPMDIR env var */ + char release[256]; /* Release: number */ + const char *build_option; /* Additional rpmbuild option */ + + + if (Verbosity) + puts("Creating RPM distribution..."); + + if (directory[0] != '/') + { + char current[1024]; /* Current directory */ + + + getcwd(current, sizeof(current)); + + snprintf(absdir, sizeof(absdir), "%s/%s", current, directory); + } + else + strlcpy(absdir, directory, sizeof(absdir)); + + /* + * Write the spec file for RPM... + */ + + if (Verbosity) + puts("Creating spec file..."); + + snprintf(specname, sizeof(specname), "%s/%s.spec", directory, prodname); + + if ((fp = fopen(specname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create spec file \"%s\" - %s\n", specname, + strerror(errno)); + return (1); + } + + if (dist->release[0]) + strlcpy(release, dist->release, sizeof(release)); + else + strlcpy(release, "0", sizeof(release)); + + fprintf(fp, "Name: %s\n", prodname); + fprintf(fp, "Version: %s\n", dist->version); + if (dist->epoch) + fprintf(fp, "Epoch: %d\n", dist->epoch); + fprintf(fp, "Release: %s\n", release); + fprintf(fp, "License: %s\n", dist->copyright); + fprintf(fp, "Packager: %s\n", dist->packager); + fprintf(fp, "Vendor: %s\n", dist->vendor); + + if (format == PACKAGE_LSB || format == PACKAGE_LSB_SIGNED) + fputs("Requires: lsb >= 3.0\n", fp); + + /* + * Tell RPM to put the distributions in the output directory... + */ + +#ifdef EPM_RPMTOPDIR + fprintf(fp, "%%define _topdir %s\n", absdir); + strcpy(rpmdir, absdir); +#else + if (getenv("RPMDIR")) + strlcpy(rpmdir, getenv("RPMDIR"), sizeof(rpmdir)); + else if (!access("/usr/src/redhat", 0)) + strcpy(rpmdir, "/usr/src/redhat"); + else if (!access("/usr/src/Mandrake", 0)) + strcpy(rpmdir, "/usr/src/Mandrake"); + else + strcpy(rpmdir, "/usr/src/RPM"); +#endif /* EPM_RPMTOPDIR */ + + snprintf(filename, sizeof(filename), "%s/RPMS", directory); + + make_directory(filename, 0777, getuid(), getgid()); + + snprintf(filename, sizeof(filename), "%s/rpms", directory); + symlink("RPMS", filename); + + if (!strcmp(platform->machine, "intel")) + snprintf(filename, sizeof(filename), "%s/RPMS/i386", directory); + else if (!strcmp(platform->machine, "ppc")) + snprintf(filename, sizeof(filename), "%s/RPMS/powerpc", directory); + else + snprintf(filename, sizeof(filename), "%s/RPMS/%s", directory, + platform->machine); + + make_directory(filename, 0777, getuid(), getgid()); + + /* + * Now list all of the subpackages... + */ + + write_spec(format, prodname, dist, fp, NULL); + for (i = 0; i < dist->num_subpackages; i ++) + write_spec(format, prodname, dist, fp, dist->subpackages[i]); + + /* + * Close the spec file... + */ + + fclose(fp); + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + snprintf(filename, sizeof(filename), "%s/buildroot%s", directory, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, 0, -1, -1)) + return (1); + break; + case 'i' : + if (format == PACKAGE_LSB || format == PACKAGE_LSB_SIGNED) + snprintf(filename, sizeof(filename), "%s/buildroot/etc/init.d/%s", + directory, file->dst); + else + snprintf(filename, sizeof(filename), "%s/buildroot%s/init.d/%s", + directory, SoftwareDir, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, 0, -1, -1)) + return (1); + break; + case 'd' : + snprintf(filename, sizeof(filename), "%s/buildroot%s", directory, file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, 0755, -1, -1); + break; + case 'l' : + snprintf(filename, sizeof(filename), "%s/buildroot%s", directory, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution from the spec file... + */ + + if (Verbosity) + puts("Building RPM binary distribution..."); + + if (format == PACKAGE_LSB_SIGNED || format == PACKAGE_RPM_SIGNED) + build_option = "-signed "; + else + build_option = ""; + + if (!strcmp(platform->machine, "intel")) + { + if (run_command(NULL, EPM_RPMBUILD " -bb --buildroot \"%s/buildroot\" " + EPM_RPMARCH "i386 %s%s", absdir, build_option, + specname)) + return (1); + } + else if (!strcmp(platform->machine, "ppc")) + { + if (run_command(NULL, EPM_RPMBUILD " -bb --buildroot \"%s/buildroot\" " + EPM_RPMARCH "powerpc %s%s", absdir, build_option, + specname)) + return (1); + } + else if (run_command(NULL, EPM_RPMBUILD " -bb --buildroot \"%s/buildroot\" " + EPM_RPMARCH "%s %s%s", absdir, platform->machine, + build_option, specname)) + return (1); + + /* + * Move the RPMs to the local directory and rename the RPMs using the + * product name specified by the user... + */ + + move_rpms(prodname, directory, platname, dist, platform, rpmdir, NULL, + release); + + for (i = 0; i < dist->num_subpackages; i ++) + move_rpms(prodname, directory, platname, dist, platform, rpmdir, + dist->subpackages[i], release); + + /* + * Build a compressed tar file to hold all of the subpackages... + */ + + if (dist->num_subpackages || setup) + { + /* + * Figure out the full name of the distribution... + */ + + if (dist->release[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, + dist->release); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + if (platname[0]) + { + strlcat(name, "-", sizeof(name)); + strlcat(name, platname, sizeof(name)); + } + + /* + * Create a compressed tar file... + */ + + snprintf(filename, sizeof(filename), "%s/%s.rpm.tgz", directory, name); + + if ((tarfile = tar_open(filename, 1)) == NULL) + return (1); + + /* + * Archive the setup and uninst GUIs and their data files... + */ + + if (setup) + { + /* + * Include the ESP Software Installation Wizard (setup)... + */ + + const char *setup_img; /* Setup image name */ + struct stat srcstat; /* File information */ + + + if (stat(SetupProgram, &srcstat)) + { + fprintf(stderr, "epm: Unable to stat GUI setup program %s - %s\n", + SetupProgram, strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", "setup", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, SetupProgram) < 0) + { + fprintf(stderr, "epm: Error writing file data for setup -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk setup\n", (srcstat.st_size + 1023) / 1024.0); + + /* + * And the image file... + */ + + stat(setup, &srcstat); + + if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".gif")) + setup_img = "setup.gif"; + else + setup_img = "setup.xpm"; + + if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, + srcstat.st_mtime, "root", "root", setup_img, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, setup) < 0) + { + fprintf(stderr, "epm: Error writing file data for %s -\n %s\n", + setup_img, strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img); + + /* + * And the types file... + */ + + if (types) + { + stat(types, &srcstat); + + if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, + srcstat.st_mtime, "root", "root", types, NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, types) < 0) + { + fprintf(stderr, "epm: Error writing file data for setup.types -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk setup.types\n", (srcstat.st_size + 1023) / 1024.0); + } + + /* + * Include the ESP Software Removal Wizard (uninst)... + */ + + if (stat(UninstProgram, &srcstat)) + { + fprintf(stderr, "epm: Unable to stat GUI uninstall program %s - %s\n", + UninstProgram, strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, + srcstat.st_mtime, "root", "root", "uninst", NULL) < 0) + { + fprintf(stderr, "epm: Error writing file header - %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (tar_file(tarfile, UninstProgram) < 0) + { + fprintf(stderr, "epm: Error writing file data for uninst -\n %s\n", + strerror(errno)); + tar_close(tarfile); + return (-1); + } + + if (Verbosity) + printf(" %7.0fk uninst\n", (srcstat.st_size + 1023) / 1024.0); + } + + /* + * Archive the main package and subpackages... + */ + + if (tar_package(tarfile, "rpm", prodname, directory, platname, dist, NULL)) + { + tar_close(tarfile); + return (1); + } + + for (i = 0; i < dist->num_subpackages; i ++) + { + if (tar_package(tarfile, "rpm", prodname, directory, platname, dist, + dist->subpackages[i])) + { + tar_close(tarfile); + return (1); + } + } + + tar_close(tarfile); + } + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/RPMS", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/rpms", directory); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/buildroot", directory); + unlink_directory(filename); + + unlink(specname); + + if (dist->num_subpackages) + { + /* + * Remove .rpm files since they are now in a .tgz file... + */ + + unlink_package("rpm", prodname, directory, platname, dist, NULL); + + for (i = 0; i < dist->num_subpackages; i ++) + unlink_package("rpm", prodname, directory, platname, dist, + dist->subpackages[i]); + } + } + + return (0); +} + + +/* + * 'move_rpms()' - Move RPM packages to the build directory... + */ + +static int /* O - 0 = success, 1 = fail */ +move_rpms(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform, /* I - Platform information */ + const char *rpmdir, /* I - RPM directory */ + const char *subpackage, /* I - Subpackage name */ + const char *release) /* I - Release: value */ +{ + char rpmname[1024]; /* RPM name */ + char prodfull[1024]; /* Full product name */ + struct stat rpminfo; /* RPM file info */ + + + /* + * Move the RPMs to the local directory and rename the RPMs using the + * product name specified by the user... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + if (dist->release[0]) + snprintf(rpmname, sizeof(rpmname), "%s/%s-%s-%s", directory, prodfull, + dist->version, dist->release); + else + snprintf(rpmname, sizeof(rpmname), "%s/%s-%s", directory, prodfull, + dist->version); + + if (platname[0]) + { + strlcat(rpmname, "-", sizeof(rpmname)); + strlcat(rpmname, platname, sizeof(rpmname)); + } + + strlcat(rpmname, ".rpm", sizeof(rpmname)); + + if (!strcmp(platform->machine, "intel")) + run_command(NULL, "/bin/mv %s/RPMS/i386/%s-%s-%s.i386.rpm %s", + rpmdir, prodfull, dist->version, release, + rpmname); + else if (!strcmp(platform->machine, "ppc")) + run_command(NULL, "/bin/mv %s/RPMS/powerpc/%s-%s-%s.powerpc.rpm %s", + rpmdir, prodfull, dist->version, release, + rpmname); + else + run_command(NULL, "/bin/mv %s/RPMS/%s/%s-%s-%s.%s.rpm %s", + rpmdir, platform->machine, prodfull, dist->version, + release, platform->machine, rpmname); + + if (Verbosity) + { + stat(rpmname, &rpminfo); + + printf(" %7.0fk %s\n", rpminfo.st_size / 1024.0, rpmname); + } + + return (0); +} + + +/* + * 'write_spec()' - Write the subpackage-specific parts of the RPM spec file. + */ + +static int /* O - 0 on success, -1 on error */ +write_spec(int format, /* I - Subformat */ + const char *prodname, /* I - Product name */ + dist_t *dist, /* I - Distribution */ + FILE *fp, /* I - Spec file */ + const char *subpackage) /* I - Subpackage name */ +{ + int i; /* Looping var */ + char name[1024]; /* Full product name */ + const char *product; /* Product to depend on */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + depend_t *d; /* Current dependency */ + const char *runlevels; /* Run levels */ + int number; /* Start/stop number */ + int have_commands; /* Have commands in current section? */ + + + /* + * Get the name we'll use for the subpackage... + */ + + if (subpackage) + snprintf(name, sizeof(name), " %s", subpackage); + else + name[0] = '\0'; + + /* + * Common stuff... + */ + + if (subpackage) + { + fprintf(fp, "%%package%s\n", name); + fprintf(fp, "Summary: %s", dist->product); + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + { + char line[1024], /* First line of description... */ + *ptr; /* Pointer into line */ + + + strlcpy(line, dist->descriptions[i].description, sizeof(line)); + if ((ptr = strchr(line, '\n')) != NULL) + *ptr = '\0'; + + fprintf(fp, " - %s", line); + } + fputs("\n", fp); + } + else + fprintf(fp, "Summary: %s\n", dist->product); + + fputs("Group: Applications\n", fp); + + /* + * List all of the dependencies... + */ + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + { + if (d->subpackage != subpackage) + continue; + + if (!strcmp(d->product, "_self")) + product = prodname; + else + product = d->product; + + if (d->type == DEPEND_REQUIRES) + fprintf(fp, "Requires: %s", product); + else if (d->type == DEPEND_PROVIDES) + fprintf(fp, "Provides: %s", product); + else if (d->type == DEPEND_REPLACES) + fprintf(fp, "Obsoletes: %s", product); + else + fprintf(fp, "Conflicts: %s", product); + + if (d->vernumber[0] == 0) + { + if (d->vernumber[1] < INT_MAX) + fprintf(fp, " <= %s\n", d->version[1]); + else + putc('\n', fp); + } + else if (d->vernumber[0] && d->vernumber[1] < INT_MAX) + { + if (d->vernumber[0] < INT_MAX && d->vernumber[1] < INT_MAX) + fprintf(fp, " >= %s, %s <= %s\n", d->version[0], product, + d->version[1]); + } + else if (d->vernumber[0] != d->vernumber[1]) + fprintf(fp, " >= %s\n", d->version[0]); + else + fprintf(fp, " = %s\n", d->version[0]); + } + + /* + * Pre/post install commands... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + break; + + if (i > 0) + { + fprintf(fp, "%%pre%s\n", name); + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + } + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + break; + + if (i > 0) + { + have_commands = 1; + + fprintf(fp, "%%post%s\n", name); + for (; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + + } + else + have_commands = 0; + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_LITERAL && c->subpackage == subpackage && + !strcmp(c->section, "spec")) + break; + + if (i > 0) + { + for (; i > 0; i --, c ++) + if (c->type == COMMAND_LITERAL && c->subpackage == subpackage && + !strcmp(c->section, "spec")) + fprintf(fp, "%s\n", c->command); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + if (!have_commands) + fprintf(fp, "%%post%s\n", name); + + fputs("if test \"x$1\" = x1; then\n", fp); + fputs(" echo Setting up init scripts...\n", fp); + + if (format == PACKAGE_LSB) + { + /* + * Use LSB commands to install the init scripts... + */ + + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fprintf(fp, " /usr/lib/lsb/install_initd /etc/init.d/%s\n", file->dst); + fprintf(fp, " /etc/init.d/%s start\n", file->dst); + } + } + else + { + /* + * Find where the frigging init scripts go... + */ + + fputs(" rcdir=\"\"\n", fp); + fputs(" for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", fp); + fputs(" if test -d $dir/rc3.d -o -h $dir/rc3.d; then\n", fp); + fputs(" rcdir=\"$dir\"\n", fp); + fputs(" fi\n", fp); + fputs(" done\n", fp); + fputs(" if test \"$rcdir\" = \"\" ; then\n", fp); + fputs(" echo Unable to determine location of startup scripts!\n", fp); + fputs(" else\n", fp); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fputs(" if test -d $rcdir/init.d; then\n", fp); + qprintf(fp, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); + qprintf(fp, " /bin/ln -s %s/init.d/%s " + "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" else\n", fp); + fputs(" if test -d /etc/init.d; then\n", fp); + qprintf(fp, " /bin/rm -f /etc/init.d/%s\n", file->dst); + qprintf(fp, " /bin/ln -s %s/init.d/%s " + "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst); + fputs(" fi\n", fp); + fputs(" fi\n", fp); + + for (runlevels = get_runlevels(dist->files + i, "0123456"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + number = get_stop(file, 0); + else + number = get_start(file, 99); + + qprintf(fp, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels, + (*runlevels == '0' || *runlevels == '1' || + *runlevels == '6') ? 'K' : 'S', number, file->dst); + qprintf(fp, " /bin/ln -s %s/init.d/%s " + "$rcdir/rc%c.d/%c%02d%s\n", SoftwareDir, file->dst, + *runlevels, + (*runlevels == '0' || *runlevels == '1' || + *runlevels == '6') ? 'K' : 'S', number, file->dst); + } + + qprintf(fp, " %s/init.d/%s start\n", SoftwareDir, file->dst); + } + + fputs(" fi\n", fp); + } + + fputs("fi\n", fp); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + break; + + if (i) + { + have_commands = 1; + + fprintf(fp, "%%preun%s\n", name); + fputs("if test \"x$1\" = x0; then\n", fp); + fputs(" echo Cleaning up init scripts...\n", fp); + + if (format == PACKAGE_LSB) + { + /* + * Use LSB commands to remove the init scripts... + */ + + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + fprintf(fp, " /etc/init.d/%s stop\n", file->dst); + fprintf(fp, " /usr/lib/lsb/remove_initd /etc/init.d/%s\n", file->dst); + } + } + else + { + /* + * Find where the frigging init scripts go... + */ + + fputs(" rcdir=\"\"\n", fp); + fputs(" for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", fp); + fputs(" if test -d $dir/rc3.d -o -h $dir/rc3.d; then\n", fp); + fputs(" rcdir=\"$dir\"\n", fp); + fputs(" fi\n", fp); + fputs(" done\n", fp); + fputs(" if test \"$rcdir\" = \"\" ; then\n", fp); + fputs(" echo Unable to determine location of startup scripts!\n", fp); + fputs(" else\n", fp); + for (; i > 0; i --, file ++) + if (tolower(file->type) == 'i' && file->subpackage == subpackage) + { + qprintf(fp, " %s/init.d/%s stop\n", SoftwareDir, file->dst); + + fputs(" if test -d $rcdir/init.d; then\n", fp); + qprintf(fp, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); + fputs(" else\n", fp); + fputs(" if test -d /etc/init.d; then\n", fp); + qprintf(fp, " /bin/rm -f /etc/init.d/%s\n", file->dst); + fputs(" fi\n", fp); + fputs(" fi\n", fp); + + for (runlevels = get_runlevels(dist->files + i, "0123456"); + isdigit(*runlevels & 255); + runlevels ++) + { + if (*runlevels == '0') + number = get_stop(file, 0); + else + number = get_start(file, 99); + + qprintf(fp, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels, + (*runlevels == '0' || *runlevels == '1' || + *runlevels == '6') ? 'K' : 'S', number, file->dst); + } + } + + fputs(" fi\n", fp); + } + + fputs("fi\n", fp); + } + else + have_commands = 0; + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage) + break; + + if (i > 0) + { + if (!have_commands) + fprintf(fp, "%%preun%s\n", name); + + for (; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + } + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage) + break; + + if (i > 0) + { + fprintf(fp, "%%postun%s\n", name); + for (; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage) + fprintf(fp, "%s\n", c->command); + } + + /* + * Description... + */ + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + { + fprintf(fp, "%%description %s\n", name); + + for (; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + fprintf(fp, "%s\n", dist->descriptions[i].description); + } + + /* + * Files... + */ + + fprintf(fp, "%%files%s\n", name); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (file->subpackage == subpackage) + switch (tolower(file->type)) + { + case 'c' : + fprintf(fp, "%%attr(%04o,%s,%s) %%config(noreplace) \"%s\"\n", + file->mode, file->user, file->group, file->dst); + break; + case 'd' : + fprintf(fp, "%%attr(%04o,%s,%s) %%dir \"%s\"\n", file->mode, + file->user, file->group, file->dst); + break; + case 'f' : + case 'l' : + fprintf(fp, "%%attr(%04o,%s,%s) \"%s\"\n", file->mode, file->user, + file->group, file->dst); + break; + case 'i' : + if (format == PACKAGE_LSB) + fprintf(fp, "%%attr(0555,root,root) \"/etc/init.d/%s\"\n", + file->dst); + else + fprintf(fp, "%%attr(0555,root,root) \"%s/init.d/%s\"\n", + SoftwareDir, file->dst); + break; + } + + return (0); +} + + +/* + * End of "$Id: rpm.c 840 2010-12-30 20:30:03Z mike $". + */ @@ -0,0 +1,182 @@ +/* + * "$Id: run.c 611 2005-01-11 21:37:42Z mike $" + * + * External program function for the ESP Package Manager (EPM). + * + * Copyright 1999-2005 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * run_command() - Run an external program. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" +#include <stdarg.h> +#include <fcntl.h> +#include <sys/wait.h> + + +/* + * 'run_command()' - Run an external program. + */ + +int /* O - Exit status */ +run_command(const char *directory, /* I - Directory for command or NULL */ + const char *command, /* I - Command string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Argument pointer */ + int pid, /* Child process ID */ + status, /* Status of child */ + argc; /* Number of arguments */ + char argbuf[10240], /* Argument buffer */ + *argptr, /* Argument string pointer */ + *argv[100]; /* Argument strings */ + + + /* + * Format the command string... + */ + + va_start(ap, command); + vsnprintf(argbuf, sizeof(argbuf) - 1, command, ap); + argbuf[sizeof(argbuf) - 1] = '\0'; + + if (Verbosity > 1) + puts(argbuf); + + /* + * Parse the argument string; arguments can be separated by whitespace + * and quoted by " and '... + */ + + argv[0] = argbuf; + + for (argptr = argbuf, argc = 1; *argptr != '\0' && argc < 99; argptr ++) + if (isspace(*argptr & 255)) + { + *argptr++ = '\0'; + + while (isspace(*argptr & 255)) + argptr ++; + + if (*argptr != '\0') + { + argv[argc] = argptr; + argc ++; + } + + argptr --; + } + else if (*argptr == '\'') + { + if (argptr == argv[argc - 1]) + argv[argc - 1] ++; + + for (argptr ++; *argptr && *argptr != '\''; argptr ++) + if (*argptr == '\\' && argptr[1]) + strcpy(argptr, argptr + 1); + + if (*argptr == '\'') + strcpy(argptr, argptr + 1); + + argptr --; + } + else if (*argptr == '\"') + { + if (argptr == argv[argc - 1]) + argv[argc - 1] ++; + + for (argptr ++; *argptr && *argptr != '\"'; argptr ++) + if (*argptr == '\\' && argptr[1]) + strcpy(argptr, argptr + 1); + + if (*argptr == '\"') + strcpy(argptr, argptr + 1); + + argptr --; + } + + argv[argc] = NULL; + + /* + * Execute the command... + */ + + if ((pid = fork()) == 0) + { + /* + * Child comes here... Redirect stdin, stdout, and stderr to /dev/null + * if !Verbosity... + */ + + if (Verbosity < 2) + { + close(0); + close(1); + close(2); + + open("/dev/null", O_RDWR); + dup(0); + dup(0); + } + + /* + * Change directories... + */ + + if (directory) + chdir(directory); + + /* + * Execute the program; if an error occurs, exit with the UNIX error... + */ + + execvp(argv[0], argv); + fprintf(stderr, "epm: Unable to execute \"%s\" program: %s\n", argv[0], + strerror(errno)); + exit(errno); + } + else if (pid < 0) + { + /* + * Error - can't fork! + */ + + perror("epm: fork failed"); + return (1); + } + + /* + * Fork successful - wait for the child and return the error status... + */ + + if (wait(&status) != pid) + { + fputs("epm: Got exit status from wrong program!\n", stderr); + return (1); + } + else if (WIFSIGNALED(status)) + return (-WTERMSIG(status)); + else + return (WEXITSTATUS(status)); +} + + +/* + * End of "$Id: run.c 611 2005-01-11 21:37:42Z mike $". + */ @@ -0,0 +1,469 @@ +/* + * "$Id: setld.c 833 2010-12-30 00:00:50Z mike $" + * + * Tru64 package gateway for the ESP Package Manager (EPM) + * + * Copyright 2001-2010 by Easy Software Products + * Copyright 2001 by Aneesh Kumar (aneesh.kumar@digital.com) at Digital India. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_setld() - Make a Tru64 setld package. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * 'make_setld()' - Make a Tru64 setld package. + */ + +int /* O - 0 = success, 1 = fail */ +make_setld(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform) /* I - Platform information */ +{ + int i, j; /* Looping vars */ + FILE *fp; /* Spec file */ + tarf_t *tarfile; /* .tardist file */ + char name[1024]; /* Full product name */ + char scpname[1024]; /* XXXVVV control program filename */ + char miname[1024]; /* XXXVVV.mi filename */ + char keyname[1024]; /* XXXVVV.key filename */ + char filename[1024]; /* Destination filename */ + char subset[1024]; /* Subset name */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + char current[1024]; /* Current directory */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + const char *runlevels; /* Run levels */ + + + REF(platform); + + /* + * Check the package information to make sure it complies with the + * extremely limited Tru64 packager requirements. + */ + + if (dist->vernumber < 100 || dist->vernumber > 999) + { + fprintf(stderr, "epm: Need a version number between 100 and 999 inclusive.\n" + " The current version number (%d) is out of range.\n", + dist->vernumber); + return (1); + } + + if (strlen(prodname) < 3) + { + fprintf(stderr, "epm: Need a product name of at least 3 uppercase characters.\n" + " The current product name (%s) is not acceptable.\n", + prodname); + return (1); + } + + for (i = 0; prodname[i]; i ++) + if (!isupper(prodname[i] & 255)) + { + fprintf(stderr, "epm: Need a product name of at least 3 uppercase characters.\n" + " The current product name (%s) is not acceptable.\n", + prodname); + return (1); + } + + for (i = 0; i < dist->num_subpackages; i ++) + { + if ((strlen(dist->subpackages[i]) + strlen(prodname)) > 77) + { + fprintf(stderr, "epm: Product + subpackage names must be less than 77 characters.\n" + " The current subpackage name (%s) is not acceptable.\n", + dist->subpackages[i]); + return (1); + } + + for (j = 0; dist->subpackages[i][j]; j ++) + if (!isupper(dist->subpackages[i][j] & 255)) + { + fprintf(stderr, "epm: Subpackage names may only contain uppercase letters.\n" + " The current subpackage name (%s) is not acceptable.\n", + dist->subpackages[i]); + return (1); + } + } + + /* + * Prepare for packaging... + */ + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodname, dist->version, + dist->release, platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, + dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + getcwd(current, sizeof(current)); + + /* + * Add symlinks for init scripts... + */ + + for (i = 0; i < dist->num_files; i ++) + if (tolower(dist->files[i].type) == 'i') + { + /* + * Make symlinks for all of the selected run levels... + */ + + for (runlevels = get_runlevels(dist->files + i, "023"); + isdigit(*runlevels & 255); + runlevels ++) + { + file = add_file(dist, dist->files[i].subpackage); + file->type = 'l'; + file->mode = 0; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "../init.d/%s", + dist->files[i].dst); + + if (*runlevels == '0') + snprintf(file->dst, sizeof(file->dst), "/sbin/rc0.d/K%02d%s", + get_stop(dist->files + i, 0), dist->files[i].dst); + else + snprintf(file->dst, sizeof(file->dst), "/sbin/rc%c.d/S%02d%s", + *runlevels, get_start(dist->files + i, 99), + dist->files[i].dst); + } + + /* + * Then send the original file to /sbin/init.d... + */ + + file = dist->files + i; + + snprintf(filename, sizeof(filename), "/sbin/init.d/%s", file->dst); + strcpy(file->dst, filename); + } + + /* + * Build package directories... + * + * Note: The src/scps directory and the key, inventory, and + * subset control programs below should actually go in + * a data subdirectory according to the Tru64 + * documentation, but (at least under 4.0d) the invcutter + * program will not be able to find the distribution files + * if they are not colocated with these data files. + */ + + if (Verbosity) + puts("Creating Tru64 (setld) distribution..."); + + snprintf(filename, sizeof(filename), "%s/output", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/src", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/output", directory); + mkdir(filename, 0777); + + snprintf(filename, sizeof(filename), "%s/src", directory); + mkdir(filename, 0777); + + snprintf(filename, sizeof(filename), "%s/src/scps", directory); + mkdir(filename, 0777); + + /* + * Write the subset control program... + */ + + if (Verbosity) + puts("Creating subset control program..."); + + snprintf(scpname, sizeof(scpname), "%s/src/scps/%sALL%03d.scp", directory, + prodname, dist->vernumber); + + if ((fp = fopen(scpname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create subset control program \"%s\" - %s\n", + scpname, strerror(errno)); + return (1); + } + + fputs("#!/bin/sh\n", fp); + fputs("case $ACT in\n", fp); + + fputs("PRE_L)\n", fp); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + { + qprintf(fp, "if test -x %s; then\n", file->dst); + qprintf(fp, " %s stop\n", file->dst); + fputs("fi\n", fp); + } + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + fprintf(fp, "%s\n", c->command); + fputs(";;\n", fp); + + fputs("POST_L)\n", fp); + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + fprintf(fp, "%s\n", c->command); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c') + { + qprintf(fp, "if test ! -f %s; then\n", file->dst); + qprintf(fp, " /bin/cp %s.N %s\n", file->dst, file->dst); + fputs("fi\n", fp); + } + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "%s start\n", file->dst); + fputs(";;\n", fp); + + fputs("PRE_D)\n", fp); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "%s stop\n", file->dst); + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + fprintf(fp, "%s\n", c->command); + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'c') + { + qprintf(fp, "if cmp -s %s.N %s; then\n", file->dst, file->dst); + qprintf(fp, " /bin/rm -f %s\n", file->dst); + fputs("fi\n", fp); + } + fputs(";;\n", fp); + + fputs("POST_D)\n", fp); + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + fprintf(fp, "%s\n", c->command); + fputs(";;\n", fp); + + fputs("esac\n", fp); + + fclose(fp); + + /* + * Sort the file list by the destination name, since kits need a sorted + * list... + */ + + sort_dist_files(dist); + + /* + * Now do the inventory file... + */ + + if (Verbosity) + puts("Creating master inventory file..."); + + snprintf(miname, sizeof(miname), "%s/src/%s%03d.mi", directory, prodname, dist->vernumber); + + if ((fp = fopen(miname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create master inventory file \"%s\" - %s\n", + miname, strerror(errno)); + return (1); + } + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + snprintf(subset, sizeof(subset), "%s%s%03d", prodname, + file->subpackage ? file->subpackage : "ALL", dist->vernumber); + + switch (tolower(file->type)) + { + case 'c' : + fprintf(fp, "2\t.%s.N\t%s\n", file->dst, subset); + break; + case 'd' : + case 'i' : + case 'f' : + case 'l' : + fprintf(fp, "0\t.%s\t%s\n", file->dst, subset); + break; + } + } + + fclose(fp); + + /* + * Create the key file... + */ + + if (Verbosity) + puts("Creating key file..."); + + snprintf(keyname, sizeof(keyname), "%s/src/%s%03d.k", directory, prodname, + dist->vernumber); + + if ((fp = fopen(keyname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create key file \"%s\" - %s\n", + keyname, strerror(errno)); + return (1); + } + + qprintf(fp, "NAME='%s, %s'\n", dist->product, dist->version); + fprintf(fp, "CODE=%s\n", prodname); + fprintf(fp, "VER=%03d\n", dist->vernumber); + fprintf(fp, "MI=%s%03d.mi\n", prodname, dist->vernumber); + fputs("COMPRESS=0\n", fp); + fputs("%%\n", fp); + qprintf(fp, "%sALL%03d\t.\t0\t'%s, %s'\n", prodname, dist->vernumber, + dist->product, dist->version); + for (i = 0; i < dist->num_subpackages; i ++) + qprintf(fp, "%s%s%03d\t.\t0\t'%s, %s'\n", prodname, dist->subpackages[i], + dist->vernumber, dist->product, dist->version); + fclose(fp); + + /* + * Copy the files over... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file or make the directory or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + case 'i' : + snprintf(filename, sizeof(filename), "%s/src%s", directory, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + + case 'd' : + snprintf(filename, sizeof(filename), "%s/src%s", directory, file->dst); + + if (Verbosity > 1) + printf("Directory %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + + case 'l' : + snprintf(filename, sizeof(filename), "%s/src%s", directory, file->dst); + + if (Verbosity > 1) + printf("%s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Build the distribution from the inventory and control files... + */ + + if (Verbosity) + puts("Building Tru64 (setld) distribution..."); + + snprintf(filename, sizeof(filename), "%s/src", directory); + chdir(filename); + + if (run_command(NULL, "kits %s%03d.k . ../output", prodname, dist->vernumber)) + return (1); + + chdir(current); + + /* + * Tar and compress the distribution... + */ + + if (Verbosity) + puts("Creating tar.gz file for distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s.tar.gz", directory, name); + + if ((tarfile = tar_open(filename, 1)) == NULL) + return (1); + + snprintf(filename, sizeof(filename), "%s/output", directory); + + if (tar_directory(tarfile, filename, prodname)) + { + tar_close(tarfile); + return (1); + } + + tar_close(tarfile); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + snprintf(filename, sizeof(filename), "%s/output", directory); + unlink_directory(filename); + + snprintf(filename, sizeof(filename), "%s/src", directory); + unlink_directory(filename); + } + + return (0); +} + + +/* + * End of "$Id: setld.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/setup.cxx b/setup.cxx new file mode 100644 index 0000000..0169218 --- /dev/null +++ b/setup.cxx @@ -0,0 +1,553 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#include "setup.h" + +Fl_Double_Window *SetupWindow=(Fl_Double_Window *)0; + +static void cb_SetupWindow(Fl_Double_Window*, void*) { + if (CancelButton->active()) + exit(0); +} + +Fl_Box *Title[6]={(Fl_Box *)0}; + +Fl_Wizard *Wizard=(Fl_Wizard *)0; + +Fl_Help_View *ReadmeFile=(Fl_Help_View *)0; + +Fl_Round_Button *TypeButton[8]={(Fl_Round_Button *)0}; + +Fl_Check_Browser *SoftwareList=(Fl_Check_Browser *)0; + +Fl_Box *SoftwareSize=(Fl_Box *)0; + +Fl_Button *InstallAllButton=(Fl_Button *)0; + +static void cb_InstallAllButton(Fl_Button*, void*) { + SoftwareList->check_all(); +list_cb(0,0); +} + +Fl_Button *InstallNoneButton=(Fl_Button *)0; + +static void cb_InstallNoneButton(Fl_Button*, void*) { + SoftwareList->check_none(); +list_cb(0,0); +} + +Fl_Browser *ConfirmList=(Fl_Browser *)0; + +Fl_Help_View *LicenseFile=(Fl_Help_View *)0; + +Fl_Round_Button *LicenseAccept=(Fl_Round_Button *)0; + +static void cb_LicenseAccept(Fl_Round_Button*, void*) { + NextButton->activate(); +} + +Fl_Round_Button *LicenseDecline=(Fl_Round_Button *)0; + +static void cb_LicenseDecline(Fl_Round_Button*, void*) { + NextButton->activate(); +} + +Fl_Group *Pane[6]={(Fl_Group *)0}; + +Fl_Progress *InstallPercent=(Fl_Progress *)0; + +Fl_Browser *InstallLog=(Fl_Browser *)0; + +Fl_Box *WelcomeImage=(Fl_Box *)0; + +#include <FL/Fl_Pixmap.H> +static const char *idata_default[] = { +"96 96 64 1", +" \tc None", +".\tc #000100", +"+\tc #0C0E0A", +"@\tc #1C1C19", +"#\tc #231C0C", +"$\tc #312714", +"%\tc #2C2B27", +"&\tc #3B2D0F", +"*\tc #403728", +"=\tc #393A38", +"-\tc #534117", +";\tc #504430", +">\tc #474946", +",\tc #5B482B", +"\'\tc #634D1C", +")\tc #704B0B", +"!\tc #5F523D", +"~\tc #555754", +"{\tc #7B562C", +"]\tc #6F5F40", +"^\tc #815E18", +"/\tc #616260", +"(\tc #7B6421", +"_\tc #816435", +":\tc #8A6620", +"<\tc #8E6A1C", +"[\tc #8A6B23", +"}\tc #856E4F", +"|\tc #727371", +"1\tc #946F2F", +"2\tc #9C7B29", +"3\tc #7F817E", +"4\tc #9C824C", +"5\tc #A18240", +"6\tc #98835F", +"7\tc #A9862F", +"8\tc #AA8B3C", +"9\tc #8E908D", +"0\tc #B09241", +"a\tc #B29451", +"b\tc #B6994D", +"c\tc #BB9D52", +"d\tc #9FA09D", +"e\tc #B8A173", +"f\tc #C0A35E", +"g\tc #BFA56D", +"h\tc #ABADAA", +"i\tc #CEB069", +"j\tc #B8B29F", +"k\tc #C3B28A", +"l\tc #B2B4B1", +"m\tc #CFB681", +"n\tc #BCBEBB", +"o\tc #DCBC7C", +"p\tc #CCBFA3", +"q\tc #C8CAC6", +"r\tc #ECCE8C", +"s\tc #CFD2CE", +"t\tc #D7D9D6", +"u\tc #FDDE9B", +"v\tc #DFE1DE", +"w\tc #E9EBE7", +"x\tc #F1F3F0", +"y\tc #FDFFFC", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" q9~==n \ + ", +" q9~@.....% \ + ", +" q9~@....*}eu#.q \ + ", +" q9~@....*}eurroi].3 t>+/ \ + ", +" q9~@...+;}euuoofffffa.% t%...~ \ + ", +" q9~@...+;6murroffffffffff#.q t%.!m+.~ \ + ", +" q9~@...+;6muromfffffffgfgffff].3 t%.!uum+.~ \ + ", +" q9~@...@;6muroiffff]@#;}afffffgffa.% t%.!uuuum..~ \ + ", +" 9~@...@!6muroifgfffffa......#;_gfffff#.q t%.!uuuuuum+.~ \ + ", +" 3..@!6rurrofffffffgfff}./vd/@+...#;_gf].| t%.!uuuuuuuum..~ \ + ", +" =.euroffffff4;$#$$$%$$#.dyyyyvd/@....#$.@ t%.!uuuuuuuuuum+.~ \ + ", +" |.}offffffff+...........vyyyyyyyyvd/@....%@.!uuuuuuuuuuuum..~\ + ", +" h.;rffffffff..hhhhhhhd.@yyyyyyyyyyyyyvd/@....%}6upuuuuuuuum+.\ +~ ", +" +.uigfgffgf..wxvxvxvd./yyyyyyyyyyyyyyyyyvd/@....*!epuuuuuum.\ +.~ ", +" >.eofffffff..vvxvxvx/.dyyyyyyyyyyyyyyyyyyyyyvd/%....%}kuuuum\ ++.~ ", +" 3.]rfffffff..xvxvxvx%.vyyyyyyyyyyyyyyyyyyyyyyyyyvd|%...uuuuu\ +m..~ ", +" q.%rfgfffff..vxvxxxv.@yyxqswyyyyyyyyyyyyyyyyyyyyyyyyx%.euuuu\ +um+.~ ", +" @.riffffff..xxqnnn9./yyxllhlntwyyyyyyyyyyyyyyyyyyyyy+.uuuuu\ +uum..~ ", +" ~.eogfgfff..vxllhl>.dyyyvtnlllhlnswyyyyyyyyyyyyyyyys.=uuuuu\ +uuum+.~ ", +" d.!rffffff..xvvvvv%.vyyyyyyyvtnlllhlntwyyyyyyyyyyyy9.}uuuuu\ +uuuum..~ ", +" t.@uffgfff..xxtssq.@yyxqqtwyyyyyxtnlllhlnswyyyyyyyy~.kuuuuu\ +uuuuum+.~ ", +" %.mifffff..xxhll|./yyxhllllqtwyyyyyvtnlllhlntwyyyy+.uupuuu\ +uuuuuum..9 ", +" thhhhhhhhh~.6offfb0..xxvts/.dyyyxvsnllllhqtwyyyyyxtnlllhnyys.*uuupuu\ +uuuuuuum+.9 ", +" %...........!r88287..xxtss%.tyyyyyyyxvsnlllllqtwyyyyyvtqsyy9.}uuuuuu\ +upuuuuuum..n ", +" h.#,---------{4877<:..xxlld.@yxwlnsvxyyyyxvsnllllhqtwyyyyyyy>.kuuuuuu\ +uuuuuuuuu;.h ", +" q..go077778882{{^)))..xxtt9.~xxxllllllqtxyyyyxvsnlllllqtxyyy+.uuuuuuu\ +uuuuuuuu!..t ", +" 9.+mr788877788_{)))..xxxv/.9xxxxvtqllllllqtxyyyyxvsnlllnyys.*uuuuuuu\ +uupuuuu!.+n ", +" 9.+mr777777782_{\')..xxll%.qvxvxxxxxxtqnlllllqtxyyyyxvqvyy9.}uuuuuu\ +uuuuuuu~..n ", +" 9.+mr728872782{{)..xxsl.@vxthhnqtxxxxxxtqllllllqtxyyyyyy~.epuuuxuu\ +uuuuu!..n ", +" 9.+er778787882_{..xxxd.~vvvnlllhhlqtvxxxxxtqnlllllqvyyy+.fouuuuuu\ +uuuu/..q ", +" 9..6r778787778{,.xyl>.9ttvvttqnlllllnqtxxxxxxtqllllyyq.#afguuuuu\ +uuu!.+n ", +" 9..6r777788787{{xxq%.nttttttvvvtqnllllhlqtxxxxxxttxx9.&)afguuuu\ +xu!..n ", +" 9+.6r828777788{}xv.@stshllnqtvvtvvtqnllhhhlqtxxxxxx>.-^)afeuuu\ +u!..n ", +" 9..6r778277888{63.>sstnllllhlnqsttvvvtqnlllhhlsxxx+.)))^afguu\ +!.........+/ ", +" 9.+6r877887778{,.3qqqqssnnllllllnqtvvvvvtqnllhxvn.#)))))afo!\ +............n ", +" 9..6r077778788{{dqqnnqsqssqqnlllhllnqttvvvvttvv3.&))))^5fff\ +ffffioru4;@.h ", +" 9..ir772878778{}nnllllnnqqqqssnnllllllnqtvtvvv>.-^1affffff\ +foour6!@...= ", +" =.)ir877778888{}nnlllllllnnqqssqqqnllllllnvvt$,affffffgou\ +ue}%...+>9q ", +" =.^)fu087877778{}lnnnnlllllllnnqqqqsqqnlllpkgfffffioourg;\ +....=|n ", +" =.:^)fu077778788{}llnnnnnnlllllllnnqqqpmgffffffoorumf11{.\ +@/dt ", +" =.<:))fu028778787{}lllnnlnnnnnlllljegfgffffioruoga^1^:^\'\ +.| ", +" =.8<1^)fu072777788{}lllnlnnlnnjkgfffffffoouuoa1:::::_::\'\ +.| ", +" =.782:^)au087878778{}dlhlhjpefffffffioruog1^^1:1^1:::11^.\ +| ", +" =.088<1^)ai878788788{}npmofooooiooouroa1:1:1_^::1_:2278(.\ +| ", +" =.70802<^)^)))))))))){aooooooomooog1{1:::::[:1[[2772787(.\ +| ", +" =.008082<<<<<<<<1<<1i1<1^^^^1^11^11::::1_[1[25787888782(.\ +| ", +" =.800008222222222222r1:7211::::::::11[[[222877772777777(.\ +| ", +" =.8080b0022222222280r1:8821:1_1:1[[[1182887878777778788(.\ +| ", +" =.08b08b888227277b0cr1<77772[:[[1[587777772787888827877(.\ +| ", +" =.b8b08cb0882728bba0r1<788878[5777787887787777777787728(.\ +| ", +" =.800808b8c888bc8c0cr1<87778777887778772878727777877877(.\ +| ", +" =.5c8cc8c00008bbacaco1<77777877728777787772888287727872(.\ +| ", +" /.#8a08c8bcbcc8c000cr1<82878727877872877877777777887778(.\ +| ", +" ~.#500c8c8abaccccccr1<77827787877877787887778787787878^.\ +| ", +" ~.#5c8cac0c08ca8car1<28777877287787872778287277772787(.\ +| ", +" ~.#5c00cacccccc0ar1<77787787782782777777778788778728(.\ +| ", +" /.#5ccc00aaacaccr1[78872877777777788878787277887877(.\ +| ", +" ~.#5ccc0ccc0ccar1[77777788788778772778727777277878(.\ +| ", +" ~.#5acc0ccfaccr[[77887272872887777287778887777727(.\ +| ", +" ~.#accca0cccar1<27788787787728870728777787827787(.\ +| ", +" ~.#5cccacaccr1[77277777777787787787877728778827(.\ +| ", +" ~.#5ccccffar1[87778788287777728777828778877788^.\ +| ", +" /.#accfcccr[[77887727878728787287777777777[-#..\ +3 ", +" ~.#acaffar1<8727877777887777078288787(\'$+....\ +/t ", +" ~.#accccr([7778778772772877727022\'&+....>3n \ + ", +" ~.#afffr1<877287887770788272(&+....=|h \ + ", +" ~.#aafr[[78787727887722(-#....%/dt \ + ", +" ~.#afr1<2777877728(-#....@~dt \ + ", +" ~.#ar[[787777(-&....+~9q \ + ", +" ~.#m:<78(\'$+...+>3n \ + ", +" ~.#(\'&++...=|n \ + ", +" ~.....%/h \ + ", +" |=/dt \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + " +}; +static Fl_Pixmap image_default(idata_default); + +Fl_Button *PrevButton=(Fl_Button *)0; + +static void cb_PrevButton(Fl_Button*, void*) { + Wizard->prev(); + +int i; + +for (i = 0; i < 6; i ++) +{ + Title[i]->activate(); + + if (Pane[i]->visible()) + break; +} + +for (i ++; i < 6; i ++) + Title[i]->deactivate(); +} + +Fl_Button *NextButton=(Fl_Button *)0; + +Fl_Button *CancelButton=(Fl_Button *)0; + +static void cb_CancelButton(Fl_Button*, void*) { + exit(0); +} + +Fl_Double_Window* make_window() { + { SetupWindow = new Fl_Double_Window(640, 330, "Install"); + SetupWindow->callback((Fl_Callback*)cb_SetupWindow); + { Title[0] = new Fl_Box(10, 10, 130, 25, "Welcome"); + Title[0]->labelfont(1); + Title[0]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* Title[0] + { Title[1] = new Fl_Box(10, 35, 130, 25, "Install Type"); + Title[1]->labelfont(1); + Title[1]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[1]->deactivate(); + } // Fl_Box* Title[1] + { Title[2] = new Fl_Box(10, 60, 130, 25, "Select Software"); + Title[2]->labelfont(1); + Title[2]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[2]->deactivate(); + } // Fl_Box* Title[2] + { Title[3] = new Fl_Box(10, 85, 130, 25, "Confirm"); + Title[3]->labelfont(1); + Title[3]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[3]->deactivate(); + } // Fl_Box* Title[3] + { Title[4] = new Fl_Box(10, 110, 130, 25, "License"); + Title[4]->labelfont(1); + Title[4]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[4]->deactivate(); + } // Fl_Box* Title[4] + { Title[5] = new Fl_Box(10, 135, 130, 25, "Installing"); + Title[5]->labelfont(1); + Title[5]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[5]->deactivate(); + } // Fl_Box* Title[5] + { Wizard = new Fl_Wizard(150, 10, 480, 275); + Wizard->box(FL_THIN_DOWN_BOX); + Wizard->color((Fl_Color)48); + { Pane[0] = new Fl_Group(150, 10, 480, 275); + Pane[0]->labelfont(1); + Pane[0]->labelsize(18); + Pane[0]->labelcolor((Fl_Color)4); + Pane[0]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[0]->hide(); + { ReadmeFile = new Fl_Help_View(170, 30, 440, 235); + } // Fl_Help_View* ReadmeFile + Pane[0]->end(); + } // Fl_Group* Pane[0] + { Pane[1] = new Fl_Group(150, 10, 480, 275); + Pane[1]->labelfont(1); + Pane[1]->labelsize(18); + Pane[1]->labelcolor((Fl_Color)4); + Pane[1]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[1]->hide(); + { Fl_Box* o = new Fl_Box(170, 30, 440, 25, "Select the installation type:"); + o->align(132|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(170, 65, 440, 200); + { TypeButton[0] = new Fl_Round_Button(170, 65, 440, 25); + TypeButton[0]->type(102); + TypeButton[0]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[0]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[0] + { TypeButton[1] = new Fl_Round_Button(170, 90, 440, 25); + TypeButton[1]->type(102); + TypeButton[1]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[1]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[1] + { TypeButton[2] = new Fl_Round_Button(170, 115, 440, 25); + TypeButton[2]->type(102); + TypeButton[2]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[2]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[2] + { TypeButton[3] = new Fl_Round_Button(170, 140, 440, 25); + TypeButton[3]->type(102); + TypeButton[3]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[3]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[3] + { TypeButton[4] = new Fl_Round_Button(170, 165, 440, 25); + TypeButton[4]->type(102); + TypeButton[4]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[4]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[4] + { TypeButton[5] = new Fl_Round_Button(170, 190, 440, 25); + TypeButton[5]->type(102); + TypeButton[5]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[5]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[5] + { TypeButton[6] = new Fl_Round_Button(170, 215, 440, 25); + TypeButton[6]->type(102); + TypeButton[6]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[6]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[6] + { TypeButton[7] = new Fl_Round_Button(170, 240, 440, 25); + TypeButton[7]->type(102); + TypeButton[7]->down_box(FL_ROUND_DOWN_BOX); + TypeButton[7]->callback((Fl_Callback*)type_cb); + } // Fl_Round_Button* TypeButton[7] + o->end(); + } // Fl_Group* o + Pane[1]->end(); + } // Fl_Group* Pane[1] + { Pane[2] = new Fl_Group(150, 10, 480, 275); + Pane[2]->labelfont(1); + Pane[2]->labelsize(18); + Pane[2]->labelcolor((Fl_Color)4); + Pane[2]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[2]->hide(); + { Fl_Box* o = new Fl_Box(170, 30, 440, 25, "Select the software you want to install:"); + o->align(132|FL_ALIGN_INSIDE); + } // Fl_Box* o + { SoftwareList = new Fl_Check_Browser(170, 85, 440, 145, " Available Software:"); + SoftwareList->type(3); + SoftwareList->box(FL_DOWN_BOX); + SoftwareList->selection_color(FL_BACKGROUND2_COLOR); + SoftwareList->labelfont(1); + SoftwareList->callback((Fl_Callback*)list_cb); + SoftwareList->align(FL_ALIGN_TOP_LEFT); + SoftwareList->when(3); + } // Fl_Check_Browser* SoftwareList + { SoftwareSize = new Fl_Box(170, 235, 241, 35, "0k marked for installation."); + SoftwareSize->align(196|FL_ALIGN_INSIDE); + } // Fl_Box* SoftwareSize + { InstallAllButton = new Fl_Button(421, 240, 80, 25, "Install All"); + InstallAllButton->callback((Fl_Callback*)cb_InstallAllButton); + } // Fl_Button* InstallAllButton + { InstallNoneButton = new Fl_Button(511, 240, 99, 25, "Install None"); + InstallNoneButton->callback((Fl_Callback*)cb_InstallNoneButton); + } // Fl_Button* InstallNoneButton + Pane[2]->end(); + } // Fl_Group* Pane[2] + { Pane[3] = new Fl_Group(150, 10, 480, 275); + Pane[3]->labelfont(1); + Pane[3]->labelsize(18); + Pane[3]->labelcolor((Fl_Color)4); + Pane[3]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[3]->hide(); + { Fl_Box* o = new Fl_Box(170, 30, 440, 25, "Confirm your software selections below:"); + o->align(132|FL_ALIGN_INSIDE); + } // Fl_Box* o + { ConfirmList = new Fl_Browser(170, 85, 440, 180, "Selected Software:"); + ConfirmList->labelfont(1); + ConfirmList->align(FL_ALIGN_TOP_LEFT); + } // Fl_Browser* ConfirmList + Pane[3]->end(); + } // Fl_Group* Pane[3] + { Pane[4] = new Fl_Group(150, 10, 480, 275); + Pane[4]->labelfont(1); + Pane[4]->labelsize(18); + Pane[4]->labelcolor((Fl_Color)4); + Pane[4]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { LicenseFile = new Fl_Help_View(170, 48, 440, 192, "License Agreement:"); + LicenseFile->labelfont(1); + LicenseFile->align(FL_ALIGN_TOP_LEFT); + Fl_Group::current()->resizable(LicenseFile); + } // Fl_Help_View* LicenseFile + { Fl_Group* o = new Fl_Group(170, 240, 400, 35); + { LicenseAccept = new Fl_Round_Button(210, 250, 210, 25, "Accept agreement and install"); + LicenseAccept->type(102); + LicenseAccept->down_box(FL_ROUND_DOWN_BOX); + LicenseAccept->callback((Fl_Callback*)cb_LicenseAccept); + LicenseAccept->align(132|FL_ALIGN_INSIDE); + } // Fl_Round_Button* LicenseAccept + { LicenseDecline = new Fl_Round_Button(430, 250, 140, 25, "Cancel installation"); + LicenseDecline->type(102); + LicenseDecline->down_box(FL_ROUND_DOWN_BOX); + LicenseDecline->callback((Fl_Callback*)cb_LicenseDecline); + } // Fl_Round_Button* LicenseDecline + o->end(); + } // Fl_Group* o + Pane[4]->end(); + } // Fl_Group* Pane[4] + { Pane[5] = new Fl_Group(150, 10, 480, 275); + Pane[5]->labelfont(1); + Pane[5]->labelsize(18); + Pane[5]->labelcolor((Fl_Color)4); + Pane[5]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[5]->hide(); + { InstallPercent = new Fl_Progress(170, 47, 440, 15, "Progress Label..."); + InstallPercent->color((Fl_Color)48); + InstallPercent->selection_color((Fl_Color)221); + InstallPercent->align(FL_ALIGN_TOP_LEFT); + } // Fl_Progress* InstallPercent + { InstallLog = new Fl_Browser(170, 74, 440, 191); + } // Fl_Browser* InstallLog + Pane[5]->end(); + } // Fl_Group* Pane[5] + Wizard->end(); + } // Fl_Wizard* Wizard + { WelcomeImage = new Fl_Box(10, 190, 130, 130); + WelcomeImage->image(image_default); + WelcomeImage->align(FL_ALIGN_BOTTOM_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* WelcomeImage + { PrevButton = new Fl_Button(396, 295, 72, 25, "@-2< Back"); + PrevButton->callback((Fl_Callback*)cb_PrevButton); + } // Fl_Button* PrevButton + { NextButton = new Fl_Button(478, 295, 74, 25, "Next @-2>"); + NextButton->callback((Fl_Callback*)next_cb); + } // Fl_Button* NextButton + { CancelButton = new Fl_Button(562, 295, 68, 25, "Cancel"); + CancelButton->callback((Fl_Callback*)cb_CancelButton); + } // Fl_Button* CancelButton + SetupWindow->end(); + } // Fl_Double_Window* SetupWindow + return SetupWindow; +} diff --git a/setup.fl b/setup.fl new file mode 100644 index 0000000..03936ab --- /dev/null +++ b/setup.fl @@ -0,0 +1,199 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 +header_name {.h} +code_name {.cxx} +Function {make_window()} {open +} { + Fl_Window SetupWindow { + label Install + callback {if (CancelButton->active()) + exit(0);} open + xywh {167 20 640 330} type Double + code0 {\#include "gui-common.h"} visible + } { + Fl_Box {Title[0]} { + label Welcome + xywh {10 10 130 25} labelfont 1 align 20 + } + Fl_Box {Title[1]} { + label {Install Type} + xywh {10 35 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[2]} { + label {Select Software} + xywh {10 60 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[3]} { + label Confirm + xywh {10 85 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[4]} { + label License + xywh {10 110 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[5]} { + label Installing + xywh {10 135 130 25} labelfont 1 align 20 deactivate + } + Fl_Wizard Wizard {open + xywh {150 10 480 275} box THIN_DOWN_BOX color 48 + } { + Fl_Group {Pane[0]} {open + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Help_View ReadmeFile { + xywh {170 30 440 235} + } + } + Fl_Group {Pane[1]} { + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Box {} { + label {Select the installation type:} + xywh {170 30 440 25} align 148 + } + Fl_Group {} { + xywh {170 65 440 200} + } { + Fl_Round_Button {TypeButton[0]} { + callback type_cb + xywh {170 65 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[1]} { + callback type_cb + xywh {170 90 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[2]} { + callback type_cb + xywh {170 115 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[3]} { + callback type_cb + xywh {170 140 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[4]} { + callback type_cb + xywh {170 165 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[5]} { + callback type_cb + xywh {170 190 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[6]} { + callback type_cb + xywh {170 215 440 25} type Radio down_box ROUND_DOWN_BOX + } + Fl_Round_Button {TypeButton[7]} { + callback type_cb + xywh {170 240 440 25} type Radio down_box ROUND_DOWN_BOX + } + } + } + Fl_Group {Pane[2]} { + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Box {} { + label {Select the software you want to install:} + xywh {170 30 440 25} align 148 + } + Fl_Check_Browser SoftwareList { + label { Available Software:} + callback list_cb + xywh {170 85 440 145} type Multi box DOWN_BOX selection_color 7 labelfont 1 align 5 when 3 + } + Fl_Box SoftwareSize { + label {0k marked for installation.} + xywh {170 235 241 35} align 212 + } + Fl_Button InstallAllButton { + label {Install All} + callback {SoftwareList->check_all(); +list_cb(0,0);} + xywh {421 240 80 25} + } + Fl_Button InstallNoneButton { + label {Install None} + callback {SoftwareList->check_none(); +list_cb(0,0);} + xywh {511 240 99 25} + } + } + Fl_Group {Pane[3]} {open + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Box {} { + label {Confirm your software selections below:} + xywh {170 30 440 25} align 148 + } + Fl_Browser ConfirmList { + label {Selected Software:} + xywh {170 85 440 180} labelfont 1 align 5 + } + } + Fl_Group {Pane[4]} {open + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 + } { + Fl_Help_View LicenseFile { + label {License Agreement:} selected + xywh {170 48 440 192} labelfont 1 align 5 resizable + } + Fl_Group {} {open + xywh {170 240 400 35} + } { + Fl_Round_Button LicenseAccept { + label {Accept agreement and install} + callback {NextButton->activate();} + xywh {210 250 210 25} type Radio down_box ROUND_DOWN_BOX align 148 + } + Fl_Round_Button LicenseDecline { + label {Cancel installation} + callback {NextButton->activate();} + xywh {430 250 140 25} type Radio down_box ROUND_DOWN_BOX + } + } + } + Fl_Group {Pane[5]} {open + xywh {150 10 480 275} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Progress InstallPercent { + label {Progress Label...} + xywh {170 47 440 15} color 48 selection_color 221 align 5 + } + Fl_Browser InstallLog { + xywh {170 74 440 191} + } + } + } + Fl_Box WelcomeImage { + image {default.xpm} xywh {10 190 130 130} align 22 + } + Fl_Button PrevButton { + label {@-2< Back} + callback {Wizard->prev(); + +int i; + +for (i = 0; i < 6; i ++) +{ + Title[i]->activate(); + + if (Pane[i]->visible()) + break; +} + +for (i ++; i < 6; i ++) + Title[i]->deactivate();} + xywh {396 295 72 25} + } + Fl_Button NextButton { + label {Next @-2>} + callback next_cb + xywh {478 295 74 25} + } + Fl_Button CancelButton { + label Cancel + callback {exit(0);} + xywh {562 295 68 25} + } + } +} @@ -0,0 +1,41 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#ifndef setup_h +#define setup_h +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> +#include "gui-common.h" +extern Fl_Double_Window *SetupWindow; +#include <FL/Fl_Box.H> +extern Fl_Box *Title[6]; +#include <FL/Fl_Wizard.H> +extern Fl_Wizard *Wizard; +#include <FL/Fl_Group.H> +#include <FL/Fl_Help_View.H> +extern Fl_Help_View *ReadmeFile; +#include <FL/Fl_Round_Button.H> +extern void type_cb(Fl_Round_Button*, void*); +extern Fl_Round_Button *TypeButton[8]; +#include <FL/Fl_Check_Browser.H> +extern void list_cb(Fl_Check_Browser*, void*); +extern Fl_Check_Browser *SoftwareList; +extern Fl_Box *SoftwareSize; +#include <FL/Fl_Button.H> +extern Fl_Button *InstallAllButton; +extern Fl_Button *InstallNoneButton; +#include <FL/Fl_Browser.H> +extern Fl_Browser *ConfirmList; +extern Fl_Help_View *LicenseFile; +extern Fl_Round_Button *LicenseAccept; +extern Fl_Round_Button *LicenseDecline; +extern Fl_Group *Pane[6]; +#include <FL/Fl_Progress.H> +extern Fl_Progress *InstallPercent; +extern Fl_Browser *InstallLog; +extern Fl_Box *WelcomeImage; +extern Fl_Button *PrevButton; +extern void next_cb(Fl_Button*, void*); +extern Fl_Button *NextButton; +extern Fl_Button *CancelButton; +Fl_Double_Window* make_window(); +#endif diff --git a/setup2.cxx b/setup2.cxx new file mode 100644 index 0000000..0969ac3 --- /dev/null +++ b/setup2.cxx @@ -0,0 +1,1220 @@ +// +// "$Id: setup2.cxx 834 2010-12-30 00:08:36Z mike $" +// +// ESP Software Installation Wizard main entry for the ESP Package Manager (EPM). +// +// Copyright 1999-2010 by Easy Software Products. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Contents: +// +// main() - Main entry for software wizard... +// get_dists() - Get a list of available software products. +// install_dist() - Install a distribution... +// license_dist() - Show the license for a distribution... +// list_cb() - Handle selections in the software list. +// load_image() - Load the setup image file (setup.gif/xpm)... +// load_readme() - Load the readme file... +// load_types() - Load the installation types from the setup.types file. +// log_cb() - Add one or more lines of text to the installation log. +// next_cb() - Show software selections or install software. +// type_cb() - Handle selections in the type list. +// update_size() - Update the total +/- sizes of the installations. +// + +#define _DEFINE_GLOBALS_ +#include "setup.h" +#include <FL/Fl_GIF_Image.H> +#include <FL/Fl_XPM_Image.H> +#include <FL/x.H> +#include <FL/filename.H> +#include <FL/fl_ask.H> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif // HAVE_SYS_PARAM_H + +#ifdef HAVE_SYS_MOUNT_H +# include <sys/mount.h> +#endif // HAVE_SYS_MOUNT_H + +#ifdef HAVE_SYS_STATFS_H +# include <sys/statfs.h> +#endif // HAVE_SYS_STATFS_H + +#ifdef HAVE_SYS_VFS_H +# include <sys/vfs.h> +#endif // HAVE_SYS_VFS_H + +#ifdef __osf__ +// No prototype for statfs under Tru64... +extern "C" { +extern int statfs(const char *, struct statfs *); +} +#endif // __osf__ + +#ifdef __APPLE__ +# include <Security/Authorization.h> +# include <Security/AuthorizationTags.h> + +AuthorizationRef SetupAuthorizationRef; +#endif // __APPLE__ + + +// +// Panes... +// + +#define PANE_WELCOME 0 +#define PANE_TYPE 1 +#define PANE_SELECT 2 +#define PANE_CONFIRM 3 +#define PANE_LICENSE 4 +#define PANE_INSTALL 5 + + +// +// Define a C API function type for comparisons... +// + +extern "C" { +typedef int (*compare_func_t)(const void *, const void *); +} + + +// +// Local functions... +// + +void get_dists(const char *d); +int install_dist(const gui_dist_t *dist); +int license_dist(const gui_dist_t *dist); +void load_image(void); +void load_readme(void); +void load_types(void); +void log_cb(int fd, int *fdptr); +void update_sizes(void); + + +// +// 'main()' - Main entry for software wizard... +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + Fl_Window *w; // Main window... + const char *distdir; // Distribution directory + + + // Use GTK+ scheme for all operating systems... + Fl::background(230, 230, 230); + Fl::scheme("gtk+"); + +#ifdef __APPLE__ + // OSX passes an extra command-line option when run from the Finder. + // If the first command-line argument is "-psn..." then skip it and use the full path + // to the executable to figure out the distribution directory... + if (argc > 1) + { + if (strncmp(argv[1], "-psn", 4) == 0) + { + char *ptr; // Pointer into basedir + static char basedir[1024]; // Base directory (static so it can be used below) + + + strlcpy(basedir, argv[0], sizeof(basedir)); + if ((ptr = strrchr(basedir, '/')) != NULL) + *ptr = '\0'; + if ((ptr = strrchr(basedir, '/')) != NULL && !strcasecmp(ptr, "/MacOS")) + { + // Got the base directory, now add "Resources" to it... + *ptr = '\0'; + strlcat(basedir, "/Resources", sizeof(basedir)); + distdir = basedir; + chdir(basedir); + } + else + distdir = "."; + + } + else + distdir = argv[1]; + } + else + distdir = "."; +#else + // Get the directory that has the software in it... + if (argc > 1) + distdir = argv[1]; + else + distdir = "."; +#endif // __APPLE__ + + w = make_window(); + + Pane[PANE_WELCOME]->show(); + PrevButton->deactivate(); + NextButton->deactivate(); + + gui_get_installed(); + get_dists(distdir); + + load_image(); + load_readme(); + load_types(); + + w->show(); + + while (!w->visible()) + Fl::wait(); + +#ifdef __APPLE__ + OSStatus status; + + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, + kAuthorizationFlagDefaults, + &SetupAuthorizationRef); + if (status != errAuthorizationSuccess) + { + fl_alert("You must have administrative priviledges to install this software!"); + return (1); + } + + AuthorizationItem items = { kAuthorizationRightExecute, 0, NULL, 0 }; + AuthorizationRights rights = { 1, &items }; + + status = AuthorizationCopyRights(SetupAuthorizationRef, &rights, NULL, + kAuthorizationFlagDefaults | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize | + kAuthorizationFlagExtendRights, NULL); + + if (status != errAuthorizationSuccess) + { + fl_alert("You must have administrative priviledges to install this software!"); + return (1); + } +#else + if (getuid() != 0) + { + fl_alert("You must be logged in as root to run setup!"); + return (1); + } +#endif // __APPLE__ + + NextButton->activate(); + + Fl::run(); + +#ifdef __APPLE__ + AuthorizationFree(SetupAuthorizationRef, kAuthorizationFlagDefaults); +#endif // __APPLE__ + + return (0); +} + + +// +// 'get_dists()' - Get a list of available software products. +// + +void +get_dists(const char *d) // I - Directory to look in +{ + int i; // Looping var + int num_files; // Number of files + dirent **files; // Files + const char *ext; // Extension + gui_dist_t *temp, // Pointer to current distribution + *installed; // Pointer to installed product + FILE *fp; // File to read from + char line[1024], // Line from file... + product[64]; // Product name... + int lowver, hiver; // Version numbers for dependencies + + + // Get the files in the specified directory... + if (chdir(d)) + { + perror("setup: Unable to change to distribution directory"); + exit(1); + } + + if ((num_files = fl_filename_list(".", &files)) == 0) + { + fputs("setup: Error - no software products found!\n", stderr); + exit(1); + } + + // Build a distribution list... + NumDists = 0; + Dists = (gui_dist_t *)0; + + for (i = 0; i < num_files; i ++) + { + ext = fl_filename_ext(files[i]->d_name); + if (!strcmp(ext, ".install") || !strcmp(ext, ".patch")) + { + // Found a .install script... + if ((fp = fopen(files[i]->d_name, "r")) == NULL) + { + perror("setup: Unable to open installation script"); + exit(1); + } + + // Add a new distribution entry... + temp = gui_add_dist(&NumDists, &Dists); + temp->type = PACKAGE_PORTABLE; + temp->filename = strdup(files[i]->d_name); + + strncpy(temp->product, files[i]->d_name, sizeof(temp->product) - 1); + *strrchr(temp->product, '.') = '\0'; // Drop .install + + // Read info from the installation script... + while (fgets(line, sizeof(line), fp) != NULL) + { + // Only read distribution info lines... + if (strncmp(line, "#%", 2)) + continue; + + // Drop the trailing newline... + line[strlen(line) - 1] = '\0'; + + // Copy data as needed... + if (strncmp(line, "#%product ", 10) == 0) + strncpy(temp->name, line + 10, sizeof(temp->name) - 1); + else if (strncmp(line, "#%version ", 10) == 0) + sscanf(line + 10, "%31s%d", temp->version, &(temp->vernumber)); + else if (strncmp(line, "#%rootsize ", 11) == 0) + temp->rootsize = atoi(line + 11); + else if (strncmp(line, "#%usrsize ", 10) == 0) + temp->usrsize = atoi(line + 10); + else if (strncmp(line, "#%incompat ", 11) == 0 || + strncmp(line, "#%requires ", 11) == 0) + { + lowver = 0; + hiver = 0; + + if (sscanf(line + 11, "%s%*s%d%*s%d", product, &lowver, &hiver) > 0) + gui_add_depend(temp, (line[2] == 'i') ? DEPEND_INCOMPAT : + DEPEND_REQUIRES, + product, lowver, hiver); + } + } + + fclose(fp); + } + else if (!strcmp(ext, ".rpm")) + { + // Found an RPM package... + char *version, // Version number + *size, // Size of package + *description; // Summary string + + + // Get the package information... + snprintf(line, sizeof(line), + "rpm -qp --qf '%%{NAME}|%%{VERSION}|%%{SIZE}|%%{SUMMARY}\\n' %s", + files[i]->d_name); + + if ((fp = popen(line, "r")) == NULL) + { + free(files[i]); + continue; + } + + if (!fgets(line, sizeof(line), fp)) + { + free(files[i]); + continue; + } + + // Drop the trailing newline... + line[strlen(line) - 1] = '\0'; + + // Grab the different fields... + if ((version = strchr(line, '|')) == NULL) + continue; + *version++ = '\0'; + + if ((size = strchr(version, '|')) == NULL) + continue; + *size++ = '\0'; + + if ((description = strchr(size, '|')) == NULL) + continue; + *description++ = '\0'; + + // Add a new distribution entry... + temp = gui_add_dist(&NumDists, &Dists); + temp->type = PACKAGE_RPM; + temp->filename = strdup(files[i]->d_name); + + strlcpy(temp->product, line, sizeof(temp->product)); + strlcpy(temp->name, description, sizeof(temp->name)); + strlcpy(temp->version, version, sizeof(temp->version)); + temp->vernumber = get_vernumber(version); + temp->rootsize = (int)(atof(size) / 1024.0 + 0.5); + + pclose(fp); + } + + free(files[i]); + } + + free(files); + + if (NumDists == 0) + { + fl_alert("No software found to install!"); + exit(1); + } + + if (NumDists > 1) + qsort(Dists, NumDists, sizeof(gui_dist_t), (compare_func_t)gui_sort_dists); + + for (i = 0, temp = Dists; i < NumDists; i ++, temp ++) + { + sprintf(line, "%s v%s", temp->name, temp->version); + + if ((installed = gui_find_dist(temp->product, NumInstalled, + Installed)) == NULL) + { + strcat(line, " (new)"); + SoftwareList->add(line, 0); + } + else if (installed->vernumber > temp->vernumber) + { + strcat(line, " (downgrade)"); + SoftwareList->add(line, 0); + } + else if (installed->vernumber == temp->vernumber) + { + strcat(line, " (installed)"); + SoftwareList->add(line, 0); + } + else + { + strcat(line, " (upgrade)"); + SoftwareList->add(line, 1); + } + } + + update_sizes(); +} + + +// +// 'install_dist()' - Install a distribution... +// + +int // O - Install status +install_dist(const gui_dist_t *dist) // I - Distribution to install +{ + char command[1024]; // Command string + int fds[2]; // Pipe FDs + int status; // Exit status +#ifndef __APPLE__ + int pid; // Process ID +#endif // !__APPLE__ + + + sprintf(command, "**** %s ****", dist->name); + InstallLog->add(command); + +#ifdef __APPLE__ + // Run the install script using Apple's authorization API... + FILE *fp = NULL; + char *args[2] = { (char *)"now", NULL }; + OSStatus astatus; + + + astatus = AuthorizationExecuteWithPrivileges(SetupAuthorizationRef, + dist->filename, + kAuthorizationFlagDefaults, + args, &fp); + + if (astatus != errAuthorizationSuccess) + { + InstallLog->add("Failed to execute install script!"); + return (1); + } + + fds[0] = fileno(fp); +#else + // Fork the command and redirect errors and info to stdout... + pipe(fds); + + if ((pid = fork()) == 0) + { + // Child comes here; start by redirecting stdout and stderr... + close(1); + close(2); + dup(fds[1]); + dup(fds[1]); + + // Close the original pipes... + close(fds[0]); + close(fds[1]); + + // Execute the command; if an error occurs, return it... + if (dist->type == PACKAGE_PORTABLE) + execl(dist->filename, dist->filename, "now", (char *)0); + else + execlp("rpm", "rpm", "-U", "--nodeps", dist->filename, (char *)0); + + exit(errno); + } + else if (pid < 0) + { + // Unable to fork! + sprintf(command, "Unable to install %s:", dist->name); + InstallLog->add(command); + + sprintf(command, "\t%s", strerror(errno)); + InstallLog->add(command); + + close(fds[0]); + close(fds[1]); + + return (1); + } + + // Close the output pipe (used by the child)... + close(fds[1]); +#endif // __APPLE__ + + // Listen for data on the input pipe... + Fl::add_fd(fds[0], (void (*)(int, void *))log_cb, fds); + + // Show the user that we're busy... + SetupWindow->cursor(FL_CURSOR_WAIT); + + // Loop until the child is done... + while (fds[0]) // log_cb() will close and zero fds[0]... + { + // Wait for events... + Fl::wait(); + +#ifndef __APPLE__ + // Check to see if the child went away... + if (waitpid(0, &status, WNOHANG) == pid) + break; +#endif // !__APPLE__ + } + +#ifdef __APPLE__ + fclose(fp); +#endif // __APPLE__ + + if (fds[0]) + { + // Close the pipe - have all the data from the child... + Fl::remove_fd(fds[0]); + close(fds[0]); + } + else + { + // Get the child's exit status... + wait(&status); + } + + // Show the user that we're ready... + SetupWindow->cursor(FL_CURSOR_DEFAULT); + + // Return... + return (status); +} + + +// +// 'license_dist()' - Show the license for a distribution... +// + +int // O - 0 if accepted, 1 if not +license_dist(const gui_dist_t *dist) // I - Distribution to license +{ + char licfile[1024]; // License filename + struct stat licinfo; // License file info + static int liclength = 0; // Size of license file + static char liclabel[1024]; // Label for license pane + + + // See if we need to show the license file... + sprintf(licfile, "%s.license", dist->product); + if (!stat(licfile, &licinfo) && licinfo.st_size != liclength) + { + // Save this license's length... + liclength = licinfo.st_size; + + // Set the title string... + snprintf(liclabel, sizeof(liclabel), "Software License for %s:", dist->name); + LicenseFile->label(liclabel); + + // Load the license into the viewer... + LicenseFile->textfont(FL_HELVETICA); + LicenseFile->textsize(14); + + gui_load_file(LicenseFile, licfile); + + // Show the license window and wait for the user... + Pane[PANE_LICENSE]->show(); + Title[PANE_LICENSE]->activate(); + LicenseAccept->clear(); + LicenseDecline->clear(); + NextButton->deactivate(); + CancelButton->activate(); + + while (Pane[PANE_LICENSE]->visible()) + Fl::wait(); + + Title[PANE_INSTALL]->deactivate(); + + CancelButton->deactivate(); + NextButton->deactivate(); + + if (LicenseDecline->value()) + { + // Can't install without acceptance... + char message[1024]; // Message for log + + + liclength = 0; + snprintf(message, sizeof(message), "License not accepted for %s!", + dist->name); + InstallLog->add(message); + return (1); + } + } + + return (0); +} + + +// +// 'list_cb()' - Handle selections in the software list. +// + +void +list_cb(Fl_Check_Browser *, void *) +{ + int i, j, k; + gui_dist_t *dist, + *dist2; + gui_depend_t *depend; + + + if (SoftwareList->nchecked() == 0) + { + update_sizes(); + + NextButton->deactivate(); + return; + } + + for (i = 0, dist = Dists; i < NumDists; i ++, dist ++) + if (SoftwareList->checked(i + 1)) + { + // Check for required/incompatible products... + for (j = 0, depend = dist->depends; j < dist->num_depends; j ++, depend ++) + switch (depend->type) + { + case DEPEND_REQUIRES : + if ((dist2 = gui_find_dist(depend->product, NumDists, + Dists)) != NULL) + { + // Software is in the list, is it selected? + k = dist2 - Dists; + + if (SoftwareList->checked(k + 1)) + continue; + + // Nope, select it unless we're unchecked another selection... + if (SoftwareList->value() != (k + 1)) + SoftwareList->checked(k + 1, 1); + else + { + SoftwareList->checked(i + 1, 0); + break; + } + } + else if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) == NULL) + { + // Required but not installed or available! + fl_alert("%s requires %s to be installed, but it is not available " + "for installation.", dist->name, depend->product); + SoftwareList->checked(i + 1, 0); + break; + } + break; + + case DEPEND_INCOMPAT : + if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) != NULL) + { + // Already installed! + fl_alert("%s is incompatible with %s. Please remove it before " + "installing this software.", dist->name, dist2->name); + SoftwareList->checked(i + 1, 0); + break; + } + else if ((dist2 = gui_find_dist(depend->product, NumDists, + Dists)) != NULL) + { + // Software is in the list, is it selected? + k = dist2 - Dists; + + // Software is in the list, is it selected? + if (!SoftwareList->checked(k + 1)) + continue; + + // Yes, tell the user... + fl_alert("%s is incompatible with %s. Please deselect it before " + "installing this software.", dist->name, dist2->name); + SoftwareList->checked(i + 1, 0); + break; + } + default : + break; + } + } + + update_sizes(); + + if (SoftwareList->nchecked()) + NextButton->activate(); + else + NextButton->deactivate(); +} + + +// +// 'load_image()' - Load the setup image file (setup.gif/xpm)... +// + +void +load_image(void) +{ + Fl_Image *img; // New image + + + if (!access("setup.xpm", 0)) + img = new Fl_XPM_Image("setup.xpm"); + else if (!access("setup.gif", 0)) + img = new Fl_GIF_Image("setup.gif"); + else + img = NULL; + + if (img) + WelcomeImage->image(img); +} + + +// +// 'load_readme()' - Load the readme file... +// + +void +load_readme(void) +{ + ReadmeFile->textfont(FL_HELVETICA); + ReadmeFile->textsize(14); + + if (access("setup.readme", 0)) + { + int i; // Looping var + gui_dist_t *dist; // Current distribution + char *buffer, // Text buffer + *ptr; // Pointer into buffer + + + buffer = new char[1024 + NumDists * 300]; + + strcpy(buffer, + "This program allows you to install the following software:\n" + "<ul>\n"); + ptr = buffer + strlen(buffer); + + for (i = NumDists, dist = Dists; i > 0; i --, dist ++) + { + sprintf(ptr, "<li>%s, %s\n", dist->name, dist->version); + ptr += strlen(ptr); + } + + strcpy(ptr, "</ul>"); + + ReadmeFile->value(buffer); + + delete[] buffer; + } + else + gui_load_file(ReadmeFile, "setup.readme"); + +} + + +// +// 'load_types()' - Load the installation types from the setup.types file. +// + +void +load_types(void) +{ + int i; // Looping var + FILE *fp; // File to read from + char line[1024], // Line from file + *lineptr, // Pointer into line + *sep; // Separator + gui_intype_t *dt; // Current install type + gui_dist_t *dist; // Distribution + + + NumInstTypes = 0; + + if ((fp = fopen("setup.types", "r")) != NULL) + { + dt = NULL; + + while (fgets(line, sizeof(line), fp) != NULL) + { + if (line[0] == '#' || line[0] == '\n') + continue; + + lineptr = line + strlen(line) - 1; + if (*lineptr == '\n') + *lineptr = '\0'; + + if (!strncasecmp(line, "TYPE", 4) && isspace(line[4])) + { + // New type... + if (NumInstTypes >= (int)(sizeof(InstTypes) / sizeof(InstTypes[0]))) + { + fprintf(stderr, "setup: Too many TYPEs (> %d) in setup.types!\n", + (int)(sizeof(InstTypes) / sizeof(InstTypes[0]))); + fclose(fp); + exit(1); + } + + // Skip whitespace... + for (lineptr = line + 5; isspace(*lineptr); lineptr ++); + + // Copy name and label string... + dt = InstTypes + NumInstTypes; + NumInstTypes ++; + + memset(dt, 0, sizeof(gui_intype_t)); + if ((sep = strchr(lineptr, '/')) != NULL) + *sep++ = '\0'; + else + sep = lineptr; + + strncpy(dt->name, lineptr, sizeof(dt->name)); + strncpy(dt->label, sep, sizeof(dt->label) - 10); + } + else if (!strncasecmp(line, "INSTALL", 7) && dt && isspace(line[7])) + { + // Install a product... + if (dt->num_products >= (int)(sizeof(dt->products) / sizeof(dt->products[0]))) + { + fprintf(stderr, "setup: Too many INSTALLs (> %d) in setup.types!\n", + (int)(sizeof(dt->products) / sizeof(dt->products[0]))); + fclose(fp); + exit(1); + } + + // Skip whitespace... + for (lineptr = line + 8; isspace(*lineptr); lineptr ++); + + // Add product to list... + if ((dist = gui_find_dist(lineptr, NumDists, Dists)) != NULL) + { + dt->products[dt->num_products] = dist - Dists; + dt->num_products ++; + dt->size += dist->rootsize + dist->usrsize; + + if ((dist = gui_find_dist(lineptr, NumInstalled, Installed)) != NULL) + dt->size -= dist->rootsize + dist->usrsize; + } + else + fprintf(stderr, "setup: Unable to find product \"%s\" for \"%s\"!\n", + lineptr, dt->label); + } + else + { + fprintf(stderr, "setup: Bad line - %s\n", line); + fclose(fp); + exit(1); + } + } + + fclose(fp); + } + else + { + Title[PANE_TYPE]->hide(); + Title[PANE_SELECT]->position(10, 35); + Title[PANE_CONFIRM]->position(10, 60); + Title[PANE_LICENSE]->position(10, 85); + Title[PANE_INSTALL]->position(10, 110); + } + + for (i = 0, dt = InstTypes; i < NumInstTypes; i ++, dt ++) + { + if (dt->size >= 1024) + sprintf(dt->label + strlen(dt->label), " (+%.1fm disk space)", + dt->size / 1024.0); + else if (dt->size) + sprintf(dt->label + strlen(dt->label), " (+%dk disk space)", dt->size); + + if ((lineptr = strchr(dt->label, '/')) != NULL) + TypeButton[i]->label(lineptr + 1); + else + TypeButton[i]->label(dt->label); + + TypeButton[i]->show(); + } + + for (; i < (int)(sizeof(TypeButton) / sizeof(TypeButton[0])); i ++) + TypeButton[i]->hide(); +} + + +// +// 'log_cb()' - Add one or more lines of text to the installation log. +// + +void +log_cb(int fd, // I - Pipe to read from + int *fdptr) // O - Pipe to read from +{ + int bytes; // Bytes read/to read + char *bufptr; // Pointer into buffer + static int bufused = 0; // Number of bytes used + static char buffer[8193]; // Buffer + + + bytes = 8192 - bufused; + if ((bytes = read(fd, buffer + bufused, bytes)) <= 0) + { + // End of file; zero the FD to tell the install_dist() function to + // stop... + + Fl::remove_fd(fd); + close(fd); + *fdptr = 0; + + if (bufused > 0) + { + // Add remaining text... + buffer[bufused] = '\0'; + InstallLog->add(buffer); + bufused = 0; + } + } + else + { + // Add bytes to the buffer, then add lines as needed... + bufused += bytes; + buffer[bufused] = '\0'; + + while ((bufptr = strchr(buffer, '\n')) != NULL) + { + *bufptr++ = '\0'; + InstallLog->add(buffer); + strcpy(buffer, bufptr); + bufused -= bufptr - buffer; + } + } + + InstallLog->bottomline(InstallLog->size()); +} + + +// +// 'next_cb()' - Show software selections or install software. +// + +void +next_cb(Fl_Button *, void *) +{ + int i; // Looping var + int progress; // Progress so far... + int error; // Errors? + static char message[1024]; // Progress message... + static char install_type[1024]; // EPM_INSTALL_TYPE env variable + static int installing = 0; // Installing software? + + + Wizard->next(); + + PrevButton->deactivate(); + + if (Wizard->value() == Pane[PANE_TYPE]) + { + if (NumInstTypes == 0) + Wizard->next(); + } + else if (Wizard->value() == Pane[PANE_SELECT]) + { + if (NumInstTypes) + PrevButton->activate(); + + // Figure out which type is chosen... + for (i = 0; i < (int)(sizeof(TypeButton) / sizeof(TypeButton[0])); i ++) + if (TypeButton[i]->value()) + break; + + if (i < (int)(sizeof(TypeButton) / sizeof(TypeButton[0]))) + { + // Set the EPM_INSTALL_TYPE environment variable... + snprintf(install_type, sizeof(install_type), "EPM_INSTALL_TYPE=%s", + InstTypes[i].name); + putenv(install_type); + + // Skip product selection if this type has a list already... + if (InstTypes[i].num_products > 0) + Wizard->next(); + } + } + + if (Wizard->value() == Pane[PANE_CONFIRM]) + { + ConfirmList->clear(); + PrevButton->activate(); + + for (i = 0; i < NumDists; i ++) + if (SoftwareList->checked(i + 1)) + ConfirmList->add(SoftwareList->text(i + 1)); + } + else if (Wizard->value() == Pane[PANE_LICENSE]) + Wizard->next(); + + if (Wizard->value() == Pane[PANE_INSTALL] && !installing) + { + // Show the licenses for each of the selected software packages... + installing = 1; + + for (i = 0, progress = 0, error = 0; i < NumDists; i ++) + if (SoftwareList->checked(i + 1) && license_dist(Dists + i)) + { + InstallPercent->label("Installation Canceled!"); + Pane[PANE_INSTALL]->redraw(); + + CancelButton->label("Close"); + CancelButton->activate(); + + fl_beep(); + return; + } + + // Then do the installs... + NextButton->deactivate(); + CancelButton->deactivate(); + CancelButton->label("Close"); + + for (i = 0, progress = 0, error = 0; i < NumDists; i ++) + if (SoftwareList->checked(i + 1)) + { + sprintf(message, "Installing %s v%s...", Dists[i].name, + Dists[i].version); + + InstallPercent->value(100.0 * progress / SoftwareList->nchecked()); + InstallPercent->label(message); + Pane[PANE_INSTALL]->redraw(); + + if ((error = install_dist(Dists + i)) != 0) + break; + + progress ++; + } + + InstallPercent->value(100.0); + + if (error) + InstallPercent->label("Installation Failed!"); + else + InstallPercent->label("Installation Complete"); + + Pane[PANE_INSTALL]->redraw(); + + CancelButton->activate(); + + fl_beep(); + + installing = 0; + } + else if (Wizard->value() == Pane[PANE_SELECT] && + SoftwareList->nchecked() == 0) + NextButton->deactivate(); + + for (i = 0; i <= PANE_INSTALL; i ++) + { + Title[i]->activate(); + + if (Pane[i]->visible()) + break; + } +} + + +// +// 'type_cb()' - Handle selections in the type list. +// + +void +type_cb(Fl_Round_Button *w, void *) // I - Radio button widget +{ + int i; // Looping var + gui_intype_t *dt; // Current install type + gui_dist_t *temp, // Current software + *installed; // Installed software + + + for (i = 0; i < (int)(sizeof(TypeButton) / sizeof(TypeButton[0])); i ++) + if (w == TypeButton[i]) + break; + + if (i >= (int)(sizeof(TypeButton) / sizeof(TypeButton[0]))) + return; + + dt = InstTypes + i; + + SoftwareList->check_none(); + + // Select all products in the install type + for (i = 0; i < dt->num_products; i ++) + SoftwareList->checked(dt->products[i] + 1, 1); + + // And then any upgrade products... + for (i = 0, temp = Dists; i < NumDists; i ++, temp ++) + { + if ((installed = gui_find_dist(temp->product, NumInstalled, + Installed)) != NULL && + installed->vernumber < temp->vernumber) + SoftwareList->checked(i + 1, 1); + } + + update_sizes(); + + NextButton->activate(); +} + + +// +// 'update_size()' - Update the total +/- sizes of the installations. +// + +void +update_sizes(void) +{ + int i; // Looping var + gui_dist_t *dist, // Distribution + *installed; // Installed distribution + int rootsize, // Total root size difference in kbytes + usrsize; // Total /usr size difference in kbytes + struct statfs rootpart, // Available root partition + usrpart; // Available /usr partition + int rootfree, // Free space on root partition + usrfree; // Free space on /usr partition + static char sizelabel[1024];// Label for selected sizes... + + + // Get the sizes for the selected products... + for (i = 0, dist = Dists, rootsize = 0, usrsize = 0; + i < NumDists; + i ++, dist ++) + if (SoftwareList->checked(i + 1)) + { + rootsize += dist->rootsize; + usrsize += dist->usrsize; + + if ((installed = gui_find_dist(dist->product, NumInstalled, + Installed)) != NULL) + { + rootsize -= installed->rootsize; + usrsize -= installed->usrsize; + } + } + + // Get the sizes of the root and /usr partition... +#if defined(__sgi) || defined(__svr4__) || defined(__SVR4) || defined(M_XENIX) + if (statfs("/", &rootpart, sizeof(rootpart), 0)) +#else + if (statfs("/", &rootpart)) +#endif // __sgi || __svr4__ || __SVR4 || M_XENIX + rootfree = 1024; + else + rootfree = (int)((double)rootpart.f_bfree * (double)rootpart.f_bsize / + 1024.0 / 1024.0 + 0.5); + +#if defined(__sgi) || defined(__svr4__) || defined(__SVR4) || defined(M_XENIX) + if (statfs("/usr", &usrpart, sizeof(usrpart), 0)) +#else + if (statfs("/usr", &usrpart)) +#endif // __sgi || __svr4__ || __SVR4 || M_XENIX + usrfree = 1024; + else + usrfree = (int)((double)usrpart.f_bfree * (double)usrpart.f_bsize / + 1024.0 / 1024.0 + 0.5); + + // Display the results to the user... + if (rootfree == usrfree) + { + rootsize += usrsize; + + if (rootsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required, %dm available.", rootsize / 1024.0, + rootfree); + else + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required, %dm available.", rootsize, rootfree); + } + else if (rootsize >= 1024 && usrsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required on /, %dm available,\n" + "%+.1fm required on /usr, %dm available.", + rootsize / 1024.0, rootfree, usrsize / 1024.0, usrfree); + else if (rootsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required on /, %dm available,\n" + "%+dk required on /usr, %dm available.", + rootsize / 1024.0, rootfree, usrsize, usrfree); + else if (usrsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required on /, %dm available,\n" + "%+.1fm required on /usr, %dm available.", + rootsize, rootfree, usrsize / 1024.0, usrfree); + else + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required on /, %dm available,\n" + "%+dk required on /usr, %dm available.", + rootsize, rootfree, usrsize, usrfree); + + SoftwareSize->label(sizelabel); + SoftwareSize->redraw(); +} + + +// +// End of "$Id: setup2.cxx 834 2010-12-30 00:08:36Z mike $". +// diff --git a/slackware.c b/slackware.c new file mode 100644 index 0000000..5e082d2 --- /dev/null +++ b/slackware.c @@ -0,0 +1,334 @@ +/* + * "$Id: slackware.c 833 2010-12-30 00:00:50Z mike $" + * + * Slackware package gateway for the ESP Package Manager (EPM). + * + * Copyright 2003-2010 by Easy Software Products. + * + * Contributed by Alec Thomas <$givenname at korn dot ch> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_slackware() - Make a Slackware software distribution package. + * make_subpackage() - Make a Slackware subpackage. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static int make_subpackage(const char *prodname, const char *directory, + const char *platname, dist_t *dist, + const char *subpackage); + + +/* + * 'make_slackware()' - Make a Slackware software distribution packages. + */ + +int /* O - 0 = success, 1 = fail */ +make_slackware(const char *prodname,/* I - Product short name */ + const char *directory, + /* I - Directory for distribution files */ + const char *platname,/* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform)/* I - Platform information */ +{ + int i; /* Looping var */ + + + REF(platform); + + /* + * Check to see if we are being run as root... + */ + + if (getuid()) + { + fprintf(stderr, "ERROR: Can only make Slackware packages as root\n"); + return (1); + } + + /* + * Create subpackages... + */ + + if (make_subpackage(prodname, directory, platname, dist, NULL)) + return (1); + + for (i = 0; i < dist->num_subpackages; i ++) + if (make_subpackage(prodname, directory, platname, dist, + dist->subpackages[i])) + return (1); + + return (0); +} + + +/* + * 'make_subpackage()' - Make a Slackware subpackage. + */ + +static int /* O - 0 = success, 1 = fail */ +make_subpackage(const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + const char *subpackage) /* I - Subpackage name */ +{ + int i; /* Looping var */ + FILE *fp; /* Spec file */ + char prodfull[1024], /* Full name of product */ + filename[1024], /* Destination filename */ + pkgname[1024]; /* Package filename */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + struct utsname platform; /* Original platform data */ + + + /* + * Figure out the full product name... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + if (Verbosity) + printf("Creating Slackware %s pkg distribution...\n", prodfull); + + /* + * Slackware uses the real machine type in its package names... + */ + + if (uname(&platform)) + { + fprintf(stderr, "ERROR: Can't get platform information - %s\n", + strerror(errno)); + + return (1); + } + + snprintf(pkgname, sizeof(pkgname), "%s-%s-%s-%s.tgz", prodfull, + dist->version, platform.machine, dist->release); + + /* + * Make a copy of the distribution files... + */ + + if (Verbosity) + puts("Copying temporary distribution files..."); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + { + /* + * Check subpackage... + */ + + if (file->subpackage != subpackage) + continue; + + /* + * Find the user and group IDs... + */ + + pwd = getpwnam(file->user); + grp = getgrnam(file->group); + + endpwent(); + endgrent(); + + /* + * Copy the file, make the directory, or make the symlink as needed... + */ + + switch (tolower(file->type)) + { + case 'c' : + case 'f' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodfull, + file->dst); + + if (Verbosity > 1) + printf("F %s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + + case 'i' : + snprintf(filename, sizeof(filename), "%s/%s/etc/rc.d/%s", directory, + prodfull, file->dst); + + if (Verbosity > 1) + printf("I %s -> %s...\n", file->src, filename); + + if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0)) + return (1); + break; + + case 'd' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodfull, + file->dst); + + if (Verbosity > 1) + printf("D %s...\n", filename); + + make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0, + grp ? grp->gr_gid : 0); + break; + + case 'l' : + snprintf(filename, sizeof(filename), "%s/%s%s", directory, prodfull, + file->dst); + + if (Verbosity > 1) + printf("L %s -> %s...\n", file->src, filename); + + make_link(filename, file->src); + break; + } + } + + /* + * Write descriptions and post-install commands as needed... + */ + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + break; + + if (i < dist->num_descriptions) + { + snprintf(filename, sizeof(filename), "%s/%s/install", directory, prodfull); + make_directory(filename, 0755, 0, 0); + + strlcat(filename, "/slack-desc", sizeof(filename)); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "ERROR: Couldn't create Slackware description file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fprintf(fp, "%s: %s\n%s:\n", prodfull, dist->product, prodfull); + + for (; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + fprintf(fp, "%s: %s\n", prodfull, dist->descriptions[i].description); + + fprintf(fp, "%s:\n", prodfull); + fprintf(fp, "%s: (Vendor: %s, Packager: %s)\n", prodfull, dist->vendor, + dist->packager); + fprintf(fp, "%s:\n", prodfull); + + fclose(fp); + } + + for (i = 0, c = dist->commands; i < dist->num_commands; i ++, c ++) + if (c->subpackage == subpackage) + break; + + if (i < dist->num_commands) + { + snprintf(filename, sizeof(filename), "%s/%s/install", directory, prodfull); + make_directory(filename, 0755, 0, 0); + + strlcat(filename, "/doinst.sh", sizeof(filename)); + + if (!(fp = fopen(filename, "w"))) + { + fprintf(stderr, "ERROR: Couldn't create post install script \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + fputs("#!/bin/sh\n", fp); + + for (i = 0, c = dist->commands; i < dist->num_commands; i ++, c ++) + if (c->subpackage == subpackage) + { + switch (c->type) + { + case COMMAND_PRE_INSTALL : + fputs("WARNING: Package contains pre-install commands which are not supported\n" + " by the Slackware packager.\n", stderr); + break; + + case COMMAND_POST_INSTALL : + fprintf(fp, "%s\n", c->command); + break; + + case COMMAND_PRE_REMOVE : + fputs("WARNING: Package contains pre-removal commands which are not supported\n" + " by the Slackware packager.\n", stderr); + break; + + case COMMAND_POST_REMOVE : + fputs("WARNING: Package contains post-removal commands which are not supported\n" + " by the Slackware packager.\n", stderr); + break; + } + } + + fclose(fp); + } + + /* + * Remove any existing package of the same name, then create the + * package... + */ + + snprintf(filename, sizeof(filename), "%s/%s", directory, pkgname); + unlink(filename); + + if (Verbosity) + puts("Building Slackware package..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodfull); + + if (run_command(filename, "makepkg --linkadd y --chown n ../%s", pkgname)) + return (1); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + unlink_directory(filename); + } + + return (0); +} + + +/* + * End of "$Id: slackware.c 833 2010-12-30 00:00:50Z mike $". + */ diff --git a/snprintf.c b/snprintf.c new file mode 100644 index 0000000..a4557a7 --- /dev/null +++ b/snprintf.c @@ -0,0 +1,276 @@ +/* + * "$Id: snprintf.c 611 2005-01-11 21:37:42Z mike $" + * + * snprintf functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2005 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * epm_vsnprintf() - Format a string into a fixed size buffer. + * epm_snprintf() - Format a string into a fixed size buffer. + */ + +/* + * Include necessary headers... + */ + +#include <stdio.h> +#include <ctype.h> +#include "epmstring.h" + + +#ifndef HAVE_VSNPRINTF +/* + * 'vsnprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +epm_vsnprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - printf-style format string */ + va_list ap) /* I - Pointer to additional arguments */ +{ + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + const char *bufformat; /* Start of format */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + + while (*format && bufptr < bufend) + { + if (*format == '%') + { + bufformat = format; + format ++; + + if (*format == '%') + { + *bufptr++ = *format++; + continue; + } + else if (strchr(" -+#\'", *format)) + sign = *format++; + else + sign = 0; + + width = 0; + while (isdigit(*format)) + width = width * 10 + *format++ - '0'; + + if (*format == '.') + { + format ++; + prec = 0; + + while (isdigit(*format)) + prec = prec * 10 + *format++ - '0'; + } + else + prec = -1; + + if (*format == 'l' && format[1] == 'l') + { + size = 'L'; + format += 2; + } + else if (*format == 'h' || *format == 'l' || *format == 'L') + size = *format++; + + if (!*format) + break; + + type = *format++; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strlcpy(tformat, bufformat, format - bufformat + 1); + + sprintf(temp, tformat, va_arg(ap, double)); + + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, bufend - bufptr); + bufptr = bufend; + break; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strlcpy(tformat, bufformat, format - bufformat + 1); + + sprintf(temp, tformat, va_arg(ap, int)); + + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, bufend - bufptr); + bufptr = bufend; + break; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + break; + + case 'p' : /* Pointer value */ + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strlcpy(tformat, bufformat, format - bufformat + 1); + + sprintf(temp, tformat, va_arg(ap, void *)); + + strlcpy(bufptr, temp, bufend - bufptr + 1); + bufptr += strlen(bufptr); + break; + + case 'c' : /* Character or character array */ + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else + { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + memcpy(bufptr, va_arg(ap, char *), width); + bufptr += width; + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + if (slen > width) + slen = width; + + if (sign == '-') + { + strncpy(bufptr, s, slen); + memset(bufptr + slen, ' ', width - slen); + } + else + { + memset(bufptr, ' ', width - slen); + strncpy(bufptr + width - slen, s, slen); + } + + bufptr += width; + break; + + case 'n' : /* Output number of chars so far */ + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strlcpy(tformat, bufformat, format - bufformat + 1); + + sprintf(temp, tformat, va_arg(ap, int)); + + strlcpy(bufptr, temp, bufend - bufptr + 1); + bufptr += strlen(bufptr); + break; + } + } + else + *bufptr++ = *format++; + } + + /* + * Nul-terminate the string and return the number of characters in it. + */ + + *bufptr = '\0'; + return (bufptr - buffer); +} +#endif /* !HAVE_VSNPRINT */ + + +#ifndef HAVE_SNPRINTF +/* + * 'epm_snprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +epm_snprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + int bytes; /* Number of bytes formatted */ + va_list ap; /* Pointer to additional arguments */ + + + va_start(ap, format); + bytes = vsnprintf(buffer, bufsize, format, ap); + va_end(ap); + + return (bytes); +} +#endif /* !HAVE_SNPRINTF */ + + +/* + * End of "$Id: snprintf.c 611 2005-01-11 21:37:42Z mike $". + */ + diff --git a/string.c b/string.c new file mode 100644 index 0000000..a103f1f --- /dev/null +++ b/string.c @@ -0,0 +1,203 @@ +/* + * "$Id: string.c 611 2005-01-11 21:37:42Z mike $" + * + * String functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2005 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * epm_strdup() - Duplicate a string. + * epm_strcasecmp() - Do a case-insensitive comparison. + * epm_strlcat() - Safely concatenate two strings. + * epm_strlcpy() - Safely copy two strings. + * epm_strncasecmp() - Do a case-insensitive comparison on up to N chars. + */ + +/* + * Include necessary headers... + */ + +#include "epmstring.h" + + +/* + * 'epm_strdup()' - Duplicate a string. + */ + +# ifndef HAVE_STRDUP +char * /* O - New string pointer */ +epm_strdup(const char *s) /* I - String to duplicate */ +{ + char *t; /* New string pointer */ + + + if (s == NULL) + return (NULL); + + if ((t = malloc(strlen(s) + 1)) == NULL) + return (NULL); + + return (strcpy(t, s)); +} +# endif /* !HAVE_STRDUP */ + + +/* + * 'epm_strcasecmp()' - Do a case-insensitive comparison. + */ + +# ifndef HAVE_STRCASECMP +int /* O - Result of comparison (-1, 0, or 1) */ +epm_strcasecmp(const char *s, /* I - First string */ + const char *t) /* I - Second string */ +{ + while (*s != '\0' && *t != '\0') + { + if (tolower(*s) < tolower(*t)) + return (-1); + else if (tolower(*s) > tolower(*t)) + return (1); + + s ++; + t ++; + } + + if (*s == '\0' && *t == '\0') + return (0); + else if (*s != '\0') + return (1); + else + return (-1); +} +# endif /* !HAVE_STRCASECMP */ + + +#ifndef HAVE_STRLCAT +/* + * 'epm_strlcat()' - Safely concatenate two strings. + */ + +size_t /* O - Length of string */ +epm_strlcat(char *dst, /* O - Destination string */ + const char *src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ +{ + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ + + + /* + * Figure out how much room is left... + */ + + dstlen = strlen(dst); + size -= dstlen + 1; + + if (!size) + return (dstlen); /* No room, return immediately... */ + + /* + * Figure out how much room is needed... + */ + + srclen = strlen(src); + + /* + * Copy the appropriate amount... + */ + + if (srclen > size) + srclen = size; + + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + + return (dstlen + srclen); +} +#endif /* !HAVE_STRLCAT */ + + +#ifndef HAVE_STRLCPY +/* + * 'epm_strlcpy()' - Safely copy two strings. + */ + +size_t /* O - Length of string */ +epm_strlcpy(char *dst, /* O - Destination string */ + const char *src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ +{ + size_t srclen; /* Length of source string */ + + + /* + * Figure out how much room is needed... + */ + + size --; + + srclen = strlen(src); + + /* + * Copy the appropriate amount... + */ + + if (srclen > size) + srclen = size; + + memcpy(dst, src, srclen); + dst[srclen] = '\0'; + + return (srclen); +} +#endif /* !HAVE_STRLCPY */ + + +/* + * 'epm_strncasecmp()' - Do a case-insensitive comparison on up to N chars. + */ + +# ifndef HAVE_STRNCASECMP +int /* O - Result of comparison (-1, 0, or 1) */ +epm_strncasecmp(const char *s, /* I - First string */ + const char *t, /* I - Second string */ + size_t n) /* I - Maximum number of characters to compare */ +{ + while (*s != '\0' && *t != '\0' && n > 0) + { + if (tolower(*s) < tolower(*t)) + return (-1); + else if (tolower(*s) > tolower(*t)) + return (1); + + s ++; + t ++; + n --; + } + + if (n == 0) + return (0); + else if (*s == '\0' && *t == '\0') + return (0); + else if (*s != '\0') + return (1); + else + return (-1); +} +# endif /* !HAVE_STRNCASECMP */ + + +/* + * End of "$Id: string.c 611 2005-01-11 21:37:42Z mike $". + */ diff --git a/support.c b/support.c new file mode 100644 index 0000000..6a4906e --- /dev/null +++ b/support.c @@ -0,0 +1,110 @@ +/* + * "$Id: support.c 733 2006-11-30 21:59:27Z mike $" + * + * Support functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2006 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * get_vernumber() - Convert a version string to a number... + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * 'get_vernumber()' - Convert a version string to a number... + */ + +int /* O - Version number */ +get_vernumber(const char *version) /* I - Version string */ +{ + int numbers[4], /* Raw version numbers */ + nnumbers, /* Number of numbers in version */ + temp, /* Temporary version number */ + offset; /* Offset for last version number */ + const char *ptr; /* Pointer into string */ + + + /* + * Loop through the version number string and construct a version number. + */ + + memset(numbers, 0, sizeof(numbers)); + + for (ptr = version; *ptr && !isdigit(*ptr & 255); ptr ++); + /* Skip leading letters, periods, etc. */ + + for (offset = 0, temp = 0, nnumbers = 0; *ptr && !isspace(*ptr & 255); ptr ++) + if (isdigit(*ptr & 255)) + temp = temp * 10 + *ptr - '0'; + else + { + /* + * Add each mini version number (m.n.p) and patch/pre stuff... + */ + + if (nnumbers < 4) + { + numbers[nnumbers] = temp; + nnumbers ++; + } + + temp = 0; + + if (*ptr == '.') + offset = 0; + else if (*ptr == 'p' || *ptr == '-') + { + if (strncmp(ptr, "pre", 3) == 0) + { + ptr += 2; + offset = -20; + } + else + offset = 0; + + nnumbers = 3; + } + else if (*ptr == 'b') + { + offset = -50; + nnumbers = 3; + } + else /* if (*ptr == 'a') */ + { + offset = -100; + nnumbers = 3; + } + } + + if (nnumbers < 4) + numbers[nnumbers] = temp; + + /* + * Compute the version number as MMmmPPpp + offset + */ + + return (((numbers[0] * 100 + numbers[1]) * 100 + numbers[2]) * 100 + + numbers[3] + offset); +} + + +/* + * End of "$Id: support.c 733 2006-11-30 21:59:27Z mike $". + */ diff --git a/swinstall.c b/swinstall.c new file mode 100644 index 0000000..52f9949 --- /dev/null +++ b/swinstall.c @@ -0,0 +1,753 @@ +/* + * "$Id: swinstall.c 829 2010-12-29 17:39:59Z mike $" + * + * HP-UX package gateway for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * make_swinstall() - Make an HP-UX software distribution package. + * write_fileset() - Write a fileset specification for a subpackage. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * Local functions... + */ + +static void write_fileset(FILE *fp, dist_t *dist, const char *directory, + const char *prodname, const char *subpackage); + + +/* + * 'make_swinstall()' - Make an HP-UX software distribution package. + */ + +int /* O - 0 = success, 1 = fail */ +make_swinstall(const char *prodname,/* I - Product short name */ + const char *directory, + /* I - Directory for distribution files */ + const char *platname,/* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + struct utsname *platform)/* I - Platform information */ +{ + int i, j; /* Looping vars */ + FILE *fp; /* Spec/script file */ + tarf_t *tarfile; /* .tardist file */ + int linknum; /* Symlink number */ + const char *vendor; /* Pointer into vendor name */ + char vtag[65], /* Vendor tag */ + *vtagptr; /* Pointer into vendor tag */ + char name[1024]; /* Full product name */ + char infoname[1024], /* Info filename */ + preinstall[1024], /* preinstall script */ + postinstall[1024], /* postinstall script */ + preremove[1024], /* preremove script */ + postremove[1024]; /* postremove script */ + char filename[1024]; /* Destination filename */ + file_t *file; /* Current distribution file */ + command_t *c; /* Current command */ + const char *runlevels; /* Run levels */ + + + REF(platform); + + if (Verbosity) + puts("Creating swinstall distribution..."); + + if (dist->release[0]) + { + if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s-%s", prodname, + dist->version, dist->release, platname); + else + snprintf(name, sizeof(name), "%s-%s-%s", prodname, + dist->version, dist->release); + } + else if (platname[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname); + else + snprintf(name, sizeof(name), "%s-%s", prodname, dist->version); + + /* + * Write the preinstall script if needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + break; + + if (i) + { + /* + * Create the preinstall script... + */ + + snprintf(preinstall, sizeof(preinstall), "%s/%s.preinst", directory, + prodname); + + if (Verbosity) + puts("Creating preinstall script..."); + + if ((fp = fopen(preinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_INSTALL) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + preinstall[0] = '\0'; + + /* + * Write the postinstall script if needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + break; + + if (i) + { + /* + * Create the postinstall script... + */ + + snprintf(postinstall, sizeof(postinstall), "%s/%s.postinst", directory, + prodname); + + if (Verbosity) + puts("Creating postinstall script..."); + + if ((fp = fopen(postinstall, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postinstall, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_INSTALL) + fprintf(fp, "%s\n", c->command); + + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "/sbin/init.d/%s start\n", file->dst); + + fclose(fp); + } + else + postinstall[0] = '\0'; + + /* + * Write the preremove script if needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + break; + + if (!i) + for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) + if (tolower(file->type) == 'i') + break; + + if (i) + { + /* + * Then create the remove script... + */ + + if (Verbosity) + puts("Creating preremove script..."); + + snprintf(preremove, sizeof(preremove), "%s/%s.prerm", directory, prodname); + + if ((fp = fopen(preremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", preremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (j = dist->num_files, file = dist->files; j > 0; j --, file ++) + if (tolower(file->type) == 'i') + qprintf(fp, "/sbin/init.d/%s stop\n", file->dst); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_PRE_REMOVE) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + preremove[0] = '\0'; + + /* + * Write the postremove script if needed... + */ + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + break; + + if (i) + { + /* + * Create the postremove script... + */ + + snprintf(postremove, sizeof(postremove), "%s/%s.postrm", directory, + prodname); + + if (Verbosity) + puts("Creating postremove script..."); + + if ((fp = fopen(postremove, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create script file \"%s\" - %s\n", postremove, + strerror(errno)); + return (1); + } + + fchmod(fileno(fp), 0755); + + fputs("#!/bin/sh\n", fp); + fputs("# " EPM_VERSION "\n", fp); + + for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) + if (c->type == COMMAND_POST_REMOVE) + fprintf(fp, "%s\n", c->command); + + fclose(fp); + } + else + postremove[0] = '\0'; + + /* + * Add symlinks for init scripts... + */ + + for (i = 0; i < dist->num_files; i ++) + if (tolower(dist->files[i].type) == 'i') + { + /* + * Make symlinks for all of the selected run levels... + */ + + for (runlevels = get_runlevels(dist->files + i, "02"); + isdigit(*runlevels & 255); + runlevels ++) + { + file = add_file(dist, dist->files[i].subpackage); + file->type = 'l'; + file->mode = 0; + strcpy(file->user, "root"); + strcpy(file->group, "sys"); + snprintf(file->src, sizeof(file->src), "../init.d/%s", + dist->files[i].dst); + + if (*runlevels == '0') + snprintf(file->dst, sizeof(file->dst), "/sbin/rc0.d/K%02d0%s", + get_stop(dist->files + i, 0), dist->files[i].dst); + else + snprintf(file->dst, sizeof(file->dst), "/sbin/rc%c.d/S%02d0%s", + *runlevels, get_start(dist->files + i, 99), + dist->files[i].dst); + } + + /* + * Then send the original file to /sbin/init.d... + */ + + file = dist->files + i; + + snprintf(filename, sizeof(filename), "/sbin/init.d/%s", file->dst); + strcpy(file->dst, filename); + } + + /* + * Create all symlinks... + */ + + if (Verbosity) + puts("Creating symlinks..."); + + for (i = dist->num_files, file = dist->files, linknum = 0; + i > 0; + i --, file ++) + if (tolower(file->type) == 'l') + { + snprintf(filename, sizeof(filename), "%s/%s.link%04d", directory, + prodname, linknum); + symlink(file->src, filename); + linknum ++; + } + + /* + * Write the description file(s) for swpackage... + */ + + if (dist->num_descriptions > 0) + { + if (Verbosity) + puts("Creating description file(s)..."); + + for (i = 0; i < dist->num_descriptions; i ++) + if (!dist->descriptions[i].subpackage) + break; + + if (i < dist->num_descriptions) + { + snprintf(filename, sizeof(filename), "%s/%s.desc", directory, prodname); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create description file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + for (; i < dist->num_descriptions; i ++) + if (!dist->descriptions[i].subpackage) + fprintf(fp, "%s\n", dist->descriptions[i].description); + + fclose(fp); + } + + for (i = 0; i < dist->num_subpackages; i ++) + { + for (j = 0; j < dist->num_descriptions; j ++) + if (dist->descriptions[j].subpackage == dist->subpackages[i]) + break; + + if (j < dist->num_descriptions) + { + snprintf(filename, sizeof(filename), "%s/%s-%s.desc", directory, + prodname, dist->subpackages[i]); + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create description file \"%s\" - %s\n", + filename, strerror(errno)); + return (1); + } + + for (; j < dist->num_descriptions; j ++) + if (dist->descriptions[j].subpackage == dist->subpackages[i]) + fprintf(fp, "%s\n", dist->descriptions[j].description); + + fclose(fp); + } + } + } + + /* + * Write the info file for swpackage... + */ + + if (Verbosity) + puts("Creating info file..."); + + snprintf(infoname, sizeof(infoname), "%s/%s.info", directory, prodname); + + if ((fp = fopen(infoname, "w")) == NULL) + { + fprintf(stderr, "epm: Unable to create info file \"%s\" - %s\n", infoname, + strerror(errno)); + return (1); + } + + /* + * Figure out the vendor tag and write a vendor class... + */ + + for (vendor = dist->vendor, vtagptr = vtag; *vendor; vendor ++) + if (isalnum(*vendor) && vtagptr < (vtag + sizeof(vtag) - 1)) + *vtagptr++ = *vendor; + + *vtagptr = '\0'; + + fputs("vendor\n", fp); + fprintf(fp, " tag %s\n", vtag); + fprintf(fp, " description %s\n", dist->vendor); + fprintf(fp, " title %s\n", dist->vendor); + fputs("end\n", fp); + + /* + * Then the product class... + */ + + fputs("product\n", fp); + fprintf(fp, " tag %s\n", prodname); + fprintf(fp, " revision %s\n", dist->version); + fprintf(fp, " title %s, %s\n", dist->product, dist->version); + + snprintf(filename, sizeof(filename), "%s/%s.desc", directory, prodname); + if (!access(filename, 0)) + fprintf(fp, " description < %s\n", filename); + if (dist->license[0]) + { + if (strncmp(dist->license, "./", 2)) + fprintf(fp, " copyright < %s\n", dist->license); + else + fprintf(fp, " copyright < %s\n", dist->license + 2); + } + if (dist->readme[0]) + { + if (strncmp(dist->readme, "./", 2)) + fprintf(fp, " readme < %s\n", dist->readme); + else + fprintf(fp, " readme < %s\n", dist->readme + 2); + } + fprintf(fp, " vendor_tag %s\n", vtag); + fputs(" is_locatable false\n", fp); + + if (dist->num_subpackages > 0) + { + /* + * Write subproduct specifications... + */ + + fputs(" subproduct\n", fp); + fputs(" tag base\n", fp); + fputs(" contents fs_base\n", fp); + fprintf(fp, " revision %s\n", dist->version); + + for (i = 0; i < dist->num_descriptions; i ++) + if (!dist->descriptions[i].subpackage) + { + fprintf(fp, " title %s, %s\n", dist->descriptions[i].description, + dist->version); + break; + } + + if (!access(filename, 0)) + fprintf(fp, " description < %s\n", filename); + fputs(" end\n", fp); + + for (i = 0; i < dist->num_subpackages; i ++) + { + fputs(" subproduct\n", fp); + fprintf(fp, " tag %s\n", dist->subpackages[i]); + fprintf(fp, " contents fs_%s\n", dist->subpackages[i]); + fprintf(fp, " revision %s\n", dist->version); + + for (j = 0; j < dist->num_descriptions; j ++) + if (dist->descriptions[j].subpackage == dist->subpackages[i]) + { + fprintf(fp, " title %s, %s\n", dist->descriptions[j].description, + dist->version); + break; + } + + snprintf(filename, sizeof(filename), "%s/%s-%s.desc", directory, + prodname, dist->subpackages[i]); + if (!access(filename, 0)) + fprintf(fp, " description < %s\n", filename); + fputs(" end\n", fp); + } + } + + /* + * Write filesets... + */ + + write_fileset(fp, dist, directory, prodname, NULL); + for (i = 0; i < dist->num_subpackages; i ++) + write_fileset(fp, dist, directory, prodname, dist->subpackages[i]); + + fputs("end\n", fp); + + fclose(fp); + + /* + * Build the distributions from the spec file... + */ + + if (Verbosity) + puts("Building swinstall depot.gz distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + mkdir(filename, 0777); + + if (run_command(NULL, "/usr/sbin/swpackage %s-s %s " + "-x target_type=tape " + "-d '|" EPM_GZIP " -9 >%s/%s.depot.gz' %s", + Verbosity == 0 ? "" : "-v ", infoname, directory, + name, prodname)) + return (1); + + if (Verbosity) + puts("Building swinstall binary distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + mkdir(filename, 0777); + + if (run_command(NULL, "/usr/sbin/swpackage %s-s %s -d %s/%s " + "-x write_remote_files=true %s", + Verbosity == 0 ? "" : "-v ", infoname, directory, + prodname, prodname)) + return (1); + + /* + * Tar and compress the distribution... + */ + + if (Verbosity) + puts("Creating depot.tgz file for distribution..."); + + snprintf(filename, sizeof(filename), "%s/%s.depot.tgz", directory, name); + + if ((tarfile = tar_open(filename, 1)) == NULL) + return (1); + + snprintf(filename, sizeof(filename), "%s/%s", directory, prodname); + + if (tar_directory(tarfile, filename, prodname)) + { + tar_close(tarfile); + return (1); + } + + tar_close(tarfile); + + /* + * Remove temporary files... + */ + + if (!KeepFiles) + { + if (Verbosity) + puts("Removing temporary distribution files..."); + + unlink(infoname); + + if (preinstall[0]) + unlink(preinstall); + if (postinstall[0]) + unlink(postinstall); + if (preremove[0]) + unlink(preremove); + if (postremove[0]) + unlink(postremove); + + while (linknum > 0) + { + linknum --; + snprintf(filename, sizeof(filename), "%s/%s.link%04d", directory, + prodname, linknum); + unlink(filename); + } + + snprintf(filename, sizeof(filename), "%s/%s.desc", directory, prodname); + unlink(filename); + + for (i = 0; i < dist->num_subpackages; i ++) + { + snprintf(filename, sizeof(filename), "%s/%s-%s.desc", directory, + prodname, dist->subpackages[i]); + unlink(filename); + } + } + + return (0); +} + + +/* + * 'write_fileset()' - Write a fileset specification for a subpackage. + */ + +static void +write_fileset(FILE *fp, /* I - File to write to */ + dist_t *dist, /* I - Distribution */ + const char *directory, /* I - Output directory */ + const char *prodname, /* I - Product name */ + const char *subpackage) /* I - Subpackage to write */ +{ + int i; /* Looping var */ + char filename[1024]; /* Temporary filename */ + depend_t *d; /* Current dependency */ + file_t *file; /* Current distribution file */ + int linknum; /* Symlink number */ + + + fputs(" fileset\n", fp); + fprintf(fp, " tag fs_%s\n", subpackage ? subpackage : "base"); + fprintf(fp, " revision %s\n", dist->version); + + for (i = 0; i < dist->num_descriptions; i ++) + if (dist->descriptions[i].subpackage == subpackage) + { + fprintf(fp, " title %s, %s\n", dist->descriptions[i].description, + dist->version); + break; + } + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REQUIRES && d->product[0] != '/' && + d->subpackage == subpackage) + break; + + if (i) + { + for (; i > 0; i --, d ++) + { + if (d->type == DEPEND_REQUIRES && d->product[0] != '/' && + d->subpackage == subpackage) + { + if (!strcmp(d->product, "_self")) + fprintf(fp, " prerequisites %s", prodname); + else + fprintf(fp, " prerequisites %s", d->product); + + if (d->vernumber[0] == 0) + { + if (d->vernumber[1] < INT_MAX) + fprintf(fp, ",r<=%s\n", d->version[1]); + else + putc('\n', fp); + } + else + fprintf(fp, ",r>=%s,r<=%s\n", d->version[0], d->version[1]); + } + } + } + + for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++) + if (d->type == DEPEND_REPLACES && d->product[0] != '/' && + d->subpackage == subpackage) + break; + + if (i) + { + for (; i > 0; i --, d ++) + { + if (d->type == DEPEND_REPLACES && d->product[0] != '/' && + d->subpackage == subpackage) + { + fprintf(fp, " ancestor %s", d->product); + if (d->vernumber[0] == 0) + { + if (d->vernumber[1] < INT_MAX) + fprintf(fp, ",r<=%s\n", d->version[1]); + else + putc('\n', fp); + } + else + fprintf(fp, ",r>=%s,r<=%s\n", d->version[0], d->version[1]); + } + } + } + + if (!subpackage) + { + /* + * Write scripts... + */ + + snprintf(filename, sizeof(filename), "%s/%s.preinst", directory, prodname); + if (!access(filename, 0)) + fprintf(fp, " preinstall %s\n", filename); + + snprintf(filename, sizeof(filename), "%s/%s.postinst", directory, prodname); + if (!access(filename, 0)) + fprintf(fp, " postinstall %s\n", filename); + + snprintf(filename, sizeof(filename), "%s/%s.prerm", directory, prodname); + if (!access(filename, 0)) + fprintf(fp, " preremove %s\n", filename); + + snprintf(filename, sizeof(filename), "%s/%s.postrm", directory, prodname); + if (!access(filename, 0)) + fprintf(fp, " postremove %s\n", filename); + } + + for (i = dist->num_files, file = dist->files, linknum = 0; + i > 0; + i --, file ++) + { + if (file->subpackage != subpackage) + { + if (tolower(file->type) == 'l') + linknum ++; + + continue; + } + + switch (tolower(file->type)) + { + case 'd' : + qprintf(fp, " file -m %04o -o %s -g %s . %s\n", file->mode, + file->user, file->group, file->dst); + break; + case 'c' : + qprintf(fp, " file -m %04o -o %s -g %s -v %s %s\n", file->mode, + file->user, file->group, file->src, file->dst); + break; + case 'f' : + case 'i' : + qprintf(fp, " file -m %04o -o %s -g %s %s %s\n", file->mode, + file->user, file->group, file->src, file->dst); + break; + case 'l' : + snprintf(filename, sizeof(filename), "%s/%s.link%04d", directory, + prodname, linknum); + linknum ++; + qprintf(fp, " file -o %s -g %s %s %s\n", file->user, file->group, + filename, file->dst); + break; + } + } + + fputs(" end\n", fp); +} + + +/* + * End of "$Id: swinstall.c 829 2010-12-29 17:39:59Z mike $". + */ @@ -0,0 +1,562 @@ +/* + * "$Id: tar.c 837 2010-12-30 00:25:29Z mike $" + * + * TAR file functions for the ESP Package Manager (EPM). + * + * Copyright 1999-2010 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Contents: + * + * tar_close() - Close a tar file, padding as needed. + * tar_directory() - Archive a directory. + * tar_file() - Write the contents of a file... + * tar_header() - Write a TAR header for the specified file... + * tar_open() - Open a TAR file for writing. + * tar_package() - Archive a package file. + */ + +/* + * Include necessary headers... + */ + +#include "epm.h" + + +/* + * 'tar_close()' - Close a tar file, padding as needed. + */ + +int /* O - -1 on error, 0 on success */ +tar_close(tarf_t *fp) /* I - File to write to */ +{ + size_t blocks; /* Number of blocks to write */ + int status; /* Return status */ + char padding[TAR_BLOCKS * TAR_BLOCK]; + /* Padding for tar blocks */ + + + if (fp->blocks > 0) + { + /* + * Zero the padding record... + */ + + memset(padding, 0, sizeof(padding)); + + /* + * Write a single 0 block to signal the end of the archive... + */ + + if (fwrite(padding, TAR_BLOCK, 1, fp->file) < 1) + return (-1); + + fp->blocks ++; + + /* + * Pad the tar files to TAR_BLOCKS blocks... This is bullshit of course, + * but old versions of tar need it... + */ + + status = 0; + + if ((blocks = fp->blocks % TAR_BLOCKS) > 0) + { + blocks = TAR_BLOCKS - blocks; + + if (fwrite(padding, TAR_BLOCK, blocks, fp->file) < blocks) + status = -1; + } + else + { + /* + * Sun tar needs at least 2 0 blocks... + */ + + if (fwrite(padding, TAR_BLOCK, blocks, fp->file) < blocks) + status = -1; + } + } + else + status = 0; + + /* + * Close the file and free memory... + */ + + if (fp->compressed) + { + if (pclose(fp->file)) + status = -1; + } + else if (fclose(fp->file)) + status = -1; + + free(fp); + + return (status); +} + + +/* + * 'tar_directory()' - Archive a directory. + */ + +int /* O - 0 on success, -1 on error */ +tar_directory(tarf_t *tar, /* I - Tar file to write to */ + const char *srcpath, /* I - Source directory */ + const char *dstpath) /* I - Destination directory */ +{ + DIR *dir; /* Directory */ + DIRENT *dent; /* Directory entry */ + char src[1024], /* Source file */ + dst[1024], /* Destination file */ + srclink[1024]; /* Symlink value */ + struct stat srcinfo; /* Information on the source file */ + + + /* + * Range check input... + */ + + if (tar == NULL || srcpath == NULL || dstpath == NULL) + return (-1); + + /* + * Try opening the source directory... + */ + + if ((dir = opendir(srcpath)) == NULL) + { + fprintf(stderr, "epm: Unable to open directory \"%s\": %s\n", srcpath, + strerror(errno)); + + return (-1); + } + + /* + * Read from the directory... + */ + + while ((dent = readdir(dir)) != NULL) + { + /* + * Skip "." and ".."... + */ + + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) + continue; + + /* + * Get source file info... + */ + + snprintf(src, sizeof(src), "%s/%s", srcpath, dent->d_name); + if (dstpath[0]) + snprintf(dst, sizeof(dst), "%s/%s", dstpath, dent->d_name); + else + strlcpy(dst, dent->d_name, sizeof(dst)); + + if (stat(src, &srcinfo)) + { + fprintf(stderr, "epm: Unable to stat \"%s\": %s\n", src, + strerror(errno)); + continue; + } + + /* + * Process accordingly... + */ + + if (Verbosity) + puts(dst); + + if (S_ISDIR(srcinfo.st_mode)) + { + /* + * Directory... + */ + + if (tar_header(tar, TAR_DIR, srcinfo.st_mode, 0, + srcinfo.st_mtime, "root", "sys", dst, NULL)) + goto fail; + + if (tar_directory(tar, src, dst)) + goto fail; + } + else if (S_ISLNK(srcinfo.st_mode)) + { + /* + * Symlink... + */ + + if (readlink(src, srclink, sizeof(srclink)) < 0) + goto fail; + + if (tar_header(tar, TAR_SYMLINK, srcinfo.st_mode, 0, + srcinfo.st_mtime, "root", "sys", dst, srclink)) + goto fail; + } + else + { + /* + * Regular file... + */ + + if (tar_header(tar, TAR_NORMAL, srcinfo.st_mode, srcinfo.st_size, + srcinfo.st_mtime, "root", "sys", dst, NULL)) + goto fail; + + if (tar_file(tar, src)) + goto fail; + } + } + + closedir(dir); + return (0); + + fail: + + closedir(dir); + return (-1); +} + + +/* + * 'tar_file()' - Write the contents of a file... + */ + +int /* O - 0 on success, -1 on error */ +tar_file(tarf_t *fp, /* I - Tar file to write to */ + const char *filename) /* I - File to write */ +{ + FILE *file; /* File to write */ + size_t nbytes, /* Number of bytes read */ + tbytes, /* Total bytes read/written */ + fill; /* Number of fill bytes needed */ + char buffer[8192]; /* Copy buffer */ + + + /* + * Try opening the file... + */ + + if ((file = fopen(filename, "rb")) == NULL) + return (-1); + + /* + * Copy the file to the tar file... + */ + + tbytes = 0; + + while ((nbytes = fread(buffer, 1, sizeof(buffer), file)) > 0) + { + /* + * Zero fill the file to a 512 byte record as needed. + */ + + if (nbytes < sizeof(buffer)) + { + fill = TAR_BLOCK - (nbytes & (TAR_BLOCK - 1)); + + if (fill < TAR_BLOCK) + { + memset(buffer + nbytes, 0, fill); + nbytes += fill; + } + } + + /* + * Write the buffer to the file... + */ + + if (fwrite(buffer, 1, nbytes, fp->file) < nbytes) + { + fclose(file); + return (-1); + } + + tbytes += nbytes; + fp->blocks += nbytes / TAR_BLOCK; + } + + /* + * Close the file and return... + */ + + fclose(file); + return (0); +} + + +/* + * 'tar_header()' - Write a TAR header for the specified file... + */ + +int /* O - 0 on success, -1 on error */ +tar_header(tarf_t *fp, /* I - Tar file to write to */ + int type, /* I - File type */ + mode_t mode, /* I - File permissions */ + off_t size, /* I - File size */ + time_t mtime, /* I - File modification time */ + const char *user, /* I - File owner */ + const char *group, /* I - File group */ + const char *pathname, /* I - File name */ + const char *linkname) /* I - File link name (for links only) */ +{ + tar_t record; /* TAR header record */ + int pathlen; /* Length of pathname */ + const char *pathsep; /* Path separator */ + int i, /* Looping var... */ + sum; /* Checksum */ + unsigned char *sumptr; /* Pointer into header record */ + struct passwd *pwd; /* Pointer to user record */ + struct group *grp; /* Pointer to group record */ + + + /* + * Find the username and groupname IDs... + */ + + pwd = getpwnam(user); + grp = getgrnam(group); + + endpwent(); + endgrent(); + + /* + * Format the header... + */ + + memset(&record, 0, sizeof(record)); + + pathlen = strlen(pathname); + + if ((pathlen < (sizeof(record.header.pathname) - 1) && type != TAR_DIR) || + (pathlen < (sizeof(record.header.pathname) - 2) && type == TAR_DIR)) + { + /* + * Pathname is short enough to fit in the initial pathname field... + */ + + strcpy(record.header.pathname, pathname); + if (type == TAR_DIR && pathname[pathlen - 1] != '/') + record.header.pathname[pathlen] = '/'; + } + else + { + /* + * Copy directory information to prefix buffer and filename information + * to pathname buffer. + */ + + if ((pathsep = strrchr(pathname, '/')) == NULL) + { + /* + * No directory info... + */ + + fprintf(stderr, "epm: Pathname \"%s\" is too long for a tar file!\n", + pathname); + return (-1); + } + + if ((pathsep - pathname) > (sizeof(record.header.prefix) - 1)) + { + /* + * Directory name too long... + */ + + fprintf(stderr, "epm: Pathname \"%s\" is too long for a tar file!\n", + pathname); + return (-1); + } + + if ((pathlen - (pathsep - pathname)) > (sizeof(record.header.pathname) - 1)) + { + /* + * Filename too long... + */ + + fprintf(stderr, "epm: Pathname \"%s\" is too long for a tar file!\n", + pathname); + return (-1); + } + + strcpy(record.header.pathname, pathsep + 1); + if (type == TAR_DIR && pathname[pathlen - 1] != '/') + record.header.pathname[pathlen - (pathsep - pathname + 1)] = '/'; + + strlcpy(record.header.prefix, pathname, (size_t)(pathsep - pathname + 1)); + } + + sprintf(record.header.mode, "%-6o ", (unsigned)mode); + sprintf(record.header.uid, "%o ", pwd == NULL ? 0 : (unsigned)pwd->pw_uid); + sprintf(record.header.gid, "%o ", grp == NULL ? 0 : (unsigned)grp->gr_gid); + sprintf(record.header.size, "%011o", (unsigned)size); + sprintf(record.header.mtime, "%011o", (unsigned)mtime); + memset(&(record.header.chksum), ' ', sizeof(record.header.chksum)); + record.header.linkflag = type; + if (type == TAR_SYMLINK) + strlcpy(record.header.linkname, linkname, sizeof(record.header.linkname)); + strcpy(record.header.magic, TAR_MAGIC); + memcpy(record.header.version, TAR_VERSION, 2); + strlcpy(record.header.uname, user, sizeof(record.header.uname)); + strlcpy(record.header.gname, group, sizeof(record.header.uname)); + + /* + * Compute the checksum of the header... + */ + + for (i = sizeof(record), sumptr = record.all, sum = 0; i > 0; i --) + sum += *sumptr++; + + /* + * Put the correct checksum in place and write the header... + */ + + sprintf(record.header.chksum, "%6o", sum); + + if (fwrite(&record, 1, sizeof(record), fp->file) < sizeof(record)) + return (-1); + + fp->blocks ++; + return (0); +} + + +/* + * 'tar_open()' - Open a TAR file for writing. + */ + +tarf_t * /* O - New tar file */ +tar_open(const char *filename, /* I - File to create */ + int compress) /* I - Compress with gzip? */ +{ + tarf_t *fp; /* New tar file */ + char command[1024]; /* Compression command */ + + + /* + * Allocate memory for the tar file state... + */ + + if ((fp = calloc(sizeof(tarf_t), 1)) == NULL) + return (NULL); + + /* + * Open the output file or pipe into gzip for compressed output... + */ + + if (compress) + { + snprintf(command, sizeof(command), EPM_GZIP " > %s", filename); + fp->file = popen(command, "w"); + } + else + fp->file = fopen(filename, "wb"); + + /* + * If we couldn't open the output file, abort... + */ + + if (fp->file == NULL) + { + free(fp); + return (NULL); + } + + /* + * Save the compression state and return... + */ + + fp->compressed = compress; + + return (fp); +} + + +/* + * 'tar_package()' - Archive a package file. + */ + +int /* O - 0 on success, -1 on failure */ +tar_package(tarf_t *tar, /* I - Tar file */ + const char *ext, /* I - Package filename extension */ + const char *prodname, /* I - Product short name */ + const char *directory, /* I - Directory for distribution files */ + const char *platname, /* I - Platform name */ + dist_t *dist, /* I - Distribution information */ + const char *subpackage) /* I - Subpackage */ +{ + char prodfull[255], /* Full name of product */ + name[1024], /* Full product name */ + filename[1024]; /* File to archive */ + struct stat filestat; /* File information */ + + + /* + * Figure out the full name of the distribution... + */ + + if (subpackage) + snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); + else + strlcpy(prodfull, prodname, sizeof(prodfull)); + + /* + * Then the subdirectory name... + */ + + if (dist->release[0]) + snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version, + dist->release); + else + snprintf(name, sizeof(name), "%s-%s", prodfull, dist->version); + + if (platname[0]) + { + strlcat(name, "-", sizeof(name)); + strlcat(name, platname, sizeof(name)); + } + + strlcat(name, ".", sizeof(name)); + strlcat(name, ext, sizeof(name)); + + /* + * Find out more about the package file... + */ + + snprintf(filename, sizeof(filename), "%s/%s", directory, name); + if (stat(filename, &filestat)) + { + fprintf(stderr, "epm: Error reading package file \"%s\": %s\n", + filename, strerror(errno)); + return (-1); + } + + /* + * Write the header and the file... + */ + + if (tar_header(tar, TAR_NORMAL, (mode_t)0644, filestat.st_size, + filestat.st_mtime, "root", "root", name, NULL)) + return (-1); + + return (tar_file(tar, filename)); +} + + +/* + * End of "$Id: tar.c 837 2010-12-30 00:25:29Z mike $". + */ diff --git a/uninst.cxx b/uninst.cxx new file mode 100644 index 0000000..29fc271 --- /dev/null +++ b/uninst.cxx @@ -0,0 +1,444 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#include "uninst.h" + +Fl_Double_Window *UninstallWindow=(Fl_Double_Window *)0; + +static void cb_UninstallWindow(Fl_Double_Window*, void*) { + if (CancelButton->active()) + exit(0); +} + +Fl_Box *Title[4]={(Fl_Box *)0}; + +Fl_Wizard *Wizard=(Fl_Wizard *)0; + +Fl_Help_View *ReadmeFile=(Fl_Help_View *)0; + +Fl_Check_Browser *SoftwareList=(Fl_Check_Browser *)0; + +Fl_Box *SoftwareSize=(Fl_Box *)0; + +Fl_Button *RemoveAllButton=(Fl_Button *)0; + +static void cb_RemoveAllButton(Fl_Button*, void*) { + SoftwareList->check_all(); +list_cb(0,0); +} + +Fl_Button *RemoveNoneButton=(Fl_Button *)0; + +static void cb_RemoveNoneButton(Fl_Button*, void*) { + SoftwareList->check_none(); +list_cb(0,0); +} + +Fl_Browser *ConfirmList=(Fl_Browser *)0; + +Fl_Group *Pane[4]={(Fl_Group *)0}; + +Fl_Progress *RemovePercent=(Fl_Progress *)0; + +Fl_Browser *RemoveLog=(Fl_Browser *)0; + +Fl_Box *WelcomeImage=(Fl_Box *)0; + +#include <FL/Fl_Pixmap.H> +static const char *idata_default[] = { +"96 96 64 1", +" \tc None", +".\tc #000100", +"+\tc #0C0E0A", +"@\tc #1C1C19", +"#\tc #231C0C", +"$\tc #312714", +"%\tc #2C2B27", +"&\tc #3B2D0F", +"*\tc #403728", +"=\tc #393A38", +"-\tc #534117", +";\tc #504430", +">\tc #474946", +",\tc #5B482B", +"\'\tc #634D1C", +")\tc #704B0B", +"!\tc #5F523D", +"~\tc #555754", +"{\tc #7B562C", +"]\tc #6F5F40", +"^\tc #815E18", +"/\tc #616260", +"(\tc #7B6421", +"_\tc #816435", +":\tc #8A6620", +"<\tc #8E6A1C", +"[\tc #8A6B23", +"}\tc #856E4F", +"|\tc #727371", +"1\tc #946F2F", +"2\tc #9C7B29", +"3\tc #7F817E", +"4\tc #9C824C", +"5\tc #A18240", +"6\tc #98835F", +"7\tc #A9862F", +"8\tc #AA8B3C", +"9\tc #8E908D", +"0\tc #B09241", +"a\tc #B29451", +"b\tc #B6994D", +"c\tc #BB9D52", +"d\tc #9FA09D", +"e\tc #B8A173", +"f\tc #C0A35E", +"g\tc #BFA56D", +"h\tc #ABADAA", +"i\tc #CEB069", +"j\tc #B8B29F", +"k\tc #C3B28A", +"l\tc #B2B4B1", +"m\tc #CFB681", +"n\tc #BCBEBB", +"o\tc #DCBC7C", +"p\tc #CCBFA3", +"q\tc #C8CAC6", +"r\tc #ECCE8C", +"s\tc #CFD2CE", +"t\tc #D7D9D6", +"u\tc #FDDE9B", +"v\tc #DFE1DE", +"w\tc #E9EBE7", +"x\tc #F1F3F0", +"y\tc #FDFFFC", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" q9~==n \ + ", +" q9~@.....% \ + ", +" q9~@....*}eu#.q \ + ", +" q9~@....*}eurroi].3 t>+/ \ + ", +" q9~@...+;}euuoofffffa.% t%...~ \ + ", +" q9~@...+;6murroffffffffff#.q t%.!m+.~ \ + ", +" q9~@...+;6muromfffffffgfgffff].3 t%.!uum+.~ \ + ", +" q9~@...@;6muroiffff]@#;}afffffgffa.% t%.!uuuum..~ \ + ", +" 9~@...@!6muroifgfffffa......#;_gfffff#.q t%.!uuuuuum+.~ \ + ", +" 3..@!6rurrofffffffgfff}./vd/@+...#;_gf].| t%.!uuuuuuuum..~ \ + ", +" =.euroffffff4;$#$$$%$$#.dyyyyvd/@....#$.@ t%.!uuuuuuuuuum+.~ \ + ", +" |.}offffffff+...........vyyyyyyyyvd/@....%@.!uuuuuuuuuuuum..~\ + ", +" h.;rffffffff..hhhhhhhd.@yyyyyyyyyyyyyvd/@....%}6upuuuuuuuum+.\ +~ ", +" +.uigfgffgf..wxvxvxvd./yyyyyyyyyyyyyyyyyvd/@....*!epuuuuuum.\ +.~ ", +" >.eofffffff..vvxvxvx/.dyyyyyyyyyyyyyyyyyyyyyvd/%....%}kuuuum\ ++.~ ", +" 3.]rfffffff..xvxvxvx%.vyyyyyyyyyyyyyyyyyyyyyyyyyvd|%...uuuuu\ +m..~ ", +" q.%rfgfffff..vxvxxxv.@yyxqswyyyyyyyyyyyyyyyyyyyyyyyyx%.euuuu\ +um+.~ ", +" @.riffffff..xxqnnn9./yyxllhlntwyyyyyyyyyyyyyyyyyyyyy+.uuuuu\ +uum..~ ", +" ~.eogfgfff..vxllhl>.dyyyvtnlllhlnswyyyyyyyyyyyyyyyys.=uuuuu\ +uuum+.~ ", +" d.!rffffff..xvvvvv%.vyyyyyyyvtnlllhlntwyyyyyyyyyyyy9.}uuuuu\ +uuuum..~ ", +" t.@uffgfff..xxtssq.@yyxqqtwyyyyyxtnlllhlnswyyyyyyyy~.kuuuuu\ +uuuuum+.~ ", +" %.mifffff..xxhll|./yyxhllllqtwyyyyyvtnlllhlntwyyyy+.uupuuu\ +uuuuuum..9 ", +" thhhhhhhhh~.6offfb0..xxvts/.dyyyxvsnllllhqtwyyyyyxtnlllhnyys.*uuupuu\ +uuuuuuum+.9 ", +" %...........!r88287..xxtss%.tyyyyyyyxvsnlllllqtwyyyyyvtqsyy9.}uuuuuu\ +upuuuuuum..n ", +" h.#,---------{4877<:..xxlld.@yxwlnsvxyyyyxvsnllllhqtwyyyyyyy>.kuuuuuu\ +uuuuuuuuu;.h ", +" q..go077778882{{^)))..xxtt9.~xxxllllllqtxyyyyxvsnlllllqtxyyy+.uuuuuuu\ +uuuuuuuu!..t ", +" 9.+mr788877788_{)))..xxxv/.9xxxxvtqllllllqtxyyyyxvsnlllnyys.*uuuuuuu\ +uupuuuu!.+n ", +" 9.+mr777777782_{\')..xxll%.qvxvxxxxxxtqnlllllqtxyyyyxvqvyy9.}uuuuuu\ +uuuuuuu~..n ", +" 9.+mr728872782{{)..xxsl.@vxthhnqtxxxxxxtqllllllqtxyyyyyy~.epuuuxuu\ +uuuuu!..n ", +" 9.+er778787882_{..xxxd.~vvvnlllhhlqtvxxxxxtqnlllllqvyyy+.fouuuuuu\ +uuuu/..q ", +" 9..6r778787778{,.xyl>.9ttvvttqnlllllnqtxxxxxxtqllllyyq.#afguuuuu\ +uuu!.+n ", +" 9..6r777788787{{xxq%.nttttttvvvtqnllllhlqtxxxxxxttxx9.&)afguuuu\ +xu!..n ", +" 9+.6r828777788{}xv.@stshllnqtvvtvvtqnllhhhlqtxxxxxx>.-^)afeuuu\ +u!..n ", +" 9..6r778277888{63.>sstnllllhlnqsttvvvtqnlllhhlsxxx+.)))^afguu\ +!.........+/ ", +" 9.+6r877887778{,.3qqqqssnnllllllnqtvvvvvtqnllhxvn.#)))))afo!\ +............n ", +" 9..6r077778788{{dqqnnqsqssqqnlllhllnqttvvvvttvv3.&))))^5fff\ +ffffioru4;@.h ", +" 9..ir772878778{}nnllllnnqqqqssnnllllllnqtvtvvv>.-^1affffff\ +foour6!@...= ", +" =.)ir877778888{}nnlllllllnnqqssqqqnllllllnvvt$,affffffgou\ +ue}%...+>9q ", +" =.^)fu087877778{}lnnnnlllllllnnqqqqsqqnlllpkgfffffioourg;\ +....=|n ", +" =.:^)fu077778788{}llnnnnnnlllllllnnqqqpmgffffffoorumf11{.\ +@/dt ", +" =.<:))fu028778787{}lllnnlnnnnnlllljegfgffffioruoga^1^:^\'\ +.| ", +" =.8<1^)fu072777788{}lllnlnnlnnjkgfffffffoouuoa1:::::_::\'\ +.| ", +" =.782:^)au087878778{}dlhlhjpefffffffioruog1^^1:1^1:::11^.\ +| ", +" =.088<1^)ai878788788{}npmofooooiooouroa1:1:1_^::1_:2278(.\ +| ", +" =.70802<^)^)))))))))){aooooooomooog1{1:::::[:1[[2772787(.\ +| ", +" =.008082<<<<<<<<1<<1i1<1^^^^1^11^11::::1_[1[25787888782(.\ +| ", +" =.800008222222222222r1:7211::::::::11[[[222877772777777(.\ +| ", +" =.8080b0022222222280r1:8821:1_1:1[[[1182887878777778788(.\ +| ", +" =.08b08b888227277b0cr1<77772[:[[1[587777772787888827877(.\ +| ", +" =.b8b08cb0882728bba0r1<788878[5777787887787777777787728(.\ +| ", +" =.800808b8c888bc8c0cr1<87778777887778772878727777877877(.\ +| ", +" =.5c8cc8c00008bbacaco1<77777877728777787772888287727872(.\ +| ", +" /.#8a08c8bcbcc8c000cr1<82878727877872877877777777887778(.\ +| ", +" ~.#500c8c8abaccccccr1<77827787877877787887778787787878^.\ +| ", +" ~.#5c8cac0c08ca8car1<28777877287787872778287277772787(.\ +| ", +" ~.#5c00cacccccc0ar1<77787787782782777777778788778728(.\ +| ", +" /.#5ccc00aaacaccr1[78872877777777788878787277887877(.\ +| ", +" ~.#5ccc0ccc0ccar1[77777788788778772778727777277878(.\ +| ", +" ~.#5acc0ccfaccr[[77887272872887777287778887777727(.\ +| ", +" ~.#accca0cccar1<27788787787728870728777787827787(.\ +| ", +" ~.#5cccacaccr1[77277777777787787787877728778827(.\ +| ", +" ~.#5ccccffar1[87778788287777728777828778877788^.\ +| ", +" /.#accfcccr[[77887727878728787287777777777[-#..\ +3 ", +" ~.#acaffar1<8727877777887777078288787(\'$+....\ +/t ", +" ~.#accccr([7778778772772877727022\'&+....>3n \ + ", +" ~.#afffr1<877287887770788272(&+....=|h \ + ", +" ~.#aafr[[78787727887722(-#....%/dt \ + ", +" ~.#afr1<2777877728(-#....@~dt \ + ", +" ~.#ar[[787777(-&....+~9q \ + ", +" ~.#m:<78(\'$+...+>3n \ + ", +" ~.#(\'&++...=|n \ + ", +" ~.....%/h \ + ", +" |=/dt \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + ", +" \ + " +}; +static Fl_Pixmap image_default(idata_default); + +Fl_Button *PrevButton=(Fl_Button *)0; + +static void cb_PrevButton(Fl_Button*, void*) { + Wizard->prev(); +int i; +for (i = 0; i < 4; i ++) +{ + Title[i]->activate(); + + if (Pane[i]->visible()) + break; +} + +for (i ++; i < 4; i ++) + Title[i]->deactivate(); +} + +Fl_Button *NextButton=(Fl_Button *)0; + +Fl_Button *CancelButton=(Fl_Button *)0; + +static void cb_CancelButton(Fl_Button*, void*) { + exit(0); +} + +Fl_Double_Window* make_window() { + { UninstallWindow = new Fl_Double_Window(640, 310, "Uninstall"); + UninstallWindow->callback((Fl_Callback*)cb_UninstallWindow); + { Title[0] = new Fl_Box(10, 10, 130, 25, "Welcome"); + Title[0]->labelfont(1); + Title[0]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* Title[0] + { Title[1] = new Fl_Box(10, 35, 130, 25, "Select Software"); + Title[1]->labelfont(1); + Title[1]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[1]->deactivate(); + } // Fl_Box* Title[1] + { Title[2] = new Fl_Box(10, 60, 130, 25, "Confirm"); + Title[2]->labelfont(1); + Title[2]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[2]->deactivate(); + } // Fl_Box* Title[2] + { Title[3] = new Fl_Box(10, 85, 130, 25, "Removing"); + Title[3]->labelfont(1); + Title[3]->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + Title[3]->deactivate(); + } // Fl_Box* Title[3] + { Wizard = new Fl_Wizard(150, 10, 480, 255); + Wizard->box(FL_THIN_DOWN_BOX); + Wizard->color((Fl_Color)48); + { Pane[0] = new Fl_Group(150, 10, 480, 255); + Pane[0]->labelfont(1); + Pane[0]->labelsize(18); + Pane[0]->labelcolor((Fl_Color)4); + Pane[0]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[0]->hide(); + { ReadmeFile = new Fl_Help_View(170, 30, 440, 215); + } // Fl_Help_View* ReadmeFile + Pane[0]->end(); + } // Fl_Group* Pane[0] + { Pane[1] = new Fl_Group(150, 10, 480, 255); + Pane[1]->labelfont(1); + Pane[1]->labelsize(18); + Pane[1]->labelcolor((Fl_Color)4); + Pane[1]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[1]->hide(); + { Fl_Box* o = new Fl_Box(170, 30, 440, 25, "Select the software to remove:"); + o->align(132|FL_ALIGN_INSIDE); + } // Fl_Box* o + { SoftwareList = new Fl_Check_Browser(170, 83, 440, 127, " Installed Software:"); + SoftwareList->type(3); + SoftwareList->box(FL_DOWN_BOX); + SoftwareList->selection_color(FL_BACKGROUND2_COLOR); + SoftwareList->labelfont(1); + SoftwareList->callback((Fl_Callback*)list_cb); + SoftwareList->align(FL_ALIGN_TOP_LEFT); + SoftwareList->when(3); + } // Fl_Check_Browser* SoftwareList + { SoftwareSize = new Fl_Box(170, 215, 220, 35, "0k marked for removal."); + SoftwareSize->align(196|FL_ALIGN_INSIDE); + } // Fl_Box* SoftwareSize + { RemoveAllButton = new Fl_Button(400, 220, 90, 25, "Remove All"); + RemoveAllButton->callback((Fl_Callback*)cb_RemoveAllButton); + } // Fl_Button* RemoveAllButton + { RemoveNoneButton = new Fl_Button(500, 220, 110, 25, "Remove None"); + RemoveNoneButton->callback((Fl_Callback*)cb_RemoveNoneButton); + } // Fl_Button* RemoveNoneButton + Pane[1]->end(); + } // Fl_Group* Pane[1] + { Pane[2] = new Fl_Group(150, 10, 480, 255); + Pane[2]->labelfont(1); + Pane[2]->labelsize(18); + Pane[2]->labelcolor((Fl_Color)4); + Pane[2]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + Pane[2]->hide(); + { Fl_Box* o = new Fl_Box(170, 30, 440, 25, "Confirm software selected for removal:"); + o->align(132|FL_ALIGN_INSIDE); + } // Fl_Box* o + { ConfirmList = new Fl_Browser(170, 83, 440, 162, "Software to Remove:"); + ConfirmList->labelfont(1); + ConfirmList->align(FL_ALIGN_TOP_LEFT); + } // Fl_Browser* ConfirmList + Pane[2]->end(); + } // Fl_Group* Pane[2] + { Pane[3] = new Fl_Group(150, 10, 480, 255); + Pane[3]->labelfont(1); + Pane[3]->labelsize(18); + Pane[3]->labelcolor((Fl_Color)4); + Pane[3]->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { RemovePercent = new Fl_Progress(170, 45, 440, 15, "Progress Label..."); + RemovePercent->color((Fl_Color)48); + RemovePercent->selection_color((Fl_Color)221); + RemovePercent->align(FL_ALIGN_TOP_LEFT); + } // Fl_Progress* RemovePercent + { RemoveLog = new Fl_Browser(170, 70, 440, 175); + } // Fl_Browser* RemoveLog + Pane[3]->end(); + } // Fl_Group* Pane[3] + Wizard->end(); + } // Fl_Wizard* Wizard + { WelcomeImage = new Fl_Box(10, 170, 130, 130); + WelcomeImage->image(image_default); + WelcomeImage->align(FL_ALIGN_BOTTOM_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* WelcomeImage + { PrevButton = new Fl_Button(396, 275, 72, 25, "@-2< Back"); + PrevButton->callback((Fl_Callback*)cb_PrevButton); + } // Fl_Button* PrevButton + { NextButton = new Fl_Button(478, 275, 74, 25, "Next @-2>"); + NextButton->callback((Fl_Callback*)next_cb); + } // Fl_Button* NextButton + { CancelButton = new Fl_Button(562, 275, 68, 25, "Cancel"); + CancelButton->callback((Fl_Callback*)cb_CancelButton); + } // Fl_Button* CancelButton + UninstallWindow->end(); + } // Fl_Double_Window* UninstallWindow + return UninstallWindow; +} diff --git a/uninst.fl b/uninst.fl new file mode 100644 index 0000000..43b3f37 --- /dev/null +++ b/uninst.fl @@ -0,0 +1,123 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 +header_name {.h} +code_name {.cxx} +Function {make_window()} {open +} { + Fl_Window UninstallWindow { + label Uninstall + callback {if (CancelButton->active()) + exit(0);} open selected + xywh {264 44 640 310} type Double + code0 {\#include "gui-common.h"} visible + } { + Fl_Box {Title[0]} { + label Welcome + xywh {10 10 130 25} labelfont 1 align 20 + } + Fl_Box {Title[1]} { + label {Select Software} + xywh {10 35 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[2]} { + label Confirm + xywh {10 60 130 25} labelfont 1 align 20 deactivate + } + Fl_Box {Title[3]} { + label Removing + xywh {10 85 130 25} labelfont 1 align 20 deactivate + } + Fl_Wizard Wizard {open + xywh {150 10 480 255} box THIN_DOWN_BOX color 48 + } { + Fl_Group {Pane[0]} {open + xywh {150 10 480 255} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Help_View ReadmeFile { + xywh {170 30 440 215} + } + } + Fl_Group {Pane[1]} {open + xywh {150 10 480 255} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Box {} { + label {Select the software to remove:} + xywh {170 30 440 25} align 148 + } + Fl_Check_Browser SoftwareList { + label { Installed Software:} + callback list_cb + xywh {170 83 440 127} type Multi box DOWN_BOX selection_color 7 labelfont 1 align 5 when 3 + } + Fl_Box SoftwareSize { + label {0k marked for removal.} + xywh {170 215 220 35} align 212 + } + Fl_Button RemoveAllButton { + label {Remove All} + callback {SoftwareList->check_all(); +list_cb(0,0);} + xywh {400 220 90 25} + } + Fl_Button RemoveNoneButton { + label {Remove None} + callback {SoftwareList->check_none(); +list_cb(0,0);} + xywh {500 220 110 25} + } + } + Fl_Group {Pane[2]} {open + xywh {150 10 480 255} labelfont 1 labelsize 18 labelcolor 4 align 21 hide + } { + Fl_Box {} { + label {Confirm software selected for removal:} + xywh {170 30 440 25} align 148 + } + Fl_Browser ConfirmList { + label {Software to Remove:} + xywh {170 83 440 162} labelfont 1 align 5 + } + } + Fl_Group {Pane[3]} {open + xywh {150 10 480 255} labelfont 1 labelsize 18 labelcolor 4 align 21 + } { + Fl_Progress RemovePercent { + label {Progress Label...} + xywh {170 45 440 15} color 48 selection_color 221 align 5 + } + Fl_Browser RemoveLog { + xywh {170 70 440 175} + } + } + } + Fl_Box WelcomeImage { + image {default.xpm} xywh {10 170 130 130} align 22 + } + Fl_Button PrevButton { + label {@-2< Back} + callback {Wizard->prev(); +int i; +for (i = 0; i < 4; i ++) +{ + Title[i]->activate(); + + if (Pane[i]->visible()) + break; +} + +for (i ++; i < 4; i ++) + Title[i]->deactivate();} + xywh {396 275 72 25} + } + Fl_Button NextButton { + label {Next @-2>} + callback next_cb + xywh {478 275 74 25} + } + Fl_Button CancelButton { + label Cancel + callback {exit(0);} + xywh {562 275 68 25} + } + } +} diff --git a/uninst.h b/uninst.h new file mode 100644 index 0000000..3e933ac --- /dev/null +++ b/uninst.h @@ -0,0 +1,35 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#ifndef uninst_h +#define uninst_h +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> +#include "gui-common.h" +extern Fl_Double_Window *UninstallWindow; +#include <FL/Fl_Box.H> +extern Fl_Box *Title[4]; +#include <FL/Fl_Wizard.H> +extern Fl_Wizard *Wizard; +#include <FL/Fl_Group.H> +#include <FL/Fl_Help_View.H> +extern Fl_Help_View *ReadmeFile; +#include <FL/Fl_Check_Browser.H> +extern void list_cb(Fl_Check_Browser*, void*); +extern Fl_Check_Browser *SoftwareList; +extern Fl_Box *SoftwareSize; +#include <FL/Fl_Button.H> +extern Fl_Button *RemoveAllButton; +extern Fl_Button *RemoveNoneButton; +#include <FL/Fl_Browser.H> +extern Fl_Browser *ConfirmList; +extern Fl_Group *Pane[4]; +#include <FL/Fl_Progress.H> +extern Fl_Progress *RemovePercent; +extern Fl_Browser *RemoveLog; +extern Fl_Box *WelcomeImage; +extern Fl_Button *PrevButton; +extern void next_cb(Fl_Button*, void*); +extern Fl_Button *NextButton; +extern Fl_Button *CancelButton; +Fl_Double_Window* make_window(); +#endif diff --git a/uninst2.cxx b/uninst2.cxx new file mode 100644 index 0000000..a551f08 --- /dev/null +++ b/uninst2.cxx @@ -0,0 +1,741 @@ +// +// "$Id: uninst2.cxx 834 2010-12-30 00:08:36Z mike $" +// +// ESP Software Removal Wizard main entry for the ESP Package Manager (EPM). +// +// Copyright 1999-2010 by Easy Software Products. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Contents: +// +// main() - Main entry for software wizard... +// list_cb() - Handle selections in the software list. +// load_image() - Load the setup image file (setup.gif/xpm)... +// load_readme() - Load the readme file... +// log_cb() - Add one or more lines of text to the removal log. +// next_cb() - Show software selections or remove software. +// remove_dist() - Remove a distribution... +// show_installed() - Show the installed software products. +// update_size() - Update the total +/- sizes of the installations. +// + +#define _DEFINE_GLOBALS_ +#include "uninst.h" +#include <FL/x.H> +#include <FL/filename.H> +#include <FL/fl_ask.H> +#include <FL/Fl_XPM_Image.H> +#include <FL/Fl_GIF_Image.H> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif // HAVE_SYS_PARAM_H + +#ifdef HAVE_SYS_MOUNT_H +# include <sys/mount.h> +#endif // HAVE_SYS_MOUNT_H + +#ifdef HAVE_SYS_STATFS_H +# include <sys/statfs.h> +#endif // HAVE_SYS_STATFS_H + +#ifdef HAVE_SYS_VFS_H +# include <sys/vfs.h> +#endif // HAVE_SYS_VFS_H + +#ifdef __osf__ +// No prototype for statfs under Tru64... +extern "C" { +extern int statfs(const char *, struct statfs *); +} +#endif // __osf__ + +#ifdef __APPLE__ +# include <Security/Authorization.h> +# include <Security/AuthorizationTags.h> + +AuthorizationRef SetupAuthorizationRef; +#endif // __APPLE__ + + +// +// Panes... +// + +#define PANE_WELCOME 0 +#define PANE_SELECT 1 +#define PANE_CONFIRM 2 +#define PANE_REMOVE 3 + + +// +// Local functions... +// + +void load_image(void); +void load_readme(void); +void log_cb(int fd, int *fdptr); +int remove_dist(const gui_dist_t *dist); +void show_installed(void); +void update_sizes(void); + + +// +// 'main()' - Main entry for software wizard... +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + Fl_Window *w; // Main window... + + + // Use GTK+ scheme for all operating systems... + Fl::background(230, 230, 230); + Fl::scheme("gtk+"); + +#ifdef __APPLE__ + // OSX passes an extra command-line option when run from the Finder. + // If the first command-line argument is "-psn..." then skip it and use the full path + // to the executable to figure out the distribution directory... + if (argc > 1) + { + if (strncmp(argv[1], "-psn", 4) == 0) + { + char *ptr; // Pointer into basedir + static char basedir[1024]; // Base directory (static so it can be used below) + + + strlcpy(basedir, argv[0], sizeof(basedir)); + if ((ptr = strrchr(basedir, '/')) != NULL) + *ptr = '\0'; + if ((ptr = strrchr(basedir, '/')) != NULL && !strcasecmp(ptr, "/MacOS")) + { + // Got the base directory, now add "Resources" to it... + *ptr = '\0'; + strlcat(basedir, "/Resources", sizeof(basedir)); + chdir(basedir); + } + } + } +#endif // __APPLE__ + + w = make_window(); + + Pane[PANE_WELCOME]->show(); + PrevButton->deactivate(); + NextButton->deactivate(); + + gui_get_installed(); + show_installed(); + + load_image(); + load_readme(); + + w->show(); + + while (!w->visible()) + Fl::wait(); + +#ifdef __APPLE__ + OSStatus status; + + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, + kAuthorizationFlagDefaults, + &SetupAuthorizationRef); + if (status != errAuthorizationSuccess) + { + fl_alert("You must have administrative priviledges to remove this software!"); + return (1); + } + + AuthorizationItem items = { kAuthorizationRightExecute, 0, NULL, 0 }; + AuthorizationRights rights = { 1, &items }; + + status = AuthorizationCopyRights(SetupAuthorizationRef, &rights, NULL, + kAuthorizationFlagDefaults | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize | + kAuthorizationFlagExtendRights, NULL); + + if (status != errAuthorizationSuccess) + { + fl_alert("You must have administrative priviledges to remove this software!"); + return (1); + } +#else + if (getuid() != 0) + { + fl_alert("You must be logged in as root to run uninstall!"); + return (1); + } +#endif // __APPLE__ + + NextButton->activate(); + + Fl::run(); + +#ifdef __APPLE__ + AuthorizationFree(SetupAuthorizationRef, kAuthorizationFlagDefaults); +#endif // __APPLE__ + + return (0); +} + + +// +// 'list_cb()' - Handle selections in the software list. +// + +void +list_cb(Fl_Check_Browser *, void *) +{ + int i, j, k; + gui_dist_t *dist, + *dist2; + gui_depend_t *depend; + + + if (SoftwareList->nchecked() == 0) + { + update_sizes(); + + NextButton->deactivate(); + return; + } + + for (i = 0, dist = Installed; i < NumInstalled; i ++, dist ++) + if (SoftwareList->checked(i + 1)) + { + // Check for required/incompatible products... + for (j = 0, depend = dist->depends; j < dist->num_depends; j ++, depend ++) + switch (depend->type) + { + case DEPEND_REQUIRES : + if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) != NULL) + { + // Software is in the list, is it selected? + k = dist2 - Installed; + + if (SoftwareList->checked(k + 1)) + continue; + + // Nope, select it unless we're unchecked another selection... + if (SoftwareList->value() != (k + 1)) + SoftwareList->checked(k + 1, 1); + else + { + SoftwareList->checked(i + 1, 0); + break; + } + } + else if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) == NULL) + { + // Required but not installed or available! + fl_alert("%s requires %s to be installed, but it is not available " + "for installation.", dist->name, depend->product); + SoftwareList->checked(i + 1, 0); + break; + } + break; + + case DEPEND_INCOMPAT : + if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) != NULL) + { + // Already installed! + fl_alert("%s is incompatible with %s. Please remove it before " + "installing this software.", dist->name, dist2->name); + SoftwareList->checked(i + 1, 0); + break; + } + else if ((dist2 = gui_find_dist(depend->product, NumInstalled, + Installed)) != NULL) + { + // Software is in the list, is it selected? + k = dist2 - Installed; + + // Software is in the list, is it selected? + if (!SoftwareList->checked(k + 1)) + continue; + + // Yes, tell the user... + fl_alert("%s is incompatible with %s. Please deselect it before " + "installing this software.", dist->name, dist2->name); + SoftwareList->checked(i + 1, 0); + break; + } + default : + break; + } + } + + update_sizes(); + + if (SoftwareList->nchecked()) + NextButton->activate(); + else + NextButton->deactivate(); +} + + +// +// 'load_image()' - Load the setup image file (setup.gif/xpm)... +// + +void +load_image(void) +{ + Fl_Image *img; // New image + + + if (!access("setup.xpm", 0)) + img = new Fl_XPM_Image("setup.xpm"); + else if (!access("setup.gif", 0)) + img = new Fl_GIF_Image("setup.gif"); + else + img = NULL; + + if (img) + WelcomeImage->image(img); +} + + +// +// 'load_readme()' - Load the readme file... +// + +void +load_readme(void) +{ + ReadmeFile->textfont(FL_HELVETICA); + ReadmeFile->textsize(14); + + if (access("uninst.readme", 0)) + { + int i; // Looping var + gui_dist_t *dist; // Current distribution + char *buffer, // Text buffer + *ptr; // Pointer into buffer + + + buffer = new char[1024 + NumInstalled * 400]; + + strcpy(buffer, "This program allows you to remove the following " + "software:</p>\n" + "<ul>\n"); + ptr = buffer + strlen(buffer); + + for (i = NumInstalled, dist = Installed; i > 0; i --, dist ++) + { + sprintf(ptr, "<li>%s, %s\n", dist->name, dist->version); + ptr += strlen(ptr); + } + + strcpy(ptr, "</ul>"); + + ReadmeFile->value(buffer); + + delete[] buffer; + } + else + gui_load_file(ReadmeFile, "uninst.readme"); + +} + + +// +// 'log_cb()' - Add one or more lines of text to the removal log. +// + +void +log_cb(int fd, // I - Pipe to read from + int *fdptr) // O - Pipe to read from +{ + int bytes; // Bytes read/to read + char *bufptr; // Pointer into buffer + static int bufused = 0; // Number of bytes used + static char buffer[8193]; // Buffer + + + bytes = 8192 - bufused; + if ((bytes = read(fd, buffer + bufused, bytes)) <= 0) + { + // End of file; zero the FD to tell the remove_dist() function to + // stop... + + Fl::remove_fd(fd); + close(fd); + *fdptr = 0; + + if (bufused > 0) + { + // Add remaining text... + buffer[bufused] = '\0'; + RemoveLog->add(buffer); + bufused = 0; + } + } + else + { + // Add bytes to the buffer, then add lines as needed... + bufused += bytes; + buffer[bufused] = '\0'; + + while ((bufptr = strchr(buffer, '\n')) != NULL) + { + *bufptr++ = '\0'; + RemoveLog->add(buffer); + strcpy(buffer, bufptr); + bufused -= bufptr - buffer; + } + } + + RemoveLog->bottomline(RemoveLog->size()); +} + + +// +// 'next_cb()' - Show software selections or remove software. +// + +void +next_cb(Fl_Button *, void *) +{ + int i; // Looping var + int progress; // Progress so far... + int error; // Errors? + static char message[1024]; // Progress message... + static int removing = 0; // Removing software? + + + Wizard->next(); + + PrevButton->deactivate(); + + if (Wizard->value() == Pane[PANE_CONFIRM]) + { + ConfirmList->clear(); + PrevButton->activate(); + + for (i = 0; i < NumInstalled; i ++) + if (SoftwareList->checked(i + 1)) + ConfirmList->add(SoftwareList->text(i + 1)); + } + + if (Wizard->value() == Pane[PANE_REMOVE] && !removing) + { + removing = 1; + + NextButton->deactivate(); + CancelButton->deactivate(); + CancelButton->label("Close"); + + for (i = 0, progress = 0, error = 0; i < NumInstalled; i ++) + if (SoftwareList->checked(i + 1)) + { + sprintf(message, "Removing %s v%s...", Installed[i].name, + Installed[i].version); + + RemovePercent->value(100.0 * progress / SoftwareList->nchecked()); + RemovePercent->label(message); + Pane[PANE_REMOVE]->redraw(); + + if ((error = remove_dist(Installed + i)) != 0) + break; + + progress ++; + } + + RemovePercent->value(100.0); + + if (error) + RemovePercent->label("Removal Failed!"); + else + RemovePercent->label("Removal Complete"); + + Pane[PANE_REMOVE]->redraw(); + + CancelButton->activate(); + + fl_beep(); + + removing = 0; + } + else if (Wizard->value() == Pane[PANE_SELECT] && + SoftwareList->nchecked() == 0) + NextButton->deactivate(); +} + + +// +// 'remove_dist()' - Remove a distribution... +// + +int // O - Remove status +remove_dist(const gui_dist_t *dist) // I - Distribution to remove +{ + char command[1024]; // Command string + int fds[2]; // Pipe FDs + int status; // Exit status +#ifndef __APPLE__ + int pid; // Process ID +#endif // !__APPLE__ + + snprintf(command, sizeof(command), "**** %s ****", dist->name); + RemoveLog->add(command); + + if (dist->type == PACKAGE_PORTABLE) + snprintf(command, sizeof(command), EPM_SOFTWARE "/%s.remove", + dist->product); + +#ifdef __APPLE__ + // Run the remove script using Apple's authorization API... + FILE *fp = NULL; + char *args[2] = { (char *)"now", NULL }; + OSStatus astatus; + + + astatus = AuthorizationExecuteWithPrivileges(SetupAuthorizationRef, command, kAuthorizationFlagDefaults, + args, &fp); + + if (astatus != errAuthorizationSuccess) + { + RemoveLog->add("Failed to execute remove script!"); + return (1); + } + + fds[0] = fileno(fp); +#else + // Fork the command and redirect errors and info to stdout... + pipe(fds); + + if ((pid = fork()) == 0) + { + // Child comes here; start by redirecting stdout and stderr... + close(1); + close(2); + dup(fds[1]); + dup(fds[1]); + + // Close the original pipes... + close(fds[0]); + close(fds[1]); + + // Execute the command; if an error occurs, return it... + if (dist->type == PACKAGE_PORTABLE) + execl(command, command, "now", (char *)0); + else + execlp("rpm", "rpm", "-e", "--nodeps", dist->product, (char *)0); + + exit(errno); + } + else if (pid < 0) + { + // Unable to fork! + sprintf(command, "Unable to remove %s:", dist->name); + RemoveLog->add(command); + + sprintf(command, "\t%s", strerror(errno)); + RemoveLog->add(command); + + close(fds[0]); + close(fds[1]); + + return (1); + } + + // Close the output pipe (used by the child)... + close(fds[1]); +#endif // __APPLE__ + + // Listen for data on the input pipe... + Fl::add_fd(fds[0], (void (*)(int, void *))log_cb, fds); + + // Show the user that we're busy... + UninstallWindow->cursor(FL_CURSOR_WAIT); + + // Loop until the child is done... + while (fds[0]) // log_cb() will close and zero fds[0]... + { + // Wait for events... + Fl::wait(); + +#ifndef __APPLE__ + // Check to see if the child went away... + if (waitpid(0, &status, WNOHANG) == pid) + break; +#endif // !__APPLE__ + } + +#ifdef __APPLE__ + fclose(fp); +#endif // __APPLE__ + + if (fds[0]) + { + // Close the pipe - have all the data from the child... + Fl::remove_fd(fds[0]); + close(fds[0]); + } + else + { + // Get the child's exit status... + wait(&status); + } + + // Show the user that we're ready... + UninstallWindow->cursor(FL_CURSOR_DEFAULT); + + // Return... + return (status); +} + + +// +// 'show_installed()' - Show the installed software products. +// + +void +show_installed() +{ + int i; // Looping var + gui_dist_t *temp; // Pointer to current distribution + char line[1024]; // Product name and version... + + + if (NumInstalled == 0) + { + fl_alert("No software found to remove!"); + exit(1); + } + + for (i = 0, temp = Installed; i < NumInstalled; i ++, temp ++) + { + sprintf(line, "%s v%s", temp->name, temp->version); + + SoftwareList->add(line, 0); + } + + update_sizes(); +} + + +// +// 'update_size()' - Update the total +/- sizes of the installations. +// + +void +update_sizes(void) +{ + int i; // Looping var + gui_dist_t *dist, // Distribution + *installed; // Installed distribution + int rootsize, // Total root size difference in kbytes + usrsize; // Total /usr size difference in kbytes + struct statfs rootpart, // Available root partition + usrpart; // Available /usr partition + int rootfree, // Free space on root partition + usrfree; // Free space on /usr partition + static char sizelabel[1024];// Label for selected sizes... + + + // Get the sizes for the selected products... + for (i = 0, dist = Installed, rootsize = 0, usrsize = 0; + i < NumInstalled; + i ++, dist ++) + if (SoftwareList->checked(i + 1)) + { + rootsize += dist->rootsize; + usrsize += dist->usrsize; + + if ((installed = gui_find_dist(dist->product, NumInstalled, + Installed)) != NULL) + { + rootsize -= installed->rootsize; + usrsize -= installed->usrsize; + } + } + + // Get the sizes of the root and /usr partition... +#if defined(__sgi) || defined(__svr4__) || defined(__SVR4) || defined(M_XENIX) + if (statfs("/", &rootpart, sizeof(rootpart), 0)) +#else + if (statfs("/", &rootpart)) +#endif // __sgi || __svr4__ || __SVR4 || M_XENIX + rootfree = 1024; + else + rootfree = (int)((double)rootpart.f_bfree * (double)rootpart.f_bsize / + 1024.0 / 1024.0 + 0.5); + +#if defined(__sgi) || defined(__svr4__) || defined(__SVR4) || defined(M_XENIX) + if (statfs("/usr", &usrpart, sizeof(usrpart), 0)) +#else + if (statfs("/usr", &usrpart)) +#endif // __sgi || __svr4__ || __SVR4 || M_XENIX + usrfree = 1024; + else + usrfree = (int)((double)usrpart.f_bfree * (double)usrpart.f_bsize / + 1024.0 / 1024.0 + 0.5); + + // Display the results to the user... + if (rootfree == usrfree) + { + rootsize += usrsize; + + if (rootsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required, %dm available.", rootsize / 1024.0, + rootfree); + else + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required, %dm available.", rootsize, rootfree); + } + else if (rootsize >= 1024 && usrsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required on /, %dm available,\n" + "%+.1fm required on /usr, %dm available.", + rootsize / 1024.0, rootfree, usrsize / 1024.0, usrfree); + else if (rootsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+.1fm required on /, %dm available,\n" + "%+dk required on /usr, %dm available.", + rootsize / 1024.0, rootfree, usrsize, usrfree); + else if (usrsize >= 1024) + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required on /, %dm available,\n" + "%+.1fm required on /usr, %dm available.", + rootsize, rootfree, usrsize / 1024.0, usrfree); + else + snprintf(sizelabel, sizeof(sizelabel), + "%+dk required on /, %dm available,\n" + "%+dk required on /usr, %dm available.", + rootsize, rootfree, usrsize, usrfree); + + SoftwareSize->label(sizelabel); + SoftwareSize->redraw(); +} + + +// +// End of "$Id: uninst2.cxx 834 2010-12-30 00:08:36Z mike $". +// |