smart-1.4.orig/0000755000000000000000000000000011545144044010333 5ustar smart-1.4.orig/smart.py0000755000000000000000000001412011545144020012026 0ustar #!/usr/bin/env python # # Copyright (c) 2004 Conectiva, Inc. # # Written by Gustavo Niemeyer # # This file is part of Smart Package Manager. # # Smart Package Manager 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. # # Smart Package Manager 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 Smart Package Manager; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import sys if sys.version_info < (2, 3): sys.exit("error: Python 2.3 or later required") from smart import init, initDistro, initPlugins, initPycurl, initPsyco from smart.const import VERSION, DATADIR from smart.option import OptionParser from smart import * import pwd import os # Avoid segfault due to strange linkage order. Remove this ASAP. import pyexpat USAGE=_("smart command [options] [arguments]") DESCRIPTION=_(""" Action commands: update install reinstall upgrade remove check fix download clean Query commands: search query newer info stats Setup commands: config channel priority mirror flag Run "smart command --help" for more information. """) EXAMPLES = _(""" smart install --help smart install pkgname smart --gui smart --gui install pkgname smart --shell """) def parse_options(argv): parser = OptionParser(usage=USAGE, description=DESCRIPTION, examples=EXAMPLES, skipunknown=True, add_help_option=False, version="smart %s" % VERSION) parser.add_option("--config-file", metavar=_("FILE"), help=_("configuration file " "(default is /config)")) parser.add_option("--data-dir", metavar=_("DIR"), help=_("data directory (default is %s)") % DATADIR) parser.add_option("--log-level", metavar=_("LEVEL"), help=_("set the log level to LEVEL (debug, info, " "warning, error)")) parser.add_option("--gui", action="store_true", help=_("use the default graphic interface")) parser.add_option("--shell", action="store_true", help=_("use the default shell interface")) parser.add_option("--quiet", action="store_true", help=_("use the quiet interface")) parser.add_option("--interface", metavar=_("NAME"), help=_("use the given interface")) parser.add_option("--ignore-locks", action="store_true", help=_("don't respect locking")) parser.add_option("-o", "--option", action="append", default=[], metavar=_("OPT"), help=_("set the option given by a name=value pair")) opts, args = parser.parse_args() if args: opts.command = arg = args[0] opts.argv = args[1:] if arg and arg[0] == "-": if arg == "-h" or len(arg) > 2 and "--help".startswith(arg): parser.print_help() sys.exit(0) else: raise Error, _("no such option: %s") % arg else: opts.command = None opts.argv = [] if not (opts.command or opts.gui or opts.shell or opts.interface): parser.print_help() sys.exit(1) return opts def set_config_options(options): import re globals = {} globals["__builtins__"] = {} globals["True"] = True globals["true"] = True globals["yes"] = True globals["False"] = False globals["false"] = False globals["no"] = False SETRE = re.compile(r"^(\S+?)(\+?=)(.*)$") for opt in options: m = SETRE.match(opt) if not m: raise Error, _("Invalid option: %s") % opt path, assign, value = m.groups() try: value = int(value) except ValueError: try: value = eval(value, globals) except: pass if assign == "+=": sysconf.add(path, value, soft=True) else: sysconf.set(path, value, soft=True) def main(argv): # Get the right $HOME, even when using sudo. if os.getuid() == 0: os.environ["HOME"] = pwd.getpwuid(0)[5] opts = None ctrl = None exitcode = 1 try: opts = parse_options(argv) ctrl = init(command=opts.command, argv=opts.argv, datadir=opts.data_dir, configfile=opts.config_file, gui=opts.gui, shell=opts.shell, quiet=opts.quiet, interface=opts.interface, forcelocks=opts.ignore_locks, loglevel=opts.log_level) if opts.option: set_config_options(opts.option) initDistro(ctrl) initPlugins() initPycurl() initPsyco() exitcode = iface.run(opts.command, opts.argv) if exitcode is None: exitcode = 0 ctrl.saveSysConf() ctrl.restoreMediaState() except Error, e: if opts and opts.log_level == "debug": import traceback traceback.print_exc() if iface.object: iface.error(unicode(e)) else: sys.stderr.write(_("error: %s\n") % e) if ctrl: ctrl.saveSysConf() ctrl.restoreMediaState() except KeyboardInterrupt: if opts and opts.log_level == "debug": import traceback traceback.print_exc() sys.exit(1) sys.stderr.write(_("\nInterrupted\n")) print if exitcode != 0: sys.exit(exitcode) if __name__ == "__main__": main(sys.argv[1:]) # vim:ts=4:sw=4:et smart-1.4.orig/MANIFEST.in0000644000000000000000000000153711545144020012071 0ustar recursive-include smart *.py *.c *.h *.png include smart setup.cfg MANIFEST.in HACKING IDEAS TODO LICENSE README Makefile include doc/README.html doc/default.css doc/smart.8 doc/sysconf-index include smart/backends/rpm/README recursive-include tests *.py *.txt recursive-include tests/data * include test recursive-include contrib/ksmarttray *.png *.cc *.h *.am *.in.in recursive-include contrib/ksmarttray LICENSE eventsrc AUTHORS build.sh recursive-include contrib/ksmarttray ChangeLog COPYING INSTALL NEWS README recursive-include contrib/ksmarttray ksmarttray.desktop graft contrib/ksmarttray/admin recursive-include contrib/smart-update *.c Makefile recursive-include contrib/patches * recursive-include contrib/rpmhelper * recursive-include contrib/servicemenus * recursive-include contrib/bash-completion * recursive-include locale *.pot *.po *.mo smart-1.4.orig/doc/0000755000000000000000000000000011571172604011102 5ustar smart-1.4.orig/doc/sysconf-index0000644000000000000000000000121311545144020013603 0ustar A index of the various sysconf variables and what they do: ---------------------------------------------------------- commit-log: a filename to write a logfile of commited changesets data-dir: the main datadir of smart commit: do we actually want to commit the operation remove-packages: should downloaded packages removed after they where applied prefer-removable: should we prefer removable over the network dist-cache: do we use a cache mirrors: mirrors-history: force-channels: log-level: channels: the channels known to smart detectlocalchannels-maxdepth: socket-timeout: max-active-downloads: %s-proxy: default-localmedia: sorter-profile: smart-1.4.orig/doc/default.css0000644000000000000000000001132411545144020013231 0ustar /* :Author: David Goodger :Contact: goodger@users.sourceforge.net :Date: $Date: 2004/11/13 21:02:20 $ :Version: $Revision: 1.44 $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. */ body { background-color: white } /* "! important" is used here to override other ``margin-top`` and ``margin-bottom`` styles that are later in the stylesheet or more specific. See . */ .first { margin-top: 0 ! important } .last { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } /* Uncomment (& remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { color: red ; font-weight: bold ; font-family: sans-serif } div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em } div.footer, div.header { font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin-left: 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font-family: serif ; font-size: 100% } pre.line-block { font-family: serif ; font-size: 100% } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; background-color: #eeeeee } span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.option-argument { font-style: italic } span.pre { white-space: pre } span.problematic { color: red } table.citation { border-left: solid thin gray } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid thin black } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } th.docinfo-name, th.field-name { font-weight: bold ; text-align: left ; white-space: nowrap } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } tt.docutils { background-color: #eeeeee } ul.auto-toc { list-style-type: none } smart-1.4.orig/doc/smart.80000644000000000000000000000347511545144020012322 0ustar .\" smart - The Smart Package Manager .TH "smart" "8" "2006 Jun 16" "Christoph Thiel" "" .SH "NAME" smart \- The Smart Package Manager .SH "SYNOPSIS" \fBsmart\fP command [options] [arguments] .SH "DESCRIPTION" The \fBSmart\fP Package Manager project has the ambitious objective of creating smart and portable algorithms for solving adequately the problem of managing software upgrading and installation. This tool works in all major distributions, and will bring notable advantages over native tools currently in use (APT, APT\-RPM, YUM, URPMI, etc). .SH "Action commands" .nf update install reinstall upgrade remove check fix download clean .fi .SH "Setup commands" .nf channel priority mirror flag .fi .SH "Query commands" .nf search query info stats .fi Run "smart command \-\-help" for more information. .SH "Options" .PP .IP "\fB\-\-version\fP" Show program's version number and exit .IP "\fB\-\-config\-file=FILE\fP" Configuration file (default is /config) .IP "\fB\-\-data\-dir=DIR\fP" Specifies the config file location \- can take http, ftp urls and local file Data directory (default is /var/lib/smart/) .IP "\fB\-\-log\-level=LEVEL\fP" Set the log level to level (debug, info, warning, error) .IP "\fB\-\-gui\fP" Use the default graphic interface .IP "\fB\-\-shell\fP" Use the default shell interface .IP "\fB\-\-interface=NAME\fP" Use the given interface .IP "\fB\-\-ignore\-locks\fP" Don't respect locking .IP "\fB\-o OPT, \-\-option=OPT\fP" Set the option given by a name=value pair .SH "Examples" .nf smart install \-\-help smart install pkgname smart \-\-gui smart \-\-gui install pkgname smart \-\-shell .fi .SH "FILES" .nf /etc/smart/ /var/lib/smart/ /usr/lib/smart/ /usr/lib/smart/plugins/ .fi .SH "SEE ALSO" .nf http://labix.org/smart .fi .SH "AUTHOR" .nf Gustavo Niemeyer .fi smart-1.4.orig/doc/README.html0000644000000000000000000010602511545144020012721 0ustar Smart Package Manager

Smart Package Manager

Author: Gustavo Niemeyer
Contact: niemeyer@conectiva.com
Revision: $Rev$
Date: $Date$

Overview

The Smart Package Manager project has the ambitious objective of creating smart and portable algorithms for solving adequately the problem of managing software upgrading and installation. This tool works in all major distributions, and will bring notable advantages over native tools currently in use (APT, APT-RPM, YUM, URPMI, etc).

From The Free On-line Dictionary of Computing:

smart

    1. <programming> Said of a program that does the {Right Thing}
    in a wide variety of complicated circumstances. (...)

Project Status

The development of Smart Package Manager started on May 4th, 2004, and version 1.0 was released on Aug 14th, 2008, after extended beta testing.

Features

Modular

Smart has been developed with modularity and flexibility in mind. It's completely backend-based, and package-manager-agnostic. Support is currently implemented for RPM, DPKG, and Slackware package management systems, and porting it to new systems should be very easy.

Smart Transactions

That's one of the most interesting aspects of Smart Package Manager, and the one who has motivated calling it smart. Computing transactions respecting the relations involved in the package management world may become an unpleasant task when thousands of packages and relations are being considered, or even when just a few complex relations turn the most obvious choice into the unwanted one.

While other applications try to find a possible solution to satisfy the relations involved in some user-requested operation, and sometimes even fail to do so [1], Smart goes beyond it. In the kernel of Smart Package Manager lives an algorithm that will not only find a solution, if one is available, but will find the best solution. This is done by quickly weighting every possible solution with a pluggable policy, which redefines the term "best" depending on the operation goal (install, remove, upgrade, etc).

This behavior has many interesting consequences. In upgrades, for instance, while precedence is given to newer versions, intermediate versions may get selected if they bring a better global result for the system. Packages may even be reinstalled, if different packages with the same name-version pair have different relations, and the one not installed is considered a better option.

Another important goal achieved with the transaction algorithm is that, even though it is able to check and fix relations in the whole system, it will work even when there are broken relations in installed packages. Only relations related to the operation being made are checked for correctness.

[1]Check Case Studies for real cases where the algorithm works better than what is implemented in other applications.

Multiple Interfaces

Smart has multiple native and completely integrated interfaces:

  • Command line interface, with several useful subcommands: update, install, reinstall, upgrade, remove, check, fix, download, search, and more.
  • Shell interface, with command and argument completion, making it easy to perform multiple operations quickly using a local or remote terminal.
  • Graphic interface, offering the friendliness of visual user interaction.
  • Command line interface with graphic feedback, allowing one to integrate the power of command line with graphic environments.

Besides these interfaces, ksmarttray is also included in the Smart package. It notifies users about available updates using a KDE tray icon.

Channels

Channels are the way Smart becomes aware about external repositories of information. Many different channel types are supported, depending on the backend and kind of information desired:

  • APT-DEB Repository
  • APT-RPM Repository
  • DPKG Installed Packages
  • Mirror Information
  • Red Carpet Channel
  • RPM Directory
  • RPM Header List
  • RPM MetaData (YUM)
  • RPM Installed Packages
  • Slackware Repository
  • Slackware Installed Packages
  • URPMI Repository

Priority Handling

Priorities are a powerful way to easily handle integration of multiple channels and explicit user setups regarding preferred package versions.

Basically, packages with higher priorities are considered a better option to be installed in the system, even when package versions state otherwise. Priorities may be individually assigned to all packages in given channels, to all packages with given names, and to packages with given names inside given channels.

With custom priority setups, it becomes possible to avoid unwanted upgrades, force downgrades, select packages in given channels as preferential, and other kinds of interesting setups.

Autobalancing Mirror System

Smart offers a very flexible mirror support. Mirrors are URLs that supposedly provide the same contents as are available in other URLs, named origins. There is no internal restriction on the kind of information which is mirrored. Once an origin URL is provided, and one or more mirror URLs are provided, these mirrors will be considered for any file which is going to be fetched from an URL starting with the origin URL.

Mirror precedence is dynamically computed based on the history of downloads of all mirrors available for a given origin URL (including the origin site itself). The fastest mirrors and with less errors are chosen. When errors occur, the next mirror in the queue is tried.

For instance, if a mirror http://mirror.url/path/ is provided for the origin ftp://origin.url/other/path/, and a file in ftp://origin.url/other/path/subpath/somefile is going to be fetched, the mirror will be considered for being used, and the URL http://mirror.url/path/subpath/somefile will be used if the mirror is chosen. Notice that strings are compared and replaced without any pre-processing, so that it's possible to use different schemes (ftp, http, etc) in mirror entries, and even URLs ending in prefixes of directory entries.

Downloading Mechanism

Smart has a fast parallel downloading mechanism, allowing multiple connections to be used for one or more sites. The mechanism supports:

  • Resuming
  • Timestamp checking
  • Parallel uncompression
  • Autodetection of FTP user limit
  • Cached file validation

and more.

At the moment, the following schemes are nativelly supported:

  • file
  • ftp
  • http
  • https
  • scp

Additionally, the following schemes are supported when pycurl is available:

  • ftps
  • telnet
  • dict
  • ldap

Removable Media Support

Smart Package Manager implements builtin support for removable media (CDROMs, DVDs, etc) in most of the supported channel types. The following features are currently implemented:

  • Mountpoint autodetection
  • Support for multiple simultaneous media drives
  • Medias may be inserted in any order
  • Installed system is guaranteed to maintain correct relations between media changes
  • Remote removable media support using any of the supported schemes (ftp, http, scp, etc)

Running Smart

Smart Package Manager may be run in many different ways, depending on the interface in use and on the intended goal.

The following command would install the foobar package, for instance:

smart install foobar

While the following command would install the foobar package, but with graphic output:

smart --gui install foobar

To open the graphic interface in interactive mode, one may simply run:

smart --gui

Similarly, the following command would open the shell interface:

smart --shell

Extensive help is available for all commands, by using the --help switch:

smart --help
smart install --help
smart channel --help
...

Building Smart

Dependencies

Core:

Smart is written in Python, with some core modules rewritten as C extensions for memory savings and performance gains. With that in mind, the core system of Smart depends on Python 2.3 or higher, and a C compiler to build the extensions.

Graphic Interface:
 

The "gtk" graphic interface depends on pygtk 2.4 or higher. The "qt" graphic interface depends on pyqt 3.3 (not 4.x).

RPM backend:

The RPM backend depends on the Python rpm module of RPM 4.4 or higher, due to a limitation which was present in previous versions of the ts.dbMatch() method, and the availability of the readHeaderFromFD() function.

In the contrib/patches/ subdirectory there are patches for previous RPM versions including the missing functionality. There are also pre-packaged binary versions which include the patched module without requiring changes in other tools.

DPKG backend:

There are no extra dependencies besides DPKG itself.

Slackware backend:
 

There are no extra dependencies besides the packaging scripts installpkg, upgradepkg and removepkg.

Case Studies

In this section will be described real cases showing Smart behavior in comparison with other tools, or handling unusual situations.

Notice that Smart was not tuned to work in any of these cases, and the reason it works is because handling unusual situations was the initial project goal.

Case 1 - APT

This case happened in a real world environment where a weakness in the algorithm used by APT (which is the same used in APT-RPM) turned a simple operation into a problem of obscure results. Smart Package Manager was used in the same environment to show its results.

The problem starts when an installation of xscreensaver is tried:

[root@damien:/root] apt-get install xscreensaver
Reading Package Lists... Done
Building Dependency Tree... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.

Since you only requested a single operation it is extremely likely that
the package is simply not installable and a bug report against
that package should be filed.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  xscreensaver: Depends: libglade-2.0.so.0
                Depends: libxml2.so.2
E: Broken packages

The error shown makes the user believe that libglade-2.0.so.0 and libxml2.so.2 are not available. That's not the case:

[root@damien:/root] apt-get install libxml2
Reading Package Lists... Done
Building Dependency Tree... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.

Since you only requested a single operation it is extremely likely that
the package is simply not installable and a bug report against
that package should be filed.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  libxml2: Depends: glibc-iconv but it is not going to be installed
E: Broken packages

Another misguiding error message. Let's go further:

[root@damien:/root] apt-get install glibc-iconv
Reading Package Lists... Done
Building Dependency Tree... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.

Since you only requested a single operation it is extremely likely that
the package is simply not installable and a bug report against
that package should be filed.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  glibc-iconv: Depends: glibc-gconvdata (= 2.3.3) but 1:2.3.2-586_1cl is to be installed
E: Broken packages

Version 2.3.3 is needed, but 1:2.3.2-586_1cl is to be installed. This message is mostly correct. The only problem is, "1:2.3.2-586_1cl" is already installed:

[root@damien:/root] apt-cache policy glibc-gconvdata
glibc-gconvdata:
  Installed: 1:2.3.2-586_1cl
  Candidate: 1:2.3.2-586_1cl
  Version Table:
 *** 1:2.3.2-586_1cl 0
        100 RPM Database
     0:2.3.3-69473cl 0
        500 file: conectiva/all pkglist

The problem was found. A package from another repository (586_1cl shows it's not native, in that specific case) has a higher epoch than the one available in the usual repository. This clearly shows that the APT algorithm marks a single version as candidate, and when this is not the wanted version for some operation, the whole operation is compromised.

When testing Smart Package Manager in the same environment, the expected result is obtained:

[root@damien:/root] smart install xscreensaver
Updating cache...              ######################################## [100%]

Computing transaction...

Downgrading packages (1):
  glibc-gconvdata-0:2.3.3-69473cl.i386

Installing packages (4):
  glibc-iconv-0:2.3.3-69473cl.i386
  libglade2-2.4.0-68154cl.i386
  libxml2-2:2.6.13-67598cl.i386
  xscreensaver-4.15-69825cl.i386

Confirm changes (Y/n)?

Smart correctly selected glibc-gconvdata for downgrading as the only possibility of performing the user requested operation.

Case 2 - APT & YUM

This is another real case, and is being reproduced in a controlled environment for tests with YUM, APT-RPM, and Smart.

The issue is, a package named A requires package BCD explicitly, and RPM detects implicit dependencies between A and libB, libC, and libD. Package BCD provides libB, libC, and libD, but additionally there is a package B providing libB, a package C providing libC, and a package D providing libD.

In other words, there's a package A which requires four different symbols, and one of these symbols is provided by a single package BCD, which happens to provide all symbols needed by A. There are also packages B, C, and D, that provide some of the symbols required by A, but can't satisfy all dependencies without BCD.

The expected behavior for an operation asking to install A is obviously selecting BCD to satisfy A's dependencies, on the other hand, YUM and APT fail to deliver that as a guaranteed operation, as is shown below.

First, let's see how YUM deals with the problem:

[root@burma ~]% yum install A
Setting up Install Process
Setting up Repo:  localpub
repomd.xml                100% |=========================|  951 B    00:00
Reading repository metadata in from local files
localpub  : ################################################## 5/5
Resolving Dependencies
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for A to pack into transaction set.
A-1.0-1cl.i386.rpm        100% |=========================| 1.0 kB    00:00
---> Package A.i386 0:1.0-1cl set to be installed
--> Running transaction check
--> Processing Dependency: libD for package: A
--> Processing Dependency: libC for package: A
--> Processing Dependency: libB for package: A
--> Processing Dependency: BCD for package: A
--> Restarting Dependency Resolution with new changes.
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for D to pack into transaction set.
D-1.0-1cl.i386.rpm        100% |=========================| 1.0 kB    00:00
---> Package D.i386 0:1.0-1cl set to be installed
---> Downloading header for C to pack into transaction set.
C-1.0-1cl.i386.rpm        100% |=========================| 1.0 kB    00:00
---> Package C.i386 0:1.0-1cl set to be installed
---> Downloading header for B to pack into transaction set.
B-1.0-1cl.i386.rpm        100% |=========================| 1.0 kB    00:00
---> Package B.i386 0:1.0-1cl set to be installed
---> Downloading header for BCD to pack into transaction set.
BCD-1.0-1cl.i386.rpm      100% |=========================| 1.0 kB    00:00
---> Package BCD.i386 0:1.0-1cl set to be installed
--> Running transaction check

Dependencies Resolved
Transaction Listing:
  Install: A.i386 0:1.0-1cl

Performing the following to resolve dependencies:
  Install: B.i386 0:1.0-1cl
  Install: BCD.i386 0:1.0-1cl
  Install: C.i386 0:1.0-1cl
  Install: D.i386 0:1.0-1cl
Is this ok [y/N]:

YUM selected all packages for installation, even though BCD alone would satisfy A's dependencies.

Let's see how APT deals with that:

[root@burma ~]% apt-get install A
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
  B BCD
The following NEW packages will be installed:
  A B BCD
0 upgraded, 3 newly installed, 0 removed and 0 not upgraded.
Need to get 0B/4055B of archives.
After unpacking 0B of additional disk space will be used.
Do you want to continue? [Y/n] n

As a coincidence, APT did a better job, and selected only B and BCD to satisfy A's dependency, which is still not right.

Now, let's see how Smart would solve the problem:

[root@burma ~]% smart install A
Updating cache...               ######################################## [100%]

Computing transaction...

Installing packages (2):
  A-1.0-1cl@i386     BCD-1.0-1cl@i386

2.7kb of package files are needed.

Confirm changes (Y/n)?

Smart correctly selected only BCD, since it's necessary anyway, and solves all dependencies.

Case 3 - APT & YUM

That's another interesting case which was tested with APT-RPM and YUM.

In this case, there's a package A version 1.0 installed in the system, and there are two versions available for upgrading: 1.5 and 2.0. Version 1.5 may be installed without problems, but version 2.0 has a dependency on B, which is not available anywhere.

In this case, the best possibility is upgrading to 1.5, since upgrading to 2.0 is not an option.

Let's see how APT reacts to this situation:

[root@burma ~]% apt-get upgrade A
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages have been kept back
  A
0 upgraded, 0 newly installed, 0 removed and 1 not upgraded.

APT seems to refuse to upgrade A, even though version 1.5 might be installed without problems.

What happens when forcing APT to install A:

[root@burma ~]% apt-get install A
Reading Package Lists... Done
Building Dependency Tree... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.

Since you only requested a single operation it is extremely likely that
the package is simply not installable and a bug report against
that package should be filed.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  A: Depends: B but it is not installable
E: Broken packages

It really refuses to install the newest version, and doesn't consider the possibility of using version 1.5.

Now, let's see how YUM would handle it.

Update:This test case was showing the wrong results for YUM, since it was using a cached version of the package header that didn't present the missing dependency. I apologise for showing invalid results.
[root@burma ~]% yum update
Setting up Update Process
Setting up Repo:  localpub
repomd.xml                100% |=========================|  951 B    00:00
Reading repository metadata in from local files
primary.xml.gz            100% |=========================|  809 B    00:00
MD Read   : ################################################## 3/3
localpub  : ################################################## 3/3
Resolving Dependencies
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for A to pack into transaction set.
A-2.0-1cl.i386.rpm        100% |=========================| 1.3 kB    00:00
---> Package A.i386 0:2.0-1cl set to be updated
--> Running transaction check
--> Processing Dependency: B for package: A
--> Finished Dependency Resolution
Error: missing dep: B for pkg A

Just like APT, YUM selected version 2.0 and didn't consider the availability of an intermediate version.

Now, let's see how Smart would behave in the same situation:

[root@burma ~]% smart upgrade
Loading cache...
Updating cache...               ######################################## [100%]

Computing transaction...

Upgrading packages (1):
  A-1.5-1cl@i386

1.3kb of package files are needed.

Confirm changes (Y/n)?

Smart correctly selects the intermediate version 1.5, which is the only viable possibility given the current options.

Case 4 - APT

This case presents the following situation: there's a package A, installed in the system, which depends on libfoo, currently being provided by B 1.0. What happens if B is upgraded to version 2.0, but libfoo is moved to be provided by package C?

The expected behavior would be to upgrade B to version 2.0, and install C to satisfy A's dependency.

That's not what happens with APT:

[root@burma ~]% apt-get dist-upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
Calculating Upgrade... Done
The following packages will be upgraded
  B
The following packages will be REMOVED:
  A
1 upgraded, 0 newly installed, 1 removed and 0 not upgraded.
Need to get 0B/1321B of archives.
After unpacking 0B of additional disk space will be used.
Do you want to continue? [Y/n]

Let's see Smart in the same situation:

[root@burma ~]% smart upgrade
Loading cache...
Updating cache...               ######################################## [100%]

Computing transaction...

Upgrading packages (1):
  B-2.0-1cl@i386

Installing packages (1):
  C-2.0-1cl@i386

2.6kB of package files are needed.

Confirm changes (Y/n)?

Smart correctly selected package C for installation as a viable possibility of leaving A installed in the system while upgrading B.

Credits

This is the credit section, where people and institutions that have somehow contributed to the project are mentioned.

Conectiva, Inc.:
 Funded the creation of Smart, and its development up to August of 2005.
Canonical Ltd:Is funding Smart development since September of 2005.
Wanderlei Cavassin:
 Conectiva's research & development coordinator, who believed the project was viable and encouraged the author to work on it.
Ednilson Miura & Herton Ronaldo Krzesinski:
 Conectiva employees, helped setting up many distributions for tests whenever necessary.
Andreas Hasenack:
 Conectiva employee, helped as being the first brave pre-alpha tester, and contributed with many ideas, discussions, etc.
Arnaldo Carvalho de Melo:
 Conectiva board member, helped with the "channel of mirrors" idea and by encouraging the author to build a generic channel information method.
Others @ Conectiva:
 Many other people in Conectiva helped with ideas and alpha-testing in general during the pre-release period of Smart development.
Guilerme Manika & Ruda Moura:
 Ancient Conectiva employees, now board members of the Haxent company, helped by testing Smart extensively in Fedora, reporting many bugs and suggesting changes. They have also created the Smart FAQ.
APT-RPM & Debian:
 Experience on packaging and ideas for a better framework were developed while the author of Smart worked as the APT-RPM maintainer.
Jeff Johnson:Contributed as being the RPM maintainer itself, and in many discussions regarding packaging theory in general.
Seth Vidal:YUM author, and member of the Duke University, contributed to Smart with the development of the XML MetaData repository format and discussions about it.
Michael Vogt:Currently the maintainer of the Synaptic, used to co-maintain it with the author of Smart. Many of his ideas ended up being adopted in Smart as a consequence.
Sebastian Heinlein:
 Author of the package icons for Synaptic, that were mercilessly stolen to be used in Smart's graphic interface.
TaQ/PiterPunk at #slackware-br:
 These guys helped Smart development by explaining details of Slackware practices regarding packaging.
Matt Zimmerman:Debian/Ubuntu developer and co-maintainer of the APT software, helped by shining some light regarding details of the DPKG pre-depends ordering expectations.
Mauricio Teixeira:
 FAQ maintenance, YaST2 channel maintainer, "tracker cleaner", general suggestions and code contributions.
Jonathan Rocker:
 Documentation help.
smart-1.4.orig/HACKING0000644000000000000000000000144511545144020011320 0ustar Code Conventions ---------------- - Classes must be new-style, and named LikeThis. - Functions and methods are named likeThis(). - Variables and attributes are named likethis. - Private and protected attributes are named _likethis. - Private methods where name clashing with subclasses is probable (e.g. Progress) are named __likethis. - Identation is 4 expanded spaces. - Lines must have at most 79 columns. - Follow PEP-8 whenever it doesn't conflict with the statements above. - Space comparisons >= like == this, but parameters like=this. - Methods/function calls have parameters(spaced, like, this), even if they((have, additional, parenthesis)). Testing ------- - For every change, try to create a new test. - Run all tests: 'make test'. - Run specific test: 'TEST=tests/test.txt make test' smart-1.4.orig/contrib/0000755000000000000000000000000011571172604011775 5ustar smart-1.4.orig/contrib/rpmhelper/0000755000000000000000000000000011571172604013773 5ustar smart-1.4.orig/contrib/rpmhelper/rpmhelper.c0000644000000000000000000000357311545144020016135 0ustar #include #include #include #define _RPMTS_INTERNAL #include #include typedef struct rpmtsObject_s { PyObject_HEAD PyObject *md_dict; rpmts ts; /* Other unneeded fields */ } rpmtsObject; PyObject *rpmmi_Wrap(rpmdbMatchIterator mi); long tagNumFromPyObject(PyObject *item); static PyObject * dbMatch(PyObject *self, PyObject *args, PyObject *kwds) { rpmtsObject *s; PyObject *TagN = NULL; PyObject *Key = NULL; char *key = NULL; unsigned int ikey; int len = 0; int tag = RPMDBI_PACKAGES; char * kwlist[] = {"ts", "tagNumber", "key", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:Match", kwlist, &s, &TagN, &Key)) return NULL; if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) { PyErr_SetString(PyExc_TypeError, "unknown tag type"); return NULL; } if (Key) { if (PyString_Check(Key)) { key = PyString_AsString(Key); len = PyString_Size(Key); } else if (PyInt_Check(Key)) { ikey = PyInt_AsLong(Key); key = (char *)&ikey; len = sizeof(ikey); } else { PyErr_SetString(PyExc_TypeError, "unknown key type"); return NULL; } } if (s->ts->rdb == NULL) { int rc = rpmtsOpenDB(s->ts, O_RDONLY); if (rc || s->ts->rdb == NULL) { PyErr_SetString(PyExc_TypeError, "rpmdb open failed"); return NULL; } } return rpmmi_Wrap(rpmtsInitIterator(s->ts, tag, key, len)); } static PyMethodDef rpmhelper_methods[] = { {"dbMatch", (PyCFunction)dbMatch, METH_VARARGS|METH_KEYWORDS, NULL}, {NULL, NULL} }; DL_EXPORT(void) initrpmhelper(void) { PyObject *m; m = Py_InitModule3("rpmhelper", rpmhelper_methods, ""); } /* vim:ts=4:sw=4:et */ smart-1.4.orig/contrib/rpmhelper/setup.py0000755000000000000000000000144611545144020015505 0ustar #!/usr/bin/python from distutils.core import setup, Extension import os try: from rpm import _rpm as rpmmodule except ImportError: import rpm as rpmmodule rpmmoduledir = os.path.dirname(rpmmodule.__file__) setup(name="rpmhelper", version = "0.1", description = "", author = "Gustavo Niemeyer", author_email = "niemeyer@conectiva.com", license = "GPL", url = "http://smartpm.org", long_description = "", ext_modules = [ Extension("rpmhelper", ["rpmhelper.c"], include_dirs=["/usr/include/rpm"], runtime_library_dirs=[rpmmoduledir], extra_link_args=[rpmmodule.__file__], ) ], ) smart-1.4.orig/contrib/rpmhelper/README0000644000000000000000000000053311545144020014644 0ustar The rpmhelper Python module introduces a custom dbMatch() function which works correctly on x86_64 when using iterator offsets, just like RPM >= 4.4.1-0.18. If compiled and importable by Smart, it will be used automatically. If you have RPM >= 4.4.1-0.18, or is not on x86_64, DO NOT USE IT, because this is a hotfix, is ugly, and will die soon. smart-1.4.orig/contrib/servicemenus/0000755000000000000000000000000011571172604014505 5ustar smart-1.4.orig/contrib/servicemenus/kde_add_smart_channel.sh0000755000000000000000000000160011545144020021302 0ustar #!/bin/sh path="$1" rpmpkgs=$(ls -l $path | grep \.rpm | wc -l) debpkgs=$(ls -l $path | grep \.deb | wc -l) if [ $rpmpkgs -gt 0 ] && [ $debpkgs -gt 0 ]; then type=$(kdialog --title "Add Smart channel" --combobox "RPM and DEB files found. Which should I add?" "Both" "RPM" "DEB") if [ "$?" -ne 0 ]; then exit $?; fi elif [ $rpmpkgs -gt 0 ]; then type="RPM" else type="DEB" fi dirname=$(echo $path | awk -F'/' '{ print $(NF-1)"-"$NF }') addrpm="smart --gui channel --add rpm-dir-$dirname type=rpm-dir name=rpm-dir-$dirname path=$path -y" adddeb="smart --gui channel --add deb-dir-$dirname type=deb-dir name=deb-dir-$dirname path=$path -y" case $type in Both) $addrpm $adddeb ;; RPM) $addrpm ;; DEB) $adddeb ;; esac error=$? if [ "$error" -ne 0 ]; then kdialog --error "Error from Smart! ($error)" else kdialog --msgbox "Smart channel added." fi smart-1.4.orig/contrib/servicemenus/README0000644000000000000000000000211711545144020015356 0ustar From: Mauricio Teixeira (netmask) To: smart@labix.org Subject: Smart KDE service menu Date: Sat, 03 Dec 2005 15:37:04 -0200 Hi! Using an interesting SUSE idea of using a KDE service menu to add new repositories into YaST, I've managed to code something similar for Smart. I'm sending the necessary files attached: * add_smart_channel.desktop copy into /share/apps/konqueror/servicemenus/ (on SUSE it's /opt/kde3/share/apps/konqueror/servicemenus/) * kde_add_smart_channel.sh copy somwhere in your $PATH (don't forget to chmod 755!) After that, you can right click on a directory under Konqueror and it will: a) Detect what kind of packages you have there (either RPM or DEB) b) Ask what kind of channel to add (RPM, DEB or Both) Please, give me any feedbacks on it ok? I've not tested it too much, but who knows what can happen? :) -- % Mauricio Teixeira (netmask) % mteixeira{a}webset{d}net <> Maceio/AL/BR % TI+Telecom Analyst <> Linux Specialist % http://mteixeira.webset.net <> http://pmping.sf.net % [D0CE 6BD4 526B B7D1 6F4E 85FA A7A0 1A6F B23A A9EE] smart-1.4.orig/contrib/servicemenus/add_smart_channel.desktop0000644000000000000000000000042111545144020021513 0ustar [Desktop Entry] Name=Smart actions Type=Service X-KDE-ServiceType=inode/directory Actions=Add; [Desktop Action Add] Name=Add directory as Smart channel Name[pt_BR]=Adicionar diretório como canal do Smart Exec=kdesu --nonewdcop -- kde_add_smart_channel.sh %U Icon=smart smart-1.4.orig/contrib/bash-completion/0000755000000000000000000000000011571172604015061 5ustar smart-1.4.orig/contrib/bash-completion/README0000644000000000000000000000043711545144020015735 0ustar AUTHOR: Mauricio Teixeira (netmask) DATE: Sun November 19 FILE: smart-completion.sh WHAT: BASH command line completion for Smart. It completes options, action commands, and options from action commands. HOW: Just copy smart-completion.sh to /etc/bash_completion smart-1.4.orig/contrib/bash-completion/smart-completion.sh0000644000000000000000000000357411545144020020713 0ustar # # Copyright (c) 2005 Canonical # Copyright (c) 2004 Conectiva, Inc. # # Written by Mauricio Teixeira # # This file is part of Smart Package Manager. # # Smart Package Manager 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. # # Smart Package Manager 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 Smart Package Manager; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # _smart() { local cur prev opts smartdir=$(python -c "import smart; print smart.__file__" \ | awk '{sub("/__init__.py[c]?","");print}') commands="$(ls ${smartdir}/commands/*.py \ | awk -F '/' '{gsub(/\.py|__init__.py[c]?|\n/,""); print $NF}')" COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" if [[ ${prev} == "smart" ]] ; then # Completion for general options and action commands opts="${commands} $(grep "add_option" $(which smart) | tr \" \\n \ | grep "^-" | tr \\n " ")" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 elif [[ ! -z "$(echo $commands | grep ${COMP_WORDS[1]})" ]] ; then # Completion for action command options opts="$(grep "add_option" "${smartdir}/commands/${COMP_WORDS[1]}.py" \ | tr \" \\n | grep "^-" | tr \\n " ")" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi } complete -F _smart smart smart-1.4.orig/contrib/ksmarttray/0000755000000000000000000000000011571172604014176 5ustar smart-1.4.orig/contrib/ksmarttray/ChangeLog0000644000000000000000000000005011545144020015733 0ustar Dummy file required by KDE build admin. smart-1.4.orig/contrib/ksmarttray/ksmarttray.desktop0000644000000000000000000000026011545144020017760 0ustar [Desktop Entry] Name=KSmartTray Comment=KDE Tray widget for updating RPM files Exec=/usr/bin/ksmarttray Icon=ksmarttray Type=Application Categories=Qt;Settings;PackageManager; smart-1.4.orig/contrib/ksmarttray/INSTALL0000644000000000000000000000005011545144020015212 0ustar Dummy file required by KDE build admin. smart-1.4.orig/contrib/ksmarttray/Makefile.am0000644000000000000000000000134311545144020016223 0ustar SUBDIRS = $(TOPSUBDIRS) $(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ; $(top_srcdir)/subdirs: cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs $(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4 MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files package-messages: $(MAKE) -f admin/Makefile.common package-messages $(MAKE) -C po merge EXTRA_DIST = admin dist-hook: cd $(top_distdir) && perl admin/am_edit -padmin cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs smart-1.4.orig/contrib/ksmarttray/COPYING0000644000000000000000000000005011545144020015214 0ustar Dummy file required by KDE build admin. smart-1.4.orig/contrib/ksmarttray/LICENSE0000644000000000000000000004313111545144020015175 0ustar 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. Copyright (C) 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) year 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. , 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. smart-1.4.orig/contrib/ksmarttray/admin/0000755000000000000000000000000011571172604015266 5ustar smart-1.4.orig/contrib/ksmarttray/admin/install-sh0000755000000000000000000002533211545144020017267 0ustar #!/bin/sh # install - install a program, script, or datafile scriptversion=2005-11-07.23 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" posix_glob= posix_mkdir= # Symbolic mode for testing mkdir with directories. # It is the same as 755, but also tests that "u+" works. test_mode=u=rwx,g=rx,o=rx,u+wx # Desired mode of installed file. mode=0755 # Desired mode of newly created intermediate directories. # It is empty if not known yet. intermediate_mode= chmodcmd=$chmodprog chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) mode=$2 shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi test -n "$dir_arg" || trap '(exit $?); exit' 1 2 13 15 for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') posix_mkdir=false if $mkdirprog -m $test_mode -p -- / >/dev/null 2>&1; then posix_mkdir=true else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./-m "$test_mode" ./-p ./-- 2>/dev/null fi ;; esac if $posix_mkdir && { # With -d, create the new directory with the user-specified mode. # Otherwise, create it using the same intermediate mode that # mkdir -p would use when creating intermediate directories. # POSIX says that this mode is "$(umask -S),u+wx", so use that # if umask -S works. if test -n "$dir_arg"; then mkdir_mode=$mode else case $intermediate_mode in '') if umask_S=`(umask -S) 2>/dev/null`; then intermediate_mode=$umask_S,u+wx else intermediate_mode=$test_mode fi ;; esac mkdir_mode=$intermediate_mode fi $mkdirprog -m "$mkdir_mode" -p -- "$dstdir" } then : else # mkdir does not conform to POSIX, or it failed possibly due to # a race condition. Create the directory the slow way, step by # step, checking for races as we go. case $dstdir in /*) pathcomp=/ ;; -*) pathcomp=./ ;; *) pathcomp= ;; esac case $posix_glob in '') if (set -f) 2>/dev/null; then posix_glob=true else posix_glob=false fi ;; esac oIFS=$IFS IFS=/ $posix_glob && set -f set fnord $dstdir shift $posix_glob && set +f IFS=$oIFS for d do test "x$d" = x && continue pathcomp=$pathcomp$d if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # Don't fail if two instances are running concurrently. test -d "$pathcomp" || exit 1 fi pathcomp=$pathcomp/ done obsolete_mkdir_used=true fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dst"; then $doit $rmcmd -f "$dst" 2>/dev/null \ || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } } || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: smart-1.4.orig/contrib/ksmarttray/admin/mkinstalldirs0000755000000000000000000000662211545144020020072 0ustar #! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2005-06-29.22 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode= usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit $? ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit $? ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do case $file in /*) pathcomp=/ ;; *) pathcomp= ;; esac oIFS=$IFS IFS=/ set fnord $file shift IFS=$oIFS for d do test "x$d" = x && continue pathcomp=$pathcomp$d case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr= chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp=$pathcomp/ done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: smart-1.4.orig/contrib/ksmarttray/admin/doxygen.sh0000644000000000000000000005435011545144020017276 0ustar #! /bin/sh # # doxygen.sh Copyright (C) 2005 by Adriaan de Groot # Based on some code from Doxyfile.am, among other things. # License: GPL version 2. # See file COPYING in kdelibs for details. echo "*** doxygen.sh" # Recurse handling is a little complicated, since normally # subdir (given on the command-line) processing doesn't recurse # but you can force it to do so. recurse=1 recurse_given=NO use_modulename=1 cleanup=YES while test -n "$1" ; do case "x$1" in "x--no-cleanup" ) cleanup=NO ;; "x--no-recurse" ) recurse=0 recurse_given=YES ;; "x--recurse" ) recurse=1 recurse_given=YES ;; "x--no-modulename" ) use_modulename=0 ;; "x--modulename" ) use_modulename=1 ;; "x--help" ) echo "doxygen.sh usage:" echo "doxygen.sh [--no-recurse] [--no-modulename] []" exit 2 ;; x--doxdatadir=* ) DOXDATA=`echo $1 | sed -e 's+--doxdatadir=++'` ;; x--installdir=*) PREFIX=`echo $1 | sed -e 's+--installdir=++'` ;; x--* ) echo "Unknown option: $1" exit 1 ;; * ) top_srcdir="$1" break ;; esac shift done ### Sanity check the mandatory "top srcdir" argument. if test -z "$top_srcdir" ; then echo "Usage: doxygen.sh " exit 1 fi if test ! -d "$top_srcdir" ; then echo "top_srcdir ($top_srcdir) is not a directory." exit 1 fi ### Normalize top_srcdir so it is an absolute path. if expr "x$top_srcdir" : "x/" > /dev/null ; then # top_srcdir is absolute already : else top_srcdir=`cd "$top_srcdir" 2> /dev/null && pwd` if test ! -d "$top_srcdir" ; then echo "top_srcdir ($top_srcdir) is not a directory." exit 1 fi fi ### Sanity check and guess QTDOCDIR. if test -z "$QTDOCDIR" ; then if test -z "$QTDIR" ; then for i in /usr/X11R6/share/doc/qt/html do QTDOCDIR="$i" test -d "$QTDOCDIR" && break done else for i in share/doc/qt/html doc/html do QTDOCDIR="$QTDIR/$i" test -d "$QTDOCDIR" && break done fi fi if test -z "$QTDOCDIR" || test ! -d "$QTDOCDIR" ; then if test -z "$QTDOCDIR" ; then echo "* QTDOCDIR could not be guessed." else echo "* QTDOCDIR does not name a directory." fi if test -z "$QTDOCTAG" ; then echo "* QTDOCDIR set to \"\"" QTDOCDIR="" else echo "* But I'll use $QTDOCDIR anyway because of QTDOCTAG." fi fi ### Get the "top srcdir", also its name, and handle the case that subdir "." ### is given (which would be top_srcdir then, so it's equal to none-given ### but no recursion either). ### # top_srcdir="$1" # Already set by options processing module_name=`basename "$top_srcdir"` subdir="$2" if test "x." = "x$subdir" ; then subdir="" if test "x$recurse_given" = "xNO" ; then recurse=0 fi fi if test "x" != "x$subdir" ; then # If no recurse option given explicitly, default to # no recurse when processing subdirs given on the command-line. if test "x$recurse_given" = "xNO" ; then recurse=0 fi fi if test -z "$DOXDATA" || test ! -d "$DOXDATA" ; then if test -n "$DOXDATA" ; then echo "* \$DOXDATA is '$DOXDATA' which does not name a directory" fi DOXDATA="$top_srcdir/doc/common" fi if test ! -d "$DOXDATA" ; then echo "* \$DOXDATA does not name a directory ( or is unset ), tried \"$DOXDATA\"" exit 1 fi if test -n "$PREFIX" && test ! -d "$PREFIX" ; then echo "* \$PREFIX does not name a directory, tried \"$PREFIX\"" echo "* \$PREFIX is disabled." PREFIX="" fi ### We need some values from top-level files, which ### are not preserved between invocations of this ### script, so factor it out for easy use. create_doxyfile_in() { eval `grep 'VERSION="' "$top_srcdir/admin/cvs.sh"` echo "PROJECT_NUMBER = $VERSION" > Doxyfile.in grep '^KDE_INIT_DOXYGEN' "$top_srcdir/configure.in.in" | \ sed -e 's+[^[]*\[\([^]]*\)+PROJECT_NAME = "\1"+' \ -e 's+].*++' >> Doxyfile.in } apidoxdir="$module_name"-apidocs test "x$use_modulename" = "x0" && apidoxdir="apidocs" ### If we're making the top subdir, create the structure ### for the apidox and initialize it. Otherwise, just use the ### structure assumed to be there. if test -z "$subdir" ; then if test ! -d "$apidoxdir" ; then mkdir "$apidoxdir" > /dev/null 2>&1 fi cd "$apidoxdir" > /dev/null 2>&1 || { echo "Cannot create and cd into $apidoxdir" exit 1 } test -f "Doxyfile.in" || create_doxyfile_in # Copy in logos and the like for i in "favicon.ico" "kde_gear_64.png" do cp "$DOXDATA/$i" . > /dev/null 2> /dev/null done for i in "$top_srcdir/doc/api/Dox-"*.png do T=`basename "$i" | sed -e 's+Dox-++'` test -f "$i" && cp "$i" "./$T" > /dev/null 2> /dev/null done top_builddir="." srcdir="$1" subdir="." else cd "$apidoxdir" > /dev/null 2>&1 || { echo "Cannot cd into $apidoxdir -- maybe you need to" echo "build the top-level dox first." exit 1 } if test "x1" = "x$recurse" ; then # OK, so --recurse was requested if test ! -f "subdirs.top" ; then echo "* No subdirs.top available in the $apidoxdir." echo "* The --recurse option will be ignored." recurse=0 fi fi fi ### Read a single line (TODO: support \ continuations) from the Makefile.am. ### Used to extract variable assignments from it. extract_line() { file="$2" ; test -z "$file" && file="$srcdir/Makefile.am" pattern=`echo "$1" | tr + .` grep "^$1" "$file" | \ sed -e "s+$pattern.*=\s*++" } ### Handle the COMPILE_{FIRST,LAST,BEFORE,AFTER} part of Makefile.am ### in the toplevel. Copied from admin/cvs.sh. Licence presumed LGPL). create_subdirs() { echo "* Sorting top-level subdirs" dirs= idirs= if test -f "$top_srcdir/inst-apps"; then idirs=`cat "$top_srcdir/"inst-apps` else idirs=`cd "$top_srcdir" && ls -1 | sort` fi compilefirst="" compilelast="" if test -f "$top_srcdir/"Makefile.am.in ; then compilefirst=`sed -ne 's#^COMPILE_FIRST[ ]*=[ ]*##p' "$top_srcdir/"Makefile.am.in | head -n 1` compilelast=`sed -ne 's#^COMPILE_LAST[ ]*=[ ]*##p' "$top_srcdir/"Makefile.am.in | head -n 1` fi for i in $idirs; do if test -f "$top_srcdir/$i"/Makefile.am; then case " $compilefirst $compilelast " in *" $i "*) ;; *) dirs="$dirs $i" esac fi done : > ./_SUBDIRS for d in $compilefirst; do echo $d >> ./_SUBDIRS done (for d in $dirs; do list="" if test -f "$top_srcdir/"Makefile.am.in ; then list=`sed -ne "s#^COMPILE_BEFORE_$d""[ ]*=[ ]*##p" "$top_srcdir/"Makefile.am.in | head -n 1` fi for s in $list; do echo $s $d done list="" if test -f "$top_srcdir/"Makefile.am.in ; then list=`sed -ne "s#^COMPILE_AFTER_$d""[ ]*=[ ]*##p" "$top_srcdir/"Makefile.am.in | head -n 1` fi for s in $list; do echo $d $s done echo $d $d done ) | tsort >> ./_SUBDIRS for d in $compilelast; do echo $d >> ./_SUBDIRS done test -r _SUBDIRS && mv _SUBDIRS subdirs.top || true } ### Add HTML header, footer, CSS tags to Doxyfile. ### Assumes $subdir is set. Argument is a string ### to stick in front of the file if needed. apidox_htmlfiles() { dox_header="$top_srcdir/doc/api/$1header.html" dox_footer="$top_srcdir/doc/api/$1footer.html" dox_css="$top_srcdir/doc/api/doxygen.css" test -f "$dox_header" || dox_header="$DOXDATA/$1header.html" test -f "$dox_footer" || dox_footer="$DOXDATA/$1footer.html" test -f "$dox_css" || dox_css="$DOXDATA/doxygen.css" echo "HTML_HEADER = $dox_header" >> "$subdir/Doxyfile" ; \ echo "HTML_FOOTER = $dox_footer" >> "$subdir/Doxyfile" ; \ echo "HTML_STYLESHEET = $dox_css" >> "$subdir/Doxyfile" } apidox_specials() { line=`extract_line DOXYGEN_PROJECTNAME "$1"` test -n "$line" && echo "PROJECT_NAME = \"$line\"" >> "$2" } apidox_local() { for i in "$top_srcdir/doc/api/Doxyfile.local" do if test -f "$i" ; then cat "$i" >> "$subdir/Doxyfile" break fi done } ### Post-process HTML files by substituting in the menu files # # In non-top directories, both and # are calculated and replaced. Top directories get an empty # if any. doxyndex() { # Special case top-level to have an empty MENU. if test "x$subdir" = "x." ; then MENU="" htmldir="." htmltop="$top_builddir" # Just ., presumably echo "* Post-processing top-level files" else MENU="
    " htmldir="$subdir/html" htmltop="$top_builddir.." # top_builddir ends with / echo "* Post-processing files in $htmldir" # Build a little PHP file that maps class names to file # names, for the quick-class-picker functionality. # (The quick-class-picker is disabled due to styling # problems in IE & FF). ( echo ",g" -e "s+_00+,+g" -e "s+_3+<+g" | tr "[A-Z]" "[a-z]"` echo " \"$classname\" => \"$htmlfile\"," done | sort ; \ echo ") ?>" ) > "$subdir/classmap.inc" # This is a list of pairs, with / separators so we can use # basename and dirname (a crude shell hack) to split them # into parts. For each, if the file part exists (as a html # file) tack it onto the MENU variable as a
  • with link. for i in "Main Page/index" \ "Modules/modules" \ "Namespace List/namespaces" \ "Class Hierarchy/hierarchy" \ "Alphabetical List/classes" \ "Class List/annotated" \ "File List/files" \ "Directories/dirs" \ "Namespace Members/namespacemembers" \ "Class Members/functions" \ "Related Pages/pages" do NAME=`dirname "$i"` FILE=`basename "$i"` test -f "$htmldir/$FILE.html" && MENU="$MENU
  • $NAME
  • " done MENU="$MENU
" fi # Get the list of global Menu entries. GMENU=`cat subdirs | tr -d '\n'` PMENU=`grep '++' | awk '{ c=split($0,a,"/"); for (j=1; j<=c; j++) { printf " / %s\n" , a[j]; } }' | tr -d '\n'` # Map the PHP file into HTML options so that # it can be substituted in for the quick-class-picker. CMENU="" # For now, leave the CMENU disabled CMENUBEGIN="" if test "x$subdir" = "x." ; then # Disable CMENU on toplevel anyway CMENUBEGIN="" else test -f "$subdir/classmap.inc" && \ CMENU=`grep '=>' "$subdir/classmap.inc" | sed -e 's+"\([^"]*\)" => "'"$subdir/html/"'\([^"]*\)"+