commit 26c15dd62ff6ed506531576eecfb9b9801510b5c Author: freesource Date: Sat Jan 27 00:03:46 2001 +0000 *** empty log message *** diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40caffa --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# CVS default ignores begin +tags +TAGS +.make.state +.nse_depinfo +*~ +#* +.#* +,* +_$* +*$ +*.old +*.bak +*.BAK +*.orig +*.rej +.del-* +*.a +*.olb +*.o +*.obj +*.so +*.exe +*.Z +*.elc +*.ln +core +# CVS default ignores end diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..ec3e9aa --- /dev/null +++ b/BUGS @@ -0,0 +1,8 @@ +* Permissions of some directories are weird using mkdir(). +* ftp()/qftp() doesn't handle timeout problems very well, if alarm() + and SIG{ALRM} are used program quits with stdout "Alarm Bell". +* Debian md5sum program has different output than non-Debian md5sum + programs, will probably switch to MD5 module. +* --ftp, swimz.list, for non-US using the dists/arch/ notation doesn't + work on all sites, normal notation works if the site is set-up + this way. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..eeb586b --- /dev/null +++ b/COPYING @@ -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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/Conf.pm b/Conf.pm new file mode 100644 index 0000000..657da30 --- /dev/null +++ b/Conf.pm @@ -0,0 +1,672 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Conf; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); + +@EXPORT = qw($my_number $tmp $architecture $distribution @user_defined_section + $default_directory $default_root_directory $permission $dpkg + $dpkg_deb $ar $gcc $apt_get $apt_cache $sources @FTP $spl $cat + $sort $md5sum $zcat $tar $grep $gzip $fastswim $slowswim $longswim + $mount $umount $mke2fs $copy $pager $base $pwd $parent $library + $splt $mv $imswim $swim_conf $debug $port $timeout + $firewall $passive $apt_sources $HISTORY $alt); +%EXPORT_TAGS = ( + Path => [ qw($tmp $parent $base $library) ], + Deb => [ qw($pwd $dpkg_deb $ar $tar $grep $tmp $md5sum $cat $mv) ], + Qftp => [ qw($default_root_directory $permission @FTP + $default_directory $swim_conf) ], + Info => [ qw($parent $base $zcat) ] + ); + + + +############################# +# DEFAULT PROGRAM VARIABLES # +############################# + +# You can change this to how many lines you would like "swim -qf <>" to +# print out, before asking for -t or --total, it will automatically ask +# though, if there is more than one package and you used the option -i. +# Remember -t can be used with --scripts family members to view the +# title of the script file regardless of this setting, and if -t has to be +# used, the titles will be displayed, which makes sense. +$my_number = 23; + +# Just like a shell, you can keep a history of whatever length you want. +$HISTORY = 10; + +# For not-installed: +# This part supplies the default value for --arch. +# +# You can determine the default architecture used when -n is +# called or a not-installed database is made. Architectures are always +# being added so check with Debian to find a list. There is alpha, arm, +# hurd (alternative kernel to linux), i386, m68k, powerpc, sparc. Just use +# the arch found after the hyphen in the Contents-(arch) file. +$architecture = "i386"; + +# For not-installed: +# This part supplies the default value for --dists. +# +# The default distribution can be either stable, unstable, frozen, or +# experimental (rare). These represent the state of development that the +# packages are under. The unstable distribution can have lot's of changes +# within a very short time period, and frozen may or may not be available. +$distribution = "unstable"; + + +#For not-installed: +#This part supplies the default value for --main, --contrib, --non-free, +#and --non-us. + +# Distributions are divided into the sections. These sections are called +# distributions in the version 2.4.1.0 packaging manual, because they were at +# one time separate distributions, but this has since changed. You can +# determine which of these sections (main, non-free, contrib or non-US) to +# pull out of the Contents file if you don't want to use --main, --contrib, +# --non-free, and --non-us to selectively pick sections. Basically, whatever +# you pull out should match the Package(s) file(s) you are targetting, this +# program is friendly if you make a mistake, but it's more effecient to pull +# out just what you want. If the same package happens to exist in two +# different sections, main and non-us for example (which is really a +# situation that shouldn't exist, yet it does), you will still be able to +# find this package in the non-us group, but its section and locations will be +# the one which main recognizes assuming that you use the order in the example +# below. + +# Setting it up: +# Example: You just want to pull out main and contrib every time you run +# --initndb, --rebuildndb, or --ndb. +# @user_defined_section = qw(main contrib non-US); +# remember "non-US" not "non-us". + +# untill non-US is fixed the second is better +#@user_defined_section = qw(main contrib non-free non-US); +@user_defined_section = qw(main contrib non-free); + +# Usually, this is +$alt = "debian"; + +################ +# DF LOCATION # +################ + +# A little philosophy: +# swim was developed for maximum versatility, so whether you are just +# interested in researching, and keeping tabs on the newest packages, +# or maintaining a Debian virtual distribution on a non-Debian real +# distribution, or you are a using swim for distribution development, swim +# provides a way. The default directory (DF - which can also mean +# directory/file) keeps track of Contents and Packages files downloaded +# using --ftp, and gives the files names specific to the distribution and +# architectures they represent. But, you also have the freedom not to use +# the default directory in this case swim will still do the renaming and +# keeping track of the mtime, but you will have to remember where you put +# the files. On the other hand, if you use apt, you won't even have to use +# the DF directory for Packages files because you can get the ones specific +# to your own systems architecture from apt, but if you want to look at +# other architectures you will need to use the DF directory or one of your +# own choice. +# Naming Convention: Contents = Contents-dist.gz +# Packages = Packages-arch-dist-section.gz +$default_directory = '/root/.swim'; + + +# The default root directory is the key to easy management of packages +# downloaded through --ftp and --file, and provides an easy way to put together +# a personalized distribution. Future implementations of swim will provide +# a distribution called personal..Packages and Contents files specific to +# this distribution will automatically be made. This directory can be a +# real ftp site on your computer, or put where ever else you are allowed +# to have directories. dists/distribution/section/architecture/subject will be +# placed above this directory. No matter what, debian must be the final +# directory before dists. Other distributions are placed alongside debian, +# like debian-non-US or personal. +# Feel free to change the permissions. This directory is above your default_ +# directory. +$default_root_directory = '/pub/debian'; + +# Because you may be using a real ftp site, this configuration allows you +# to determine what permissions swim will set for directories it creates +# above the default root directory. +$permission = '0755'; + + +############### +# AR or DPKG? # +############### + +# NOTE: users set these next two with the $package_tool variable. + +# packaging friends dpkg and dpkg-deb come from the essential and +# required dpkg package. ar from the package binutils can also be used (below). +# This is the archival program used for deb packages, but binutils is just +# a standard non-essential package, and the ar capabilities are built into +# dpkg-deb, and it's better not to assume that the standard packages are +# even established, yet. +$dpkg = (); +$dpkg_deb = (); + + +# If you don't have the dpkg package on your system then you can use ar +# from the package binutils. This would be a standard, but not an essential +# package in Debian, but this package is also fairly standard amongst all +# distributions, and can even be found in the free djgpp for M$ Oses. +# Since people who have both dpkg and ar may want to try the ar method, +# rather than creating an automatic check, just assign a value to either +# ($dpkg & $dpkg_deb) or just $ar. +#my $ar = '/usr/bin/ar'; # same for RH +$ar = '/usr/bin/ar'; + + +####### +# APT # +####### + +# NOTE: users set apt-get and apt-cache with the $apt variable + +# If you have apt you are in luck. +$apt_get = (); +$apt_cache = (); +$sources = '/etc/apt/sources.list'; +$apt_sources = '/var/state/apt/lists'; + +######### +# PAGER # +######### + +# less is a nice pager, unless you like more! There is an option +# --nopager or -n. Pager is used for --help and swim called without any +# options. more comes from the required package util-linux, whereas +# less comes from a standard package called less. In the future there is +# a possiblity that a large percentage of swim may use an internal pager. +# less, more, or most or... +#$ENV{PAGER} = "/usr/bin/less"; # same RH +$ENV{PAGER} = "less"; +$pager = $ENV{PAGER}; + + + +################# +# SWIM PROGRAMS # +################# + +# This is replaced by the Makefile. +$pre="/usr"; + +# This is the hash making program fastswim. +$fastswim = "$pre/lib/SWIM/fastswim"; + +# imswim in an alternative to fastswim for --lowmem +$imswim = "$pre/lib/SWIM/imswim"; + +# This is the low memory program slowswim. +$slowswim = "$pre/lib/SWIM/slowswim"; + +# This is the dir/file making program longswim. +$longswim = "$pre/lib/SWIM/longswim"; + +############ +# TEMP DIR # +############ + +# If you want to set an alternative directory for the temporary files +# created when the databases are made, change here. You may want to make +# $tmp a RAM disk. See package loadlin for initrd documentation and an +# explanation for making such a disk. There is also +# /usr/src/kernel-source.version/Documentation. Whether this will speed +# things up is a subject of experimentation. +$tmp = '/tmp'; + +################## +# MAIN CONFFILES # +################## + +# if configuration files are not kept in /etc change this +# and set up the directories by hand. + +$swim_conf = '/etc/swim'; + + +############# +# UTILITIES # +############# + + +# This probably never will have to be changed. +$pwd = `pwd`; +chomp $pwd; + +# If the command split is somewhere else besides /usr/bin change this. +# The required package textutils provides this. +#my $splt = '/usr/bin/split'; # same RH +$splt = 'split'; + +# cat comes from the essential and required package textutils. +#my $cat = '/bin/cat'; # same RH +$cat = 'cat'; + +# This command also omes from the required and essential package textutils. +#my $sort = '/usr/bin/sort'; # same RH +$sort = 'sort'; + +# This program uses md5sum from the dpkg package, it can also use md5sum +# from the RH package. +#my $md5sum = '/usr/bin/md5sum'; # same RH +$md5sum = 'md5sum'; + +# If you want to view compressed files make sure this is correct. +# The required package gzip provides this. +#my $zcat = '/bin/zcat'; # same RH +$zcat = 'zcat'; + +# tar comes from the essential and required package tar. +#my $tar = '/bin/tar'; # same RH +$tar = 'tar'; + +# grep comes from the essential and required package grep. This seems +# to require a path. +$grep = '/bin/grep'; # same RH + +# gzip comes from the essential and required package gzip. +#my $gzip = "/bin/gzip"; # same RH +$gzip = "gzip"; + +# mount comes from the essential and required package mount. +#my $mount = '/bin/mount'; # same RH +#my $umount = '/bin/umount'; # same RH +$mount = 'mount'; +$umount = 'umount'; + +# If your file system isn't an ext2 filesystem, you may want to change +# this. mke2fs comes from the essential and required package e2fsprogs. +#my $mke2fs = '/sbin/mke2fs'; # same RH +$mke2fs = 'mke2fs'; + +# cp and mv from the essential and required package fileutils +#my $copy = '/bin/cp'; # same RH +$copy = 'cp'; +$mv = 'mv'; + +# Your system definitely has gcc if you have ar. gcc is a standard package +# in debian. +$gcc = 'gcc'; + + +###### +# FTP # +####### + +# Major mode --ftp and --file automates the download of Contents and Packages +# files. Even if you have apt installed, you may still want to download Packages +# from alternative architectures, and the Contents file for your own architecture +# or other architectures. If you want virtual and/or -ld capabilities you need +# the Contents file. You specify a list of ftp or file sites using urls (like +# apt). For your system's architecture specify the type deb, for other +# architectures specify deb(hyphen)architecture (ex: deb-alpha). Regardless of +# whether or not you specify an architecture, deb implies /dist* found under the +# base directory specified by the ftp url, except in the case of experimental, +# and to a degree non-us. minor mode --ftp, and --file will use the sites in this +# configuration as well, on a fifo (first in first out) basis, so choose the +# order of sites based on which are closest, most current, as well as fast. + +# IMPORTANT: It is a BIG MISTAKE to use the distributions name (slink,po,etc) +# anywhere in the sources list, or in swim's configuration file..in fact swim +# won't work properly, not to mention the fact that someday your favorite name +# will suddenly disappear. This is because swim thinks in terms of the real +# distribution name (stable,unstable,frozen, experimental). The problem goes +# like this - slink remains slink, but goes from unstable to frozen to stable. +# At first, using the distributions alias may seem appropriate, but the +# purpose of swim is to keep tabs on the dists, and not to ignore changes in +# the states, this also makes managing swim's databases much easier and +# intuitive...more about this later. + +# Fun experiments: Swim uses the naming conventions of apt, but leaves the +# Package files compressed in the DF directory. So you can always decompress +# the databases and move them to /var/state/apt/lists. This ofcourse assumes +# that the appropriate changes to the sources.list reflecting these Packages +# (need to be the same architecture as your system) existed before you +# update. (author needs to do this experiment :*) + +$ftp1 = "deb ftp://localhost/pub/debian unstable main contrib non-free non-US"; +$ftp2 = "deb ftp://localhost/pub/debian unstable main contrib non-free"; +$ftp3 = "deb ftp://localhost/pub/debian project/experimental/"; +@FTP = ($ftp1,$ftp2,$ftp3); + +# These next variables allow some characteristics of the ftp client +# to be altered. See Net::FTP for ways of altering some of these +# variables through the environment. + +$firewall = 0; +$port = 0; +$timeout = 120; +$debug = 0; +$passive = 0; + + +######################################## +# STUFF THAT NEVER NEEDS TO BE CHANGED # +######################################## + +# You will never need to change this unless for some weird reason all the +# files under dpkg are somewhere else (including /info*) , see --dbpath as +# an alternative if you decide to access or make the databases somewhere +# else. +$base = '/var/lib/dpkg'; + +# --dbpath takes care of this so don't touch. +$parent = '/'; +$library = '/var/lib/dpkg'; + + +############################# +# LOAD CUSTOM CONFIGURATION # +############################# + + +# Here we load in the customized configuration which override the defaults +# Might as well use do, let the world learn Perl ... compare this to apt's +# configuation file with scopes. Swim's sources.list file (/etc/swim/swimz.list), +# will be grabbed at SWIM::Apt and SWIM::Qftp if it exists. + +do "$swim_conf/swimrc"; +do "$ENV{HOME}/.swim/swimrc"; +if ((defined $dpkg && !defined $dpkg_deb) || + (!defined $dpkg && defined $dpkg_deb)) { + print "swim: need to give both \$dpkg and \$dpkg_deb a value if you want dpkg\n"; + exit; +} +if (defined $package_tool) { + if ($package_tool =~ /ar/) { + $ar = $ar; + } + else { + $dpkg = 'dpkg'; + $dpkg_deb = 'dpkg-deb'; + undef $ar; + } +} +if (defined $apt) { + $apt_get = 'apt-get'; + $apt_cache = 'apt-cache'; +} + + +############################### +# MAKE ANY NEEDED DIRECTORIES # +############################### + +# make sure all the appropriate directories are made +if (!-d $default_directory) { + if (-e $default_directory) { + print "swim: can not create default directory because a file exists\n"; + exit; + } + my @DRD = split(m,/,,$default_directory); + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + -d $placement or mkdir("$placement",0755); + } +} + +if (!-d "$default_directory$default_root_directory") { + my @DRD = split(m,/,,$default_root_directory); + print "swim: debian must be the final directory before dists\n" + if $DRD[$#DRD] ne "debian"; + exit if $DRD[$#DRD] ne "debian"; + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + unless (-d "$default_directory$placement") { + mkdir("$default_directory$placement",0755) + or die "swim: could not create root default directory\n"; + } + } +} + +# Makefile will make sure these directories exist, unless for some strange +# reason you have to change them. + +if (!-d $library) { + mkdir($library,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $base) { + mkdir($base,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $swim_conf) { + mkdir($swim_conf,0666) or die "Couldn't create configuration file directory, + please make the directories which are needed.\n"; +} + +1; + +__END__ + +=head1 NAME + +swimrc - swim configuration file + +=head1 DESCRIPTION + +B is the configuartion file for swim allowing many default values +to be set so that they do not have to be mentioned on the command line. +Swimrc interacts directly with Perl allowing a wide variety of variables +found in B to be altered. + +=cut + +=head1 USAGE + +Values for variable can be altered for B by assigning different +values enclosed in quotes or quoted whitespace (qw()), and ended with a +semi-colon. + + $variable = "value"; + $variable = "qw(value1 value2 ..)"; + +=head1 VARIABLES + +This is a list of variables with explanations. The default values for +B are shown. + +=head2 OUTPUT VARIABLE + +$my_number can be changed to how many lines you would like "swim -qf <>" +to print out, before the program asks for C<-t> or C<--total>. Exception: +If C<-i> is used in the query and there is more than one package then the +total will be presented. + +Hint: C<-t> can be used with all the various C<--scripts> family members +to view the title of the script file regardless of this variable setting, +and if C<-t> has to be used, the titles will be displayed, which makes +sense. + +B<$my_number = 23;> + +=head2 HISTORY + +This is a shell-like history kept in relation to searches and the most +recent edit when C<--stdin> is used. + +B<$HISTORY = 10;> + +=head2 AR or DPKG? + +Debian packages are ar archives. If you are using a Debian Distribution +assign "dpkg" to $package_tool, otherwise assign "ar" to $package_tool. + +B<$package_tool = "/usr/bin/ar";> + +=head2 APT + +B does not assign a value for apt. To use C<--apt> and C<-xyz> +assign $apt the value "yes". + +Example: B<$apt = "yes";> + +=head2 PAGER + +less is a nice pager, unless you like more! Pager is used for C<--help> +and B called without any options. There is an option C<--nopager> or +C<-n>. more comes from the required package util-linux, whereas less +comes from a standard package called less. Values: "less", "more", or +"most" or... + +B<$ENV{PAGER} = "less";> + +=head2 NOT-INSTALLED VARIABLES + +Assign values for $architecture and/or $distribution to avoid having to +use C<--arch> and C<--dists> everytime the not-installed databases are +accessed with C<-n> or made or altered. + +Architectures are always being added so check with Debian to find a list. +There is I. Just use the arch found after the hyphen in the +Contents-(arch) file. + +B<$architecture = "i386";> + +The distribution can be either I. These represent the state of development that the packages are +under. The unstable distribution can have lot's of changes within a very +short time period, and frozen may or may not be available. + +B<$distribution = "unstable";> + +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at one time separate distributions, but this has since changed. + +You can determine which of the sections I to pull out of the Contents file if you don't want to use +C<--main>, C<--contrib>, C<--non-free>, and C<--non-us> to selectively +pick the sections. + +For efficiency, you should choose the sections which you will be pulling +out of the Packages file(s) being targetted. + +Rule: Use "non-US" not "non-us". + +B<@user_defined_section = qw(main contrib non-free non-US);> + +=head2 DF LOCATION + +A little philosophy: B was developed for maximum versatility, so +whether you are just interested in researching, and keeping tabs on the +newest packages, or maintaining a Debian virtual distribution on a +non-Debian distribution, or you are a using B for distribution +development, B provides a way. + +The next two variables determine the location of the DF (default +directory/file system) + +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release +file are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim will still do the renaming and keeping track of the mtime, but you +will have to remember where you put the files. + +B<$default_directory = '/root/.swim';> + +The default root directory (DRD) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be a real ftp site on your computer, or put wherever else you are +allowed to have directories. The DRD is always placed below the value +assigned to $default_directory. According to the previous assignment to +$default_directory, if the DRD is "/pub/a/debian" then the full path +would be "/root/.swim/pub/a/debian". + +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the DRD. + +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-US or +personal (specialized distribution). + +B<$default_root_directory = '/pub/debian';> + +Because you may be using a real ftp site, this variable allows you to +determine what permissions B will assign for directories it creates +below the DRD. + +B<$permission = '0755';> + +=head2 TEMPORARY DIRECTORY + +If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +$tmp a RAM disk. See package loadlin for initrd documentation and an +explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. + +B<$tmp = "/tmp";> + +=head2 FTP + +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in Net::FTP(3pm) by providing +arguments to these variables. All variables but $timeout are set to untrue +by default. + + $firewall = 0; (FTP firewall machine name) + $port = 0; (defaults to 23) + $timeout = 120; (120 seconds) + $debug = 0; (1 will turn on STDERR) + $passive = 0; (1 will enable) + +=head1 OTHER VARIABLES + +see SWIM::Conf + +=head1 FILES + + /etc/swim/swimrc + ~/.swim/swimrc + +=head1 SEE ALSO + +swim(8), Net::FTP(3pm) + +=head1 BUGS + +Send directly to mttrader@access.mountain.net. + +=head1 AUTHOR + +Jonathan D. Rosenbaum + +=head1 COPYRIGHT + + +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +=cut diff --git a/Conf.pm.alternative b/Conf.pm.alternative new file mode 100644 index 0000000..6f5b4ab --- /dev/null +++ b/Conf.pm.alternative @@ -0,0 +1,672 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Conf; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); + +@EXPORT = qw($my_number $tmp $architecture $distribution @user_defined_section + $default_directory $default_root_directory $permission $dpkg + $dpkg_deb $ar $gcc $apt_get $apt_cache $sources @FTP $spl $cat + $sort $md5sum $zcat $tar $grep $gzip $fastswim $slowswim $longswim + $mount $umount $mke2fs $copy $pager $base $pwd $parent $library + $splt $mv $imswim $swim_conf $debug $port $timeout + $firewall $passive $apt_sources $HISTORY $alt); +%EXPORT_TAGS = ( + Path => [ qw($tmp $parent $base $library) ], + Deb => [ qw($pwd $dpkg_deb $ar $tar $grep $tmp $md5sum $cat $mv) ], + Qftp => [ qw($default_root_directory $permission @FTP + $default_directory $swim_conf) ], + Info => [ qw($parent $base $zcat) ] + ); + + + +############################# +# DEFAULT PROGRAM VARIABLES # +############################# + +# You can change this to how many lines you would like "swim -qf <>" to +# print out, before asking for -t or --total, it will automatically ask +# though, if there is more than one package and you used the option -i. +# Remember -t can be used with --scripts family members to view the +# title of the script file regardless of this setting, and if -t has to be +# used, the titles will be displayed, which makes sense. +$my_number = 23; + +# Just like a shell, you can keep a history of whatever length you want. +$HISTORY = 10; + +# For not-installed: +# This part supplies the default value for --arch. +# +# You can determine the default architecture used when -n is +# called or a not-installed database is made. Architectures are always +# being added so check with Debian to find a list. There is alpha, arm, +# hurd (alternative kernel to linux), i386, m68k, powerpc, sparc. Just use +# the arch found after the hyphen in the Contents-(arch) file. +$architecture = "i386"; + +# For not-installed: +# This part supplies the default value for --dists. +# +# The default distribution can be either stable, unstable, frozen, or +# experimental (rare). These represent the state of development that the +# packages are under. The unstable distribution can have lot's of changes +# within a very short time period, and frozen may or may not be available. +$distribution = "unstable"; + + +#For not-installed: +#This part supplies the default value for --main, --contrib, --non-free, +#and --non-us. + +# Distributions are divided into the sections. These sections are called +# distributions in the version 2.4.1.0 packaging manual, because they were at +# one time separate distributions, but this has since changed. You can +# determine which of these sections (main, non-free, contrib or non-US) to +# pull out of the Contents file if you don't want to use --main, --contrib, +# --non-free, and --non-us to selectively pick sections. Basically, whatever +# you pull out should match the Package(s) file(s) you are targetting, this +# program is friendly if you make a mistake, but it's more effecient to pull +# out just what you want. If the same package happens to exist in two +# different sections, main and non-us for example (which is really a +# situation that shouldn't exist, yet it does), you will still be able to +# find this package in the non-us group, but its section and locations will be +# the one which main recognizes assuming that you use the order in the example +# below. + +# Setting it up: +# Example: You just want to pull out main and contrib every time you run +# --initndb, --rebuildndb, or --ndb. +# @user_defined_section = qw(main contrib non-US); +# remember "non-US" not "non-us". + +#untill non-US is fixed the second is better +#@user_defined_section = qw(main contrib non-free non-US); +@user_defined_section = qw(main contrib non-free); + +# Usually, this is +$alt = "debian"; + +################ +# DF LOCATION # +################ + +# A little philosophy: +# swim was developed for maximum versatility, so whether you are just +# interested in researching, and keeping tabs on the newest packages, +# or maintaining a Debian virtual distribution on a non-Debian real +# distribution, or you are a using swim for distribution development, swim +# provides a way. The default directory (DF - which can also mean +# directory/file) keeps track of Contents and Packages files downloaded +# using --ftp, and gives the files names specific to the distribution and +# architectures they represent. But, you also have the freedom not to use +# the default directory in this case swim will still do the renaming and +# keeping track of the mtime, but you will have to remember where you put +# the files. On the other hand, if you use apt, you won't even have to use +# the DF directory for Packages files because you can get the ones specific +# to your own systems architecture from apt, but if you want to look at +# other architectures you will need to use the DF directory or one of your +# own choice. +# Naming Convention: Contents = Contents-dist.gz +# Packages = Packages-arch-dist-section.gz +$default_directory = '/root/.swim'; + + +# The default root directory is the key to easy management of packages +# downloaded through --ftp and --file, and provides an easy way to put together +# a personalized distribution. Future implementations of swim will provide +# a distribution called personal..Packages and Contents files specific to +# this distribution will automatically be made. This directory can be a +# real ftp site on your computer, or put where ever else you are allowed +# to have directories. dists/distribution/section/architecture/subject will be +# placed above this directory. No matter what, debian must be the final +# directory before dists. Other distributions are placed alongside debian, +# like debian-non-US or personal. +# Feel free to change the permissions. This directory is above your default_ +# directory. +$default_root_directory = '/pub/debian'; + +# Because you may be using a real ftp site, this configuration allows you +# to determine what permissions swim will set for directories it creates +# above the default root directory. +$permission = '0755'; + + +############### +# AR or DPKG? # +############### + +# NOTE: users set these next two with the $package_tool variable. + +# packaging friends dpkg and dpkg-deb come from the essential and +# required dpkg package. ar from the package binutils can also be used (below). +# This is the archival program used for deb packages, but binutils is just +# a standard non-essential package, and the ar capabilities are built into +# dpkg-deb, and it's better not to assume that the standard packages are +# even established, yet. +$dpkg = (); +$dpkg_deb = (); + + +# If you don't have the dpkg package on your system then you can use ar +# from the package binutils. This would be a standard, but not an essential +# package in Debian, but this package is also fairly standard amongst all +# distributions, and can even be found in the free djgpp for M$ Oses. +# Since people who have both dpkg and ar may want to try the ar method, +# rather than creating an automatic check, just assign a value to either +# ($dpkg & $dpkg_deb) or just $ar. +#my $ar = '/usr/bin/ar'; # same for RH +$ar = '/usr/bin/ar'; + + +####### +# APT # +####### + +# NOTE: users set apt-get and apt-cache with the $apt variable + +# If you have apt you are in luck. +$apt_get = (); +$apt_cache = (); +$sources = '/etc/apt/sources.list'; +$apt_sources = '/var/state/apt/lists'; + +######### +# PAGER # +######### + +# less is a nice pager, unless you like more! There is an option +# --nopager or -n. Pager is used for --help and swim called without any +# options. more comes from the required package util-linux, whereas +# less comes from a standard package called less. In the future there is +# a possiblity that a large percentage of swim may use an internal pager. +# less, more, or most or... +#$ENV{PAGER} = "/usr/bin/less"; # same RH +$ENV{PAGER} = "less"; +$pager = $ENV{PAGER}; + + + +################# +# SWIM PROGRAMS # +################# + +# This is replaced by the Makefile. +$pre="/usr"; # AUTOREPLACE done by Makefile, do not edit. + +# This is the hash making program fastswim. +$fastswim = "$pre/lib/SWIM/bin/fastswim"; + +# imswim in an alternative to fastswim for --lowmem +$imswim = "$pre/lib/SWIM/bin/imswim"; + +# This is the low memory program slowswim. +$slowswim = "$pre/lib/SWIM/bin/slowswim"; + +# This is the dir/file making program longswim. +$longswim = "$pre/lib/SWIM/bin/longswim"; + +############ +# TEMP DIR # +############ + +# If you want to set an alternative directory for the temporary files +# created when the databases are made, change here. You may want to make +# $tmp a RAM disk. See package loadlin for initrd documentation and an +# explanation for making such a disk. There is also +# /usr/src/kernel-source.version/Documentation. Whether this will speed +# things up is a subject of experimentation. +$tmp = '/tmp'; + +################## +# MAIN CONFFILES # +################## + +# if configuration files are not kept in /etc change this +# and set up the directories by hand. + +$swim_conf = '/etc/swim'; + + +############# +# UTILITIES # +############# + + +# This probably never will have to be changed. +$pwd = `pwd`; +chomp $pwd; + +# If the command split is somewhere else besides /usr/bin change this. +# The required package textutils provides this. +#my $splt = '/usr/bin/split'; # same RH +$splt = 'split'; + +# cat comes from the essential and required package textutils. +#my $cat = '/bin/cat'; # same RH +$cat = 'cat'; + +# This command also omes from the required and essential package textutils. +#my $sort = '/usr/bin/sort'; # same RH +$sort = 'sort'; + +# This program uses md5sum from the dpkg package, it can also use md5sum +# from the RH package. +#my $md5sum = '/usr/bin/md5sum'; # same RH +$md5sum = 'md5sum'; + +# If you want to view compressed files make sure this is correct. +# The required package gzip provides this. +#my $zcat = '/bin/zcat'; # same RH +$zcat = 'zcat'; + +# tar comes from the essential and required package tar. +#my $tar = '/bin/tar'; # same RH +$tar = 'tar'; + +# grep comes from the essential and required package grep. This seems +# to require a path. +$grep = '/bin/grep'; # same RH + +# gzip comes from the essential and required package gzip. +#my $gzip = "/bin/gzip"; # same RH +$gzip = "gzip"; + +# mount comes from the essential and required package mount. +#my $mount = '/bin/mount'; # same RH +#my $umount = '/bin/umount'; # same RH +$mount = 'mount'; +$umount = 'umount'; + +# If your file system isn't an ext2 filesystem, you may want to change +# this. mke2fs comes from the essential and required package e2fsprogs. +#my $mke2fs = '/sbin/mke2fs'; # same RH +$mke2fs = 'mke2fs'; + +# cp and mv from the essential and required package fileutils +#my $copy = '/bin/cp'; # same RH +$copy = 'cp'; +$mv = 'mv'; + +# Your system definitely has gcc if you have ar. gcc is a standard package +# in debian. +$gcc = 'gcc'; + + +###### +# FTP # +####### + +# Major mode --ftp and --file automates the download of Contents and Packages +# files. Even if you have apt installed, you may still want to download Packages +# from alternative architectures, and the Contents file for your own architecture +# or other architectures. If you want virtual and/or -ld capabilities you need +# the Contents file. You specify a list of ftp or file sites using urls (like +# apt). For your system's architecture specify the type deb, for other +# architectures specify deb(hyphen)architecture (ex: deb-alpha). Regardless of +# whether or not you specify an architecture, deb implies /dist* found under the +# base directory specified by the ftp url, except in the case of experimental, +# and to a degree non-us. minor mode --ftp, and --file will use the sites in this +# configuration as well, on a fifo (first in first out) basis, so choose the +# order of sites based on which are closest, most current, as well as fast. + +# IMPORTANT: It is a BIG MISTAKE to use the distributions name (slink,po,etc) +# anywhere in the sources list, or in swim's configuration file..in fact swim +# won't work properly, not to mention the fact that someday your favorite name +# will suddenly disappear. This is because swim thinks in terms of the real +# distribution name (stable,unstable,frozen, experimental). The problem goes +# like this - slink remains slink, but goes from unstable to frozen to stable. +# At first, using the distributions alias may seem appropriate, but the +# purpose of swim is to keep tabs on the dists, and not to ignore changes in +# the states, this also makes managing swim's databases much easier and +# intuitive...more about this later. + +# Fun experiments: Swim uses the naming conventions of apt, but leaves the +# Package files compressed in the DF directory. So you can always decompress +# the databases and move them to /var/state/apt/lists. This ofcourse assumes +# that the appropriate changes to the sources.list reflecting these Packages +# (need to be the same architecture as your system) existed before you +# update. (author needs to do this experiment :*) + +$ftp1 = "deb ftp://localhost/pub/debian unstable main contrib non-free non-US"; +$ftp2 = "deb ftp://localhost/pub/debian unstable main contrib non-free"; +$ftp3 = "deb ftp://localhost/pub/debian project/experimental/"; +@FTP = ($ftp1,$ftp2,$ftp3); + +# These next variables allow some characteristics of the ftp client +# to be altered. See Net::FTP for ways of altering some of these +# variables through the environment. + +$firewall = 0; +$port = 0; +$timeout = 120; +$debug = 0; +$passive = 0; + + +######################################## +# STUFF THAT NEVER NEEDS TO BE CHANGED # +######################################## + +# You will never need to change this unless for some weird reason all the +# files under dpkg are somewhere else (including /info*) , see --dbpath as +# an alternative if you decide to access or make the databases somewhere +# else. +$base = '/var/lib/dpkg'; + +# --dbpath takes care of this so don't touch. +$parent = '/'; +$library = '/var/lib/dpkg'; + + +############################# +# LOAD CUSTOM CONFIGURATION # +############################# + + +# Here we load in the customized configuration which override the defaults +# Might as well use do, let the world learn Perl ... compare this to apt's +# configuation file with scopes. Swim's sources.list file (/etc/swim/swimz.list), +# will be grabbed at SWIM::Apt and SWIM::Qftp if it exists. + +do "$swim_conf/swimrc"; +do "$ENV{HOME}/.swim/swimrc"; +if ((defined $dpkg && !defined $dpkg_deb) || + (!defined $dpkg && defined $dpkg_deb)) { + print "swim: need to give both \$dpkg and \$dpkg_deb a value if you want dpkg\n"; + exit; +} +if (defined $package_tool) { + if ($package_tool =~ /ar/) { + $ar = $ar; + } + else { + $dpkg = 'dpkg'; + $dpkg_deb = 'dpkg-deb'; + undef $ar; + } +} +if (defined $apt) { + $apt_get = 'apt-get'; + $apt_cache = 'apt-cache'; +} + + +############################### +# MAKE ANY NEEDED DIRECTORIES # +############################### + +# make sure all the appropriate directories are made +if (!-d $default_directory) { + if (-e $default_directory) { + print "swim: can not create default directory because a file exists\n"; + exit; + } + my @DRD = split(m,/,,$default_directory); + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + -d $placement or mkdir("$placement",0755); + } +} + +if (!-d "$default_directory$default_root_directory") { + my @DRD = split(m,/,,$default_root_directory); + print "swim: debian must be the final directory before dists\n" + if $DRD[$#DRD] ne "debian"; + exit if $DRD[$#DRD] ne "debian"; + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + unless (-d "$default_directory$placement") { + mkdir("$default_directory$placement",0755) + or die "swim: could not create root default directory\n"; + } + } +} + +# Makefile will make sure these directories exist, unless for some strange +# reason you have to change them. + +if (!-d $library) { + mkdir($library,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $base) { + mkdir($base,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $swim_conf) { + mkdir($swim_conf,0666) or die "Couldn't create configuration file directory, + please make the directories which are needed.\n"; +} + +1; + +__END__ + +=head1 NAME + +swimrc - swim configuration file + +=head1 DESCRIPTION + +B is the configuartion file for swim allowing many default values +to be set so that they do not have to be mentioned on the command line. +Swimrc interacts directly with Perl allowing a wide variety of variables +found in B to be altered. + +=cut + +=head1 USAGE + +Values for variable can be altered for B by assigning different +values enclosed in quotes or quoted whitespace (qw()), and ended with a +semi-colon. + + $variable = "value"; + $variable = "qw(value1 value2 ..)"; + +=head1 VARIABLES + +This is a list of variables with explanations. The default values for +B are shown. + +=head2 OUTPUT VARIABLE + +$my_number can be changed to how many lines you would like "swim -qf <>" +to print out, before the program asks for C<-t> or C<--total>. Exception: +If C<-i> is used in the query and there is more than one package then the +total will be presented. + +Hint: C<-t> can be used with all the various C<--scripts> family members +to view the title of the script file regardless of this variable setting, +and if C<-t> has to be used, the titles will be displayed, which makes +sense. + +B<$my_number = 23;> + +=head2 HISTORY + +This is a shell-like history kept in relation to searches and the most +recent edit when C<--stdin> is used. + +B<$HISTORY = 10;> + +=head2 AR or DPKG? + +Debian packages are ar archives. If you are using a Debian Distribution +assign "dpkg" to $package_tool, otherwise assign "ar" to $package_tool. + +B<$package_tool = "/usr/bin/ar";> + +=head2 APT + +B does not assign a value for apt. To use C<--apt> and C<-xyz> +assign $apt the value "yes". + +Example: B<$apt = "yes";> + +=head2 PAGER + +less is a nice pager, unless you like more! Pager is used for C<--help> +and B called without any options. There is an option C<--nopager> or +C<-n>. more comes from the required package util-linux, whereas less +comes from a standard package called less. Values: "less", "more", or +"most" or... + +B<$ENV{PAGER} = "less";> + +=head2 NOT-INSTALLED VARIABLES + +Assign values for $architecture and/or $distribution to avoid having to +use C<--arch> and C<--dists> everytime the not-installed databases are +accessed with C<-n> or made or altered. + +Architectures are always being added so check with Debian to find a list. +There is I. Just use the arch found after the hyphen in the +Contents-(arch) file. + +B<$architecture = "i386";> + +The distribution can be either I. These represent the state of development that the packages are +under. The unstable distribution can have lot's of changes within a very +short time period, and frozen may or may not be available. + +B<$distribution = "unstable";> + +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at one time separate distributions, but this has since changed. + +You can determine which of the sections I to pull out of the Contents file if you don't want to use +C<--main>, C<--contrib>, C<--non-free>, and C<--non-us> to selectively +pick the sections. + +For efficiency, you should choose the sections which you will be pulling +out of the Packages file(s) being targetted. + +Rule: Use "non-US" not "non-us". + +B<@user_defined_section = qw(main contrib non-free non-US);> + +=head2 DF LOCATION + +A little philosophy: B was developed for maximum versatility, so +whether you are just interested in researching, and keeping tabs on the +newest packages, or maintaining a Debian virtual distribution on a +non-Debian distribution, or you are a using B for distribution +development, B provides a way. + +The next two variables determine the location of the DF (default +directory/file system) + +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release +file are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim will still do the renaming and keeping track of the mtime, but you +will have to remember where you put the files. + +B<$default_directory = '/root/.swim';> + +The default root directory (DRD) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be a real ftp site on your computer, or put wherever else you are +allowed to have directories. The DRD is always placed below the value +assigned to $default_directory. According to the previous assignment to +$default_directory, if the DRD is "/pub/a/debian" then the full path +would be "/root/.swim/pub/a/debian". + +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the DRD. + +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-US or +personal (specialized distribution). + +B<$default_root_directory = '/pub/debian';> + +Because you may be using a real ftp site, this variable allows you to +determine what permissions B will assign for directories it creates +below the DRD. + +B<$permission = '0755';> + +=head2 TEMPORARY DIRECTORY + +If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +$tmp a RAM disk. See package loadlin for initrd documentation and an +explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. + +B<$tmp = "/tmp";> + +=head2 FTP + +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in Net::FTP(3pm) by providing +arguments to these variables. All variables but $timeout are set to untrue +by default. + + $firewall = 0; (FTP firewall machine name) + $port = 0; (defaults to 23) + $timeout = 120; (120 seconds) + $debug = 0; (1 will turn on STDERR) + $passive = 0; (1 will enable) + +=head1 OTHER VARIABLES + +see SWIM::Conf + +=head1 FILES + + /etc/swim/swimrc + ~/.swim/swimrc + +=head1 SEE ALSO + +swim(8), Net::FTP(3pm) + +=head1 BUGS + +Send directly to mttrader@access.mountain.net. + +=head1 AUTHOR + +Jonathan D. Rosenbaum + +=head1 COPYRIGHT + + +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +=cut diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..ff9c50c --- /dev/null +++ b/INSTALL @@ -0,0 +1,51 @@ +To install swim, become root and type "make install". + +To install extra and important documentation, type "make installdoc". + +To remove, type "make remove". + +Pod documentation is found in Conf.pm and swim.pod if you want to make +different types of documention using pod translators. There are SGML +documents conforming to the debiandoc DTD for swimrc and swim which can be +converted using tools from the debiandoc-sgml package. + +(The modules mentioned below can be located at CPAN at www.perl.com.) + +Some distributions may require this module for ftp capabilities. + +Net::FTP from libnet-perl + +This module provides readline libraries. There are other similiar modules +which also work with Perl's Term::ReadLine(3pm). + +Term::ReadLine::Gnu from libterm-readline-gnu-perl or +Term::ReadLine::Perl from libterm-readline-perl-perl + +Also read QUICKSTART.text or QUICKSTART.html for additional information. +_________________________________________________________________ + +Alternative Installation + +The modules are put into /usr/lib/perl5/SWIM because this is in Perl's +@INC path, and does not violate Debian's Policy, on the other hand the +modules are rather specific to swim, although they definitely could be +used for other things. To put it in /usr/lib meant either using 'use lib +"/usr/lib"' or pushing the alternative directory into @INC doing a +'BEGIN{}', or setting the Environment variable PERL5LIB. The first method +slowed swim down, the second method caused a bad bug in SWIM::Deb, and the +third method involved trying to make a universe of shells happy, but this +is the best approach for an alternative @INC path. + +That's why there is Makefile.alternative. If you already did a 'make +install', now do a 'make remove'. Change the name of Makefile, and change +Makefile.alternative's name to Makefile. You can change PREFIX in this +Makefile to /usr/local if you want to. Follow the same steps as for the +original Makefile, but add one more step, set the Environment vaiable +PERL5LIB to the directory where the modules are. If the PREFIX was not +changed, and you are using a bash shell then 'export PERL5LIB=/usr/lib'. + +This alternative Makefile uses the tradition /usr/doc, /usr/man +directories whereas the other Makefile uses /usr/share/doc and +/usr/share/man, this is because of Debian's adherence to the next +generation fsstnd. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8a14493 --- /dev/null +++ b/Makefile @@ -0,0 +1,76 @@ +# Use Makefile.alternative if you want the modules in /usr or /usr/local, +# not in /usr/lib/perl5, see INSTALL. + +PREFIX=/usr + +all: + +clean: + -rm build + -rm *.bak + +install: + install -d $(DESTDIR)/var/lib/dpkg + install -d $(DESTDIR)/$(PREFIX)/sbin + cp -a swim $(DESTDIR)/$(PREFIX)/sbin/swim + install -d $(DESTDIR)/$(PREFIX)/lib/perl5/SWIM + cp -f Conf.pm $(DESTDIR)/$(PREFIX)/lib/perl5/SWIM/Conf.pm + cp -fa lib/* $(DESTDIR)/$(PREFIX)/lib/perl5/SWIM + install -d $(DESTDIR)/$(PREFIX)/lib/SWIM + cp -fa bin/* $(DESTDIR)/$(PREFIX)/lib/SWIM + install -d $(DESTDIR)/$(PREFIX)/share/man/man8 + cp -f swim.8 $(DESTDIR)/$(PREFIX)/share/man/man8 + install -d $(DESTDIR)/$(PREFIX)/share/man/man5 + cp -f swimrc.5 $(DESTDIR)/$(PREFIX)/share/man/man5 + install -d $(DESTDIR)/usr/share/doc/swim/swim.html + cp -fa swim.html/* $(DESTDIR)/usr/share/doc/swim/swim.html + install -d $(DESTDIR)/usr/share/doc/swim/swimrc.html + cp -fa swimrc.html/* $(DESTDIR)/usr/share/doc/swim/swimrc.html + cp -f QUICKSTART.html $(DESTDIR)/usr/share/doc/swim + cp -f REQUIREMENTS.html $(DESTDIR)/usr/share/doc/swim + cp -f swim_by_example.html $(DESTDIR)/usr/share/doc/swim + install -d $(DESTDIR)/usr/share/doc/swim/examples + cp -fa examples/* $(DESTDIR)/usr/share/doc/swim/examples + install -d $(DESTDIR)/etc/swim + cp -f swimz.list $(DESTDIR)/etc/swim + cp -f swimrc $(DESTDIR)/etc/swim + +installdoc: + install -d $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a QUICKSTART.text $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a REQUIREMENTS.text $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a swim_by_example.html $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a THEMES $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a TODO $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a BUGS $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a TODO $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a COPYING $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a contact_and_website $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a changelog $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a swim.text $(DESTDIR)/$(PREFIX)/share/doc/swim + cp -a swimrc.text $(DESTDIR)/$(PREFIX)/share/doc/swim + +remove: + rm $(PREFIX)/lib/perl5/SWIM/* + rmdir $(PREFIX)/lib/perl5/SWIM + rm $(PREFIX)/sbin/swim + rm /usr/share/doc/swim/swim.html/* + rmdir /usr/share/doc/swim/swim.html + rm /usr/share/doc/swim/swimrc.html/* + rmdir /usr/share/doc/swim/swimrc.html + rm /usr/share/doc/swim/examples/* + rmdir /usr/share/doc/swim/examples + rm /usr/share/doc/swim/* + rmdir /usr/share/doc/swim + rm $(PREFIX)/share/man/man5/swimrc.5 + rm $(PREFIX)/share/man/man8/swim.8 + rm $(PREFIX)/lib/SWIM/* + rmdir $(PREFIX)/lib/SWIM + +debian: + dpkg-buildpackage -tc -rfakeroot + + +dist: debian localdist stampede rpm + +.PHONY: debian diff --git a/Makefile.alternative b/Makefile.alternative new file mode 100644 index 0000000..c9a05d5 --- /dev/null +++ b/Makefile.alternative @@ -0,0 +1,73 @@ +# Set this to wherever you want swim to install. Eg, /usr/local or /usr +PREFIX=/usr + +all: + +clean: + -rm build + -rm *.bak + +install: + install -d $(DESTDIR)/var/lib/dpkg + install -d $(DESTDIR)/$(PREFIX)/sbin + cp -a swim $(DESTDIR)/$(PREFIX)/sbin/swim + install -d $(DESTDIR)/$(PREFIX)/lib/SWIM/bin + perl -pe '$$_="\$$pre=\"$(PREFIX)\";\n" \ + if /AUTOREPLACE/' Conf.pm.alternative \ + > $(DESTDIR)/$(PREFIX)/lib/SWIM/Conf.pm + chmod 644 $(DESTDIR)/$(PREFIX)/lib/SWIM/Conf.pm + cp -fa lib/* $(DESTDIR)/$(PREFIX)/lib/SWIM + cp -fa bin/* $(DESTDIR)/$(PREFIX)/lib/SWIM/bin + install -d $(DESTDIR)/$(PREFIX)/man/man8 + cp -f swim.8 $(DESTDIR)/$(PREFIX)/man/man8 + install -d $(DESTDIR)/$(PREFIX)/man/man5 + cp -f swimrc.5 $(DESTDIR)/$(PREFIX)/man/man5 + install -d $(DESTDIR)/usr/doc/swim/swim.html + cp -fa swim.html/* $(DESTDIR)/usr/doc/swim/swim.html + install -d $(DESTDIR)/usr/doc/swim/swimrc.html + cp -fa swimrc.html/* $(DESTDIR)/usr/doc/swim/swimrc.html + cp -f QUICKSTART.html $(DESTDIR)/usr/doc/swim + cp -f REQUIREMENTS.html $(DESTDIR)/usr/doc/swim + cp -f swim_by_example.html $(DESTDIR)/usr/doc/swim + install -d $(DESTDIR)/usr/doc/swim/examples + cp -fa examples/* $(DESTDIR)/usr/doc/swim/examples + install -d $(DESTDIR)/etc/swim + cp -f swimz.list $(DESTDIR)/etc/swim + cp -f swimrc $(DESTDIR)/etc/swim + +installdoc: + install -d $(DESTDIR)/$(PREFIX)/doc/swim + cp -a QUICKSTART.text $(DESTDIR)/$(PREFIX)/doc/swim + cp -a REQUIREMENTS.text $(DESTDIR)/$(PREFIX)/doc/swim + cp -a swim_by_example.html $(DESTDIR)/$(PREFIX)/doc/swim + cp -a THEMES $(DESTDIR)/$(PREFIX)/doc/swim + cp -a TODO $(DESTDIR)/$(PREFIX)/doc/swim + cp -a BUGS $(DESTDIR)/$(PREFIX)/doc/swim + cp -a TODO $(DESTDIR)/$(PREFIX)/doc/swim + cp -a COPYING $(DESTDIR)/$(PREFIX)/doc/swim + cp -a contact_and_website $(DESTDIR)/$(PREFIX)/doc/swim + cp -a changelog $(DESTDIR)/$(PREFIX)/doc/swim + cp -a swim.text $(DESTDIR)/$(PREFIX)/doc/swim + cp -a swimrc.text $(DESTDIR)/$(PREFIX)/doc/swim +remove: + rm -rf $(PREFIX)/lib/SWIM/* + rmdir $(PREFIX)/lib/SWIM + rm $(PREFIX)/sbin/swim + rm /usr/doc/swim/swim.html/* + rmdir /usr/doc/swim/swim.html + rm /usr/doc/swim/swimrc.html/* + rmdir /usr/doc/swim/swimrc.html + rm /usr/doc/swim/examples/* + rmdir /usr/doc/swim/examples + rm /usr/doc/swim/* + rmdir /usr/doc/swim + rm $(PREFIX)/man/man5/swimrc.5 + rm $(PREFIX)/man/man8/swim.8 + +debian: + dpkg-buildpackage -tc -rfakeroot + + +dist: debian localdist stampede rpm + +.PHONY: debian diff --git a/Programming_swim b/Programming_swim new file mode 100644 index 0000000..2aabfff --- /dev/null +++ b/Programming_swim @@ -0,0 +1,114 @@ +Database Structure + +note: what's below was written for readability, not to +indicate complex structures, all databases are normal hashes. stripped +implies that the control field was removed, but the data afterwards kept. + +Structure of statusindex.deb + +1). Initially made in SWIM::DB_Init::database +2). Updated in SWIM::DB::db +3). $sb(packagename) = qw(packagename_version group priority + status(separated with :)); + All fields stripped + +Structure of nstatusindex-arch-dists.deb + +1). Initally made in SWIM::NDB_Init::not_installed +2). Updated in SWIM::NDB::update_packages_ndb +3). $nsb(packagename) = qw(packagename_version group priority); + $nsb{"/."} = qw(packagename_version ...); + All fields stripped + + +Structure of packages.deb + +1). Initally made in SWIM::DB_Init::database +2). Updated in SWIM::DB::db +3). %db = [ @name => (packagename packagename_version ...), + @Tdescriptions => (packagename_version format_info ...), + @conf => (packagename_versionCONF + every_indented_line_after_Conffiles ...), + @REPLACE => (packagename_version(with PRE, DEP, REC, SUG, + CON, PRO, or REP appended) + package_relationship_field (unstripped) ...) + ] + +Structure of npackages-arch-dists.deb + +1). Initially made in SWIM::NDB_Init::not_installed +2). Updated in SWIM::NDB::update_packages_ndb +3). %ndb = [ @name => (packagename packagename_version ...), + @Tdescriptions => (packagename_version format_info ...), + @conf => (empty), + @REPLACE => (packagename_version(with PRE, DEP, REC, SUG, + CON, PRO, REP, MD, and FN appended) + package_relationship_field (unstripped) ...), + @FILENAME => (packagename_versionFN Filename_field(stripped) ...), + @MD5SUM => (packagename_versionMD + package_MD5_checksum(stripped) ...), + @revision => (packagename_versionMD(this comes from the + Filename field) "packagename_versionMD REVISION" + (this time the version comes from the Version + field) ...) + ] + +The revision field is unusual and occurs in the experimental distribution. +The hash is used by -p so that the version can be figured out. (check +"revision: situation" in SWIM::Deb). + +Structure of groupindex.deb + +1). Initally made in SWIM::DB_Init::database +2). Updated in SWIM::DB::db +3). $gb(group) = qw(packagenames ......) group stripped from Section: + +Structure of ngroupindex-arch-dists.deb + +1). Initially made in SWIM::NDB_Init::not_installed +2). Updated in SWIM::NDB::update_packages_ndb +3). $ngb = qw(packagenames ......) group stripped from Section: + +Structure of searchindex.deb and dirindex.deb + +1). When SWIM::DB_Init::database finishes SWIM::DB_Init::md begins. + This writes @dpackage to transfer.deb, which is processed by either + fastswim (filedir -> big and long) or imswim (which is like longswim, + which produces one large file - filedir.deb), and slowswim (big and + long) into the two files big.debian and long.debian and then the + databases are finished by SWIM::MD::process_md(). +2). Rebuilt by SWIM::DB::rebuildflatdb +3). searchindex.deb = /path/filename\n ...... (1 package) + dirindex.deb = /path/dir\n ...... (> 1 package) + +Structure of nsearchindex-arch-dists.deb and ndirindex-arch-dists.deb + +1). After SWIM::NDB_Init::initndb runs SWIM::NDB_Init::not_installed, + SWIM::NDB_Init::nmd runs longswim which produces + filedir.deb, then initndb runs slowswim producing big.debian and + long.debian. Then the database(s) are finished by + SWIM::MD::prcess_md. +2). +3). nsearchindex-arch-dists.deb = /path/filename\n ...... (1 package) + ndirindex-arch-dists.deb = /path/dir\n ...... (> 1 package) + Note: nsearch* includes elements which pertain to only one + package, this generally implies files, not directories, however + the ni often has more than one package sharing a file, so its + placed into ndir* (this would be rare with an i system). + SWIM::Search::search processes these two files differently, + which is more effecient for the much larger nsearch*, for this + reason you can't merge the two databases together. + +Structure of ncontentsindex-arch-dists.deb. + +1). A compressed Contents database, no alterations (originally the headers + were removed, but this is a waste of time.) If the FDB (flat database + option if given) SWIM::Library::compress_contents is called from + initndb(), otherwise longswim called from SWIM::NDB_Init::nmd + copies and compresses. The longswim method compresses, but + compress_contents does a cp (not -a). In both cases the header + removal has been depreciated. The important thing is that the utime + remains the same. +2). The new Contents database is copied (utime) and renamed via + compress_contents called from SWIM::NDB. +3). Contents format diff --git a/QUICKSTART.html b/QUICKSTART.html new file mode 100644 index 0000000..eac3184 --- /dev/null +++ b/QUICKSTART.html @@ -0,0 +1,206 @@ + +Quickstart + + +


+ +

QUICKSTART

+ +

+ +
READ THE REQUIREMENTS
+ +Now you can skip the next three steps if you have an installed Debian +distribution and you are in a hurry for a demonstration, but you will miss +out on swim's more awesome capabilities. With that said..... + +

+FIRST GET SWIMRC PREPARED + +

Edit the swimrc configution file, you should read swimrc(5), but I'll ask you some +question right now. You can find swimrc in /etc/swim, and swimrc can be +placed in your home directory in the subdirectory .swim. Entries in the +home directory swimrc override ones in /etc/swim. + +

+Are you using an installed Debian system? If so, you almost definitely +have dpkg installed. So uncomment this line in /etc/swim/swimrc by +removing the pound sign. + +

+$package_tool = "/usr/bin/dpkg"; + +

otherwise + +

+$package_tool = "/usr/bin/ar"; + +

+Do you have the apt package installed? Configure this, or -xyz will not +work. + +

+$apt = "yes"; + +

+Now you need to decide what architecture you would like to be swim's +default value when you download, build, and query the not-installed +databases. + +

+What flavor, do you want alpha, arm, hurd-i386, i386, m68k, powerpc, +or sparc? (more coming :*) I decided on ..... + +

+$architecture = "i386"; + +

+What kind of distribution do you want to be your default? stable, +unstable, frozen, or experimental (rare) I like the ever changing ... + +

+$distribution = "unstable"; + +

+Decide which sections you want? You can have this + +

+@user_defined_section = qw(main contrib non-free); + +

+or this. + +

+@user_defined_section = qw(main); + +

+or ..... + +

+SECOND GET SWIMZ.LIST PREPARED + +

Now grab a copy of the README.mirrors from +http://www.debian.org/misc/README.mirrors", +you will need this to set-up the configuration file /etc/swim/swimz.list. + +

If your using apt make sure to read swim(8) to get the nitty gritty on how you +can synchronize swim along with apt :*} using swimz.list. + +

+Humm, you found a site which has the distribution you want, and you know +which section you want, and you are happy knowing about packages which can +install on the architecture you computer happens to have. + +

+So what site is that? + +

+deb ftp://ftp.swimz.org + +

+What was the directory you happened to notice in the README.mirrors page? + +

+deb ftp://ftp.swimz.org/pub/debian + +

+What distribution did you want? Note: You won't want to use the Release +code name for the distribution, see +swimz.list. + +

+deb ftp://ftp.swimz.org/pub/debian unstable + +

+What sections did you want? + +

+deb ftp://ftp.swimz.org/pub/debian unstable main contrib +non-free + +

+Now put this line in the swimz.list, exactly like written, and ofcourse +use the values you want. + +

+THIRD GET THE DEBIAN DATABASE WITH FTP + +

+Just issue this command. + +

+swim --ftp --Contents DF --Packages DF + +

+and wait a little bit. + +

+FOURTH BUILD THE DATABASES + +

+This is for a computer system with a Debian distribution installed. + +

+swim --initdb + +

+This next part applies to people who followed all the steps to get here, +and also read the important requirements at the top. This makes the +not-installed databases. Go take a walk, or a swim :*} + +

+swim --initndb --Contents DF DF + +

+When either of these commands are complete they will say "over and +out". + +

+NOW WHAT? + +

Now the real fun begins. If you happen to have some experience with +rpm you already know some of the options which swim uses, but be prepared +for surpises. swim(8) goes into more detail, the +"Maximum +RPM" book by Edward C. Bailey which is freely available may +provide help for swim's --query option, but you will find that +swim greatly diverges from rpm. + +

Try something like this, and do not use the -n unless you +made the not-installed databases, on the other hand, REMEMBER to +use -n if you do not have an installed Debian system.... + +

+swim -n --search swim + +

+now do this.. + +

+swim -qnSi or swim -hn + +

+go to the directory /usr/bin and do + +

+swim -qnf . + +

+you probably will have to do + +

+swim -qnft . + +

+...the fun is just beginning... + +

+Where are you swimming to today? + + + diff --git a/QUICKSTART.text b/QUICKSTART.text new file mode 100644 index 0000000..68c55f9 --- /dev/null +++ b/QUICKSTART.text @@ -0,0 +1,140 @@ +READ THE REQUIREMENTS + +Now you can skip the next three steps if you have an installed Debian +distribution and you are in a hurry for a demonstration, but you will miss +out on swim's more awesome capabilities. With that said..... + +FIRST GET SWIMRC PREPARED + +Edit the swimrc configution file, you should read swimrc(5), but I'll ask +you some question right now. You can find swimrc in /etc/swim, and in +your home directory in the subdirectory .swim. Entries in the home +directory swimrc override ones in /etc/swim. + +Are you using an installed Debian system? If so, you almost definitely +have dpkg installed. So uncomment this line in /etc/swim/swimrc by +removing the pound sign. + +$package_tool = "/usr/bin/dpkg"; + +otherwise + +$package_tool = "/usr/bin/ar"; + +Do you have the apt package installed? Configure this, or -xyz will not +work. + +$apt = "yes"; + +Now you need to decide what architecture you would like to be swim's +default value when you download, build, and query the not-installed +databases. + +What flavor, do you want alpha, arm, hurd-i386, i386, m68k, powerpc, +or sparc? (more coming :*) I decided on ..... + +$architecture = "i386"; + +What kind of distribution do you want to be your default? stable, +unstable, frozen, or experimental (rare) I like the ever changing ... + +$distribution = "unstable"; + +Decide which sections you want? You can have this + +@user_defined_section = qw(main contrib non-free); + +or this. + +@user_defined_section = qw(main); + +or ..... + + +SECOND GET SWIMZ.LIST PREPARED + +Now grab a copy of the README.mirrors from +http://www.debian.org/misc/README.mirrors, you will need this to set-up +the configuration file /etc/swim/swimz.list. + +If your using apt make sure to read swim(8) to get the nitty gritty on how +you can synchronize swim along with apt :*} using swimz.list. + +Humm, you found a site which has the distribution you want, and you know +which section you want, and you are happy knowing about packages which can +install on the architecture you computer happens to have. + +So what site is that? + +deb ftp://ftp.swimz.org + +What was the directory you happened to notice in the README.mirrors page? + +deb ftp://ftp.swimz.org/pub/debian + +What distribution did you want? Note: You won't want to use the Release +code name for the distribution, see swimz.list. + +deb ftp://ftp.swimz.org/pub/debian unstable + +What sections did you want? + +deb ftp://ftp.swimz.org/pub/debian unstable main contrib non-free + +Now put this line in the swimz.list, exactly like written, and ofcourse +use the values you want. + +THIRD GET THE DEBIAN DATABASE WITH FTP + +Just issue this command. + +swim --ftp --Contents DF --Packages DF + +and wait a little bit. + + +FOURTH BUILD THE DATABASES + +This is for a computer system with a Debian distribution installed. + +swim --initdb + +This next part applies to people who followed all the steps to get here, +and also read the important requirements at the top. This makes the +not-installed databases. Go take a walk, or a swim :*} + +swim --initndb --Contents DF DF + +When either of these commands are complete they will say "over and out". + +NOW WHAT? + +Now the real fun begins. If you happen to have some experience with rpm +you already know some of the options which swim uses, but be prepared for +surpises. swim(8) goes into more detail, the "Maximum RPM" book by +Edward C. Bailey which is freely available may provide help for swim's +--query option, but you will find that swim greatly diverges from rpm. + +Try something like this, and do not use the -n unless you made the +not-installed databases, on the other hand, REMEMBER to use -n if you +do not have an installed system.... + +swim -n --search swim + +now do this.. + +swim -qnSi or swim -hn + +go to the directory /usr/bin and do + +swim -qnf . + +you probably will have to do + +swim -qnft . + +...the fun is just beginning... + +Where are you swimming to today? + + diff --git a/REQUIREMENTS.html b/REQUIREMENTS.html new file mode 100644 index 0000000..fa87fac --- /dev/null +++ b/REQUIREMENTS.html @@ -0,0 +1,139 @@ + +Requirements + + +


+ + +

REQUIRMENTS:

+ +

+Don't get intimidated, this is just to cover all bases, most computer +systems meet the requirements.

+ +PERL: Yes, preferably Perl 5.004.04 or greater. + +

FTP CAPABILITIES (optional): You may need to get Net::FTP +(Debian libnet-perl package) which depends on Data::Dumper (Debian +data-dumper package). You also need gcc if you do not have a +Debian system so that swim can figure out what architecture your +machine is. You can also find these modules at the CPAN mirrors or the PACKAGES below. + +

READLINE CAPABILITIES (optional): For nice readline +cpabilities get Term::ReadLine::Gnu +or alternatively Term::ReadLine::Perl which depends on Term::ReadKey +. Term::ReadLine::Gnu may be tricky to set-up on non Debian +systems because it depends on ncurses3.4 and the GNU Readline +Library version 2.1 or later, but Term::ReadLine::Perl is +much easier to set-up and allows a huge amount of package names to be +present on the command line without a segmentation fault. You could get +swim's ftp capabilities working first, and then just fetch the Debian +ReadLine package(s) and then use swim's --extract option to set the +package(s) up, but, it is sure fun doing a 'make test' when setting up the +ReadLine modules! You can also find these modules at the CPAN mirrors or the PACKAGES below.

+ +DATABASE CAPABILITIES: DB_File comes standard with Perl. But, +this doesn't mean it is compiled for the newer Berkeley Database +Libraries. DB 1.85 has +known +bugs which effect SWIM. SWIM can work with +1.85, but --rebuildflatdb and --rebuildflatndb will +not work properly. You can run a test to find out whether or not you need +to make the change if you have db_dump available on your system (which +db_dump). Enter this: + +

+perl -e 'use DB_File; tie %testdb,'DB_File',"testdb";';
+db_dump testdb
+ +

If 'db_dump testdb' produces an error you need to make the change by +installing the newest DB_File. If you have a version of libc6 less than +2.1, first, install a new version ( 2.3.4 or greater) of the Berkeley DB if you don't already +have it installed. If you get + + DB_File +from CPAN you will need to edit +config.in to point to the location of where libdb2 installed db.h, where +libdb2 is installed on your system, and the name of the library. For +Debian this would be: + +

INCLUDE = /usr/include/db2
+LIB = /usr/lib
+DBNAME = -ldb2
+ +

PACKAGES: You can get the CPAN modules in some package formats. +Debian 2.1 and Red Hat 5.0 have been tested with these packages: + +

+Debian
+libnet-perl +and
+data-dumper +and
+libterm-readline-gnu-perl + (plus a lot more) or
+libterm-readline-perl-perl +and
+libterm-readkey-perl
+libdb2 + (dump_db utility is now part of libc6 2.1)
+ +

+Red Hat
+perl-libnet +and
+perl-Data-Dumper
+db-? + +

+USER: root. Some of swim's most important functions will not work +properly unless you are running the program as root. + +

HARD DRIVE SPACE: Make sure you have enough hard drive space. +1500 +installed packages produces a 10MB fileindex.deb, and the virtual +not-installed filesystem database for the unstable distribution is now +over 40MB. 100MB of free space on your hard drive is probably a good +safety margin, if you run out of hard drive space the program will just +hang or quit. + +

+ +MEMORY: Databases made for an installed Debian system require +memory in proportion to the amount of packages actually installed; the +--lowmem option is an excellent alternative for making the +databases if the computer system is either overloaded or low on memory. +If you get "out of memory" warnings try to free up some memory first then +make the databases. You can also avoid making the virtual filesystem by +not using the --Contents option or using the FDB argument for +that option. Updating the databases uses very little memory. + +

OTHER SWIM FUNCTIONS: Most free operating systems have these +packages installed: On a non Debian system, ar from +binutils is used to query Debian binary packages. These next +packages are essential in a free operating system (Linux) - +textutils, fileutils, grep, tar, +gzip, and mount. + +

+ + + diff --git a/REQUIREMENTS.text b/REQUIREMENTS.text new file mode 100644 index 0000000..4877bb2 --- /dev/null +++ b/REQUIREMENTS.text @@ -0,0 +1,90 @@ +REQUIRMENTS: + +Don't get intimidated, this is just to cover all bases, most computer +systems meet the requirements. + +PERL: Yes, preferably Perl 5.004.04 or greater. + +FTP CAPABILITIES: (optional) You may need to get Net::FTP (Debian +libnet-perl package) which depends on Data::Dumper (Debian data-dumper +package). Also check the CPAN mirrors or the PACKAGES below. You also +need gcc if you do not have a Debian system so that swim can figure out +what architecture your machine is. You can also find these modules at the +CPAN mirrors or the PACKAGES below. + +READLINE CAPABILITIES: (optional) For nice readline cpabilities get +Term::ReadLine::Gnu or alternatively Term::ReadLine::Perl which depends on +Term::ReadKey. Term::ReadLine::Gnu may be tricky to set-up on non Debian +systems because it depends on ncurses3.4 and the GNU Readline Library +version 2.1 or later, but Term::ReadLine::Perl is much easier to set-up +and allows a huge amount of package names to be present on the command +line without a segmentation fault. You could get swim's ftp capabilities +working first, and then just fetch the Debian ReadLine package(s) and then +use swim's --extract option to set the package(s) up, but, it is sure fun +doing a 'make test' when setting up the ReadLine modules! You can also +find these modules at the CPAN mirrors or the PACKAGES below. + +DATABASE CAPABILITIES: DB_File comes standard with Perl. But, this +doesn't mean it is compiled for the newer Berkeley Database Libraries. DB +1.85 has known bugs which effect SWIM. SWIM can work with 1.85, but +--rebuildflatdb and --rebuildflatndb will not work properly. You can run +a test to find out whether or not you need to make the change if you have +db_dump available on your system (which db_dump). Enter this: + +perl -e 'use DB_File; tie %testdb,'DB_File',"testdb";'; +db_dump testdb + +If 'db_dump testdb' produces an error you need to make the change by +installing the newest DB_File. If you have a version of libc6 less than +2.1, first, install a new version (2.3.4 or greater) of the Berkeley DB if +you don't already have it installed. If you get DB_File from CPAN you +will need to edit config.in to point to the location of where libdb2 +installed db.h, where libdb2 is installed on your system, and the name of +the library. For Debian this would be: + +INCLUDE = /usr/include/db2 +LIB = /usr/lib +DBNAME = -ldb2 + +PACKAGES - You can get the CPAN modules in some package formats. Debian +2.1 and Red Hat 5.0 have been tested with these packages: + +Debian - + +libnet-perl and +data-dumper and +libterm-readline-gnu-perl (plus a lot more) or +libterm-readline-perl-perl and +libterm-readkey-perl +libdb2 + +Red Hat - + +perl-libnet and +perl-Data-Dumper +db-? + +USER: root. Some of swim's most important functions will not work +properly unless you are running the program as root. + +HARD DRIVE SPACE: Make sure you have enough hard drive space. 1500 +installed packages produces a 10MB fileindex.deb, and the virtual +not-installed filesystem database for the unstable distribution is now +over 40MB. 100MB of free space on your hard drive is probably a good +safety margin, if you run out of hard drive space the program will just +hang or quit. + +MEMORY: Databases made for an installed Debian system require memory in +proportion to the amount of packages actually installed; the --lowmem +option is an excellent alternative for making the databases if the +computer system is either overloaded or low on memory. If you get "out of +memory" warnings try to free up some memory first then make the databases. +You can also avoid making the virtual filesystem by not using the +--Contents option or using the FDB argument for that option. Updating the +databases uses very little memory. + +OTHER SWIM FUNCTIONS: Most free operating systems have these packages +installed: On a non Debian system, ar from binutils is used to query +Debian binary packages. These next packages are essential in a free +operating system (Linux) - textutils, fileutils, grep, tar, gzip, and +mount. diff --git a/THEMES b/THEMES new file mode 100644 index 0000000..2a2f7bc --- /dev/null +++ b/THEMES @@ -0,0 +1,34 @@ +Swim's design gives it the ability to implement features which were once +just fiction. + +Most people involved with WM (Window Managers) have heard of themes. +Themes have become very popular. You can design a real cool look for your +WM and then pass it on to other people to recreate what you have. But, +who ever thought that themes could also apply to distributions? The only +requirement to develop a theme from the Debian distributions is to create +a customized Packages database. Apt can take it from there, by simply +clearing the old cache, making a new cache from this Package, and +installing everything. This theme can even be installed along with an +existing installation because apt will figure out what needs to be done. + +Themes can easily be made using swim. Here's a list of ideas. + +* A module with the capability of taking the output from apt, and creating +a database which would correlate to a successful installation without ever +installing one package. This would essentially be a not-installed +database with one major difference, this database would represent the real +state of a successful installation. This would allow a developer to test +a hypothetical installation, and look at it's structure. Then a Packages +file could be made from this database and tested on a real installation. + +Although this module doesn't exist, yet, it could easily be made with a +special designated database interacting with the other functions offered +by swim's existing modules. + +* Swim already allows Packages files to be made from *debs placed in the +DF - including creating a place for a personalized distribution (coming). +A person can make there own real personalized distribution in this +manner, and then share their unique Packages file with the rest of the +world, allowing other people to recreate the state of your own +distribution on their machines. + diff --git a/TODO b/TODO new file mode 100644 index 0000000..07b7ec3 --- /dev/null +++ b/TODO @@ -0,0 +1,126 @@ +* Configuration for --dbpath, --root, --main, --contrib, --non-free, + --non-us, --arch, --dists could be automated so that a state could be + established on the command line, without needing to enter any of these + options again, untill a new state was desired, --default would bring + everything back to the default directory /var/lib/dpkg. + +* Non-root users could run all functions if permissions were changed, + probably this should be left up to the system administrator. + +* Add --todo --bugs to -q. + +* Looks like --source and --source_only is kind of deprecated now that apt_0.3.6 + is out, and there are Sources.gz in the appropriate places. But, now + there exists three unique ways to get sources, debget which doesn't use + databases, apt which uses databases, and swim which combines the + approaches of both apt and debget, all three ways have their advantages. + Swim isn't dependent on the existence of an up to date Sources.gz. + +* --ftp automatically removes packages with changed upstream-revisions.. + perhaps move them to a storage location. + +* base-files package has changed it's file/dir listing, eventually + SWIM::File can be modified in the future. + +* SWIM::Apt needs to be modified so that when it reads the Packages names + in the default directory it will look at the basename to take into + account non-Debian distributions. Non-Debian distributions should + be presented separately when DF is used as an argument. Probably a new + option will be added. This adheres to the swim philosophy of allowing + independent distributions with the exact directory structure of a normal + Debian distribution to exist. + +* mention netselect to help people find the best mirror site, and maybe + automatically use netselect on swimz.list to find which sites are up, + and are best to use first, overridding the default sequential order! + +* Yes, you can 'cp -a' and 'gzip -d' sources from swim to sources for + apt, then just do a swim --apt --check or vica versa. + +* Make sure this doesn't happen for proposed-updates - "swim: + dists/proposed-updates/single/binary-i386/Release does not exist on the + server", and make a note of proposed-updates in the manual, no Contents. + Incoming can be grabbed by doing something like this, "deb url + debian/Incoming" vs experimental "deb url/debian project/experimental/". + Packages are available here, too, no Release or Contents. swim is too + hardwired and this needs to be changed. + +* For now, a trade-off will be made in respect to updating the n* virtual + filesystem, even if Contents hasn't been updated, the versions of C,CR + will still be updated with the old Contents, on the other hand if + nfile* was version-less this wouldn't be necessary, then the behavior + mentioned next could be implemented anyways. If Contents are ever + updated on a more consistent basis, this behavior will be changed to + wait for these packages untill the next Contents, but basically this + should be done anyways, it will mean, quick updates during the week, and + one long one when the new Contents becomes available, the lack of + versioning would make this viable. Basically, a database will be kept + for .packagesdiff-arch-dist.deb, nfile* will remain versioned because + this means faster lookups. + +* Implement the "on the fly" distribution creation system. + +* Add the DF virtual system which will allow --apt2df and --df2apt to + work. + +* a search for everything found in -T + +* -o DPkg::Options::=--purge once --remove isn't a standard option to dpkg + for "remove", and possible --admindir (like --dbpath) --root (like + --root) and --instdir (where packages should be installed). + +* add --force-* at least for --purge and depends. + +* an option which would show all packages relationships for a package + being --ftp or -xyrz on the --stdin line + +* Complete menuindex() which allows a search of the debian menu system. + +* add the pid (personal information database) editing, and data storage. + +* Use the MD5 module from libmd5-perl for --md5sum? + +* gnupg, pgp, and md5sum checking for source probably using dscverify from + package devscripts, this uses the MD5 module + +* Need to add the capability to deal with weird non-standard Filename: .* + situations, both in retrieval, and archiving. In situations like this, + the distribution may not be apparent, but the package could still be + found and placed in a special area, and a special database could store + the information. This database could be transparent, and available for + quering regardless of the distribution default, or command line + specification. + +* Add the --file and --http capabilities or at least the capability to + look at Packages from strange directories grabbed by apt using these + methods. Meanwhile, swim's ftp capabilities make slow modems happy, and + allow for precise downloading versus downloading every package related + to -T. + +* Add a hash option so that swim can know that po -> unstable, this would + work fine, because swim shows the Release version, but the author is + against implementing this ability. + +* Instead of PWD!full_path, allow multiple filenames to be quoted without + pathnames for --extract. + +* .., ../, ../../, ../../file-or-dir (not ../../file-or-dir/) ability for + -qf|p works, but more complex ../ is not implemented, yet. ../ will + also follow a symbolic link, this is a feature. + +* --search by dirs when in place using -f. + +* Add the retro full spectrum of dpkg options, it's nice sometimes to just + do a simple install. + +* Gather together all the build children into a giant family including the + teacher and the checker. + +* Do the Perl for Non Free OSes thing. + +* Remove a large percentage of the bold and underlining from the + documentation. + +* Make needed changes and improvements to the Manual - a constant TODO. + +* swim faster and faster! diff --git a/bin/fastswim b/bin/fastswim new file mode 100755 index 0000000..bc178f5 --- /dev/null +++ b/bin/fastswim @@ -0,0 +1,167 @@ +#!/usr/bin/perl -w +#use diagnostics; +require 5.004; +use strict; + +################################################################################ +# Package administration and research tool for Debian # +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum # +# # +# 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.# +################################################################################ + + +# Because it is a better to write to disk, rather than trying to do +# everthing in memory, and then it's good to close the process which +# accomplished this. I am sure there are better ways. + +# Anyways if you want to test fastswim do something like this: +# fastswim --transfer /var/lib/dpkg/info /tmp /var/lib/dpkg and create a +# transfer.deb file beforehand in /tmp which has the packagename_version +# one to a line. + +my @ppackage; +my %repeaters; +my $thingy; +my $tingy; +my $temp; +my %HL; +my @name; +my %version; + +#$| = 1; +#$#name = 2000; +#$#ppackage = 2000; + + # This way has been de-pre-c-whatever-ated because it lacks version + # rememberance, and is just kept for testing purposes + if ($#ARGV == -1) { + print "swim: fastswim requires option/arguments, see program for instructions\n"; + exit; + chdir("$ARGV[1]"); + #consider readdir + @ppackage = <*.list>; + } + # This does the work + elsif ($ARGV[0] eq "--transfer") { + open(TRANSFER, "$ARGV[2]/transfer.deb"); + while () { + chomp $_; + if (defined $_) { + my @the = split(/_/, $_); + push(@ppackage, "$the[0].list"); + # remember the version. + chomp $the[1]; + $version{$the[0]} = $the[1]; + } + } + close(TRANSFER); + } + + + # Make a nice md. I decided on a Hash of Lists, giving all + # files/dirs unique name, and then a list of packages which + # correspond..because this should be faster than a Hash of Hash + # where you'd have to loop through all packages names..find the + # files/dir in all packages names which are the same..I'd assume a HL + # would be a quicker query, even though the Hash would be enormous. + # Possible things: a tree for faster query. + + # Put everything into an array..every other is package name + # Better check for packages which don't have /. in their *.list... + # which is rare, but does happen. Sometimes *.list(s) don't have + # all the parent directories, but we won't worry about that. + print " Making the massive hash\n"; + $| = 1; my $x = 1; + foreach $thingy (sort @ppackage) { + open(LIST, "$ARGV[1]/$thingy") or die "Humm, strange"; + # Because of the version..there are sometimes dots + $thingy =~ m,(.*)\.list,; + my $count = 0; + my @count = ; + close(LIST); + foreach (@count) { + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + chomp $_; + # does /. exist? it should be first. + if ($count == 0) { + if ($_ !~ m,\/\.,) { + my $shifter = $_; + my @redolist = @count; + push(@count,$shifter); + # humm let's rebuild the offending backup list, this + # is important for --db. + unshift(@redolist,"/."); + open(REDOLIST, ">$ARGV[1]/backup/$thingy.bk.bk") + or warn "needed to edit $thingy because it lacked /., + but could not open up a backup file\n"; + my $rd; + foreach $rd (@redolist) { + chomp $rd; + print REDOLIST "$rd\n"; + } + close(REDOLIST); + rename + ("$ARGV[1]/backup/$thingy.bk.bk","$ARGV[1]/backup/$thingy.bk"); + $_ = "/."; + } + } + $count = 1; + $repeaters{$_}++; + if ($repeaters{$_} == 1) { + $temp = 0; + } + else { + $temp = $repeaters{$_} - 1; + } + if (defined $version{$1}) { + $HL{$_}[$temp] = "$1_$version{$1}"; + } + } + } + undef @ppackage; + + # We will create one file with the 1..and another with >1.. + # than split..reverse..and order.accordingly..this makes + # things much faster. Remember clean-up routines for kill. + print " Starting ... writing to $ARGV[2]!\n"; + # Create the database + open(BIG, ">$ARGV[2]/big.debian") or die; + open(LONG, ">$ARGV[2]/long.debian") or die; + foreach $thingy (sort keys %HL ) { + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + # Humm, will split or grep be faster? + #my $tingy = "@{ $HL{$thingy} }" . " " . @{ $HL{$thingy} }; + my $tingy = "@{ $HL{$thingy} }"; + if (@{ $HL{$thingy} } > 1 || @{ $HL{$thingy} } eq "") { + print LONG "$thingy -> $tingy\n"; + } + elsif (@{ $HL{$thingy} } == 1) { + print BIG "$thingy -> $tingy\n"; + } + } + #print "Finished\n"; + close(BIG); + close(LONG); + #undef %HL; + print " Cleaning up\n"; + +__END__ diff --git a/bin/imswim b/bin/imswim new file mode 100755 index 0000000..67e7f6c --- /dev/null +++ b/bin/imswim @@ -0,0 +1,99 @@ +#!/usr/bin/perl -w +#use diagnostics; +require 5.004; +use strict; + +################################################################################ +# Package administration and research tool for Debian # +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum # +# # +# 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.# +################################################################################ + + +=pod + +This allows computers with a small amount of memory or overloaded system +to succeed in making the databases for SWIM::DB_Init. Instead of using +transfer.deb to grab everything into memory and then creating the +long.debian and big.debian files right out of memory for processing by +SWIM::MD, it works like longswim by creating one large file to the disk +(this can use lots of memory, but can swap easily) then it uses slowswim +to create long.debian and big.debian using a minimal memory method, then +it finishes using SWIM::MD. + +To test supply these arguments - info dir, temporary dir "imswim +/var/lib/dpkg/info /tmp" and create a transfer.deb file +beforehand in the temporary dir which has the packagename_version one to a +line. + +=cut + + + if ($#ARGV == -1) { + print "swim: imswim requires arguments, see program for instructions\n"; + exit; + } + else { + $| = 1; my $x = 1; + open(FILEDIR, ">$ARGV[1]/filedir.deb") + or warn "could not create filedir.deb\n"; + open(TRANSFER, "$ARGV[1]/transfer.deb") or warn "needs transfer.deb"; + while () { + chomp; + my @the = split(/_/, $_); + open (LIST, "$ARGV[0]/$the[0].list") + or warn "could not file *list"; + chomp; + # better check if /. is missing in any of the *list + my $count = 0; + my @count = ; + close(LIST); + foreach (@count) { + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + chomp $_; + # does /. exist? it should be first. + if ($count == 0) { + if ($_ !~ m,\/\.,) { + my $shifter = $_; + my @redolist = @count; + push(@count,$shifter); + # humm let's rebuild the offending backup list, this + # is important for --db. + unshift(@redolist,"/."); + open(REDOLIST, ">$ARGV[0]/backup/$the[0].list.bk.bk") + or warn "needed to edit $the[0].list because it lacked /., + but could not open up a backup file\n"; + my $rd; + foreach $rd (@redolist) { + chomp $rd; + print REDOLIST "$rd\n"; + } + close(REDOLIST); + rename("$ARGV[0]/backup/$the[0].list.bk.bk", + "$ARGV[0]/backup/$the[0].list.bk"); + $_ = "/."; + } + } + $count = 1; + print FILEDIR "$_ -> $the[0]_$the[1]\n"; + } # foreach @count + } # while TRANSFER + close(TRANSFER); + close(FILEDIR); + } # else diff --git a/bin/longswim b/bin/longswim new file mode 100755 index 0000000..ed31373 --- /dev/null +++ b/bin/longswim @@ -0,0 +1,591 @@ +#!/usr/bin/perl -w + +#use diagnostics; +use strict; +use DB_File; + +################################################################################ +# Package administration and research tool for Debian # +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum # +# # +# 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.# +################################################################################ + + +=pod + +This program creates the file filedir.deb using choice() and +comma_choice() (which both use timing() in case Contents is newer than +Packages). It establishes the file based on --main, --contrib, --non-free, +--non-us or the default. This program is quite time consuming and uses +more and more memory as it runs. Afterwared, the output can be processed +by fastswim (high memory approach) or slowswim (low memory approach), +whether either is faster is still subject to experimentation. swim packs +everything into the databases. It also produces the report +.contentsdiff-arch-dists.deb which shows which packages exist in Contents +which don't exist in Packages. + +This program takes a large amount of arguments. Look at nmd() in +SWIM::NDB_Init. + +=cut + + + if ($#ARGV == -1) { + print "swim: longswim requires many arguments, see program for instructions\n"; + exit; + } + +my $Contents; +my $contentsindex; +my ($main,$contrib,$non_free,$non_us); +my $tmp; +my (%watch,%ndb); +my $npackages; +my $gzip; +my $place; + +# process @ARGV +$Contents = $ARGV[0]; $contentsindex = $ARGV[1]; +$main = $ARGV[2]; $contrib = $ARGV[3]; +$non_free = $ARGV[4]; $non_us = $ARGV[5]; +$tmp = $ARGV[6]; +$npackages = $ARGV[7]; +$gzip = $ARGV[8]; +$place = $ARGV[9]; +my $Contents_mtime = $ARGV[10]; + +# tie it once not a quarter million times +tie %ndb, 'DB_File', "$npackages" or die "DB_File: $!"; + +# Let's find the arch and dists +my @archdist = split(m,/,,$contentsindex); +my($arch,$dist) = (split(m,-,,$archdist[$#archdist]))[1,2]; +$dist =~ s,\.deb,,; + +unlink("$place/.contentsdiff-$arch-$dist.deb") + if -e "$place/.contentsdiff-$arch-$dist.deb"; + +nmd(); + +# main processing program +sub nmd { + + my %again; + my %all; + + $| = 1; my $x = 1; + open(CONTENTS, "$Contents") or die "where is it?\n"; + open(FILEDIR,">$tmp/filedir.deb"); + open(CONTENTSDB,">$contentsindex"); + while () { + print CONTENTSDB $_; + if (/^FILE\s*LOCATION$/) { + while () { + s,^(\./)+,,; # filter for Debians altered dir structure + print CONTENTSDB $_; + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + chomp $_; + # find all directories + # split is the way to go. + # If it ends with / its a directory + my($dirfile,$package,@packs,@dirfile,@package,@comma); + + + ###################### + # ENDS WITH / # + ###################### + if (m,.*/\s+\w*,) { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); $dirfile =~ s,/$,,; + @comma = split(/,/,$package); + + ################# + # HAS A COMMA # + ################# + if (scalar(@comma) >= 2) { + # humm many packages share this file/dir + my @choice_package; + ########## + ## MAIN ## + ########## + if ($main eq "yes") { + foreach (@comma) { + if (defined $_) { + if ($_ !~ m,^non-free/|^contrib/|^non-us/,) { + push(@choice_package,$_); + } + } + } + @packs = comma_choice(@choice_package); + } # choice in main + ############ + ##NON-FREE## + ############ + if ($non_free eq "yes") { + foreach (@comma) { + if (m,^non-free/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice non-free + ########### + ##CONTRIB## + ########### + if ($contrib eq "yes") { + foreach (@comma) { + if (m,^contrib/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice contrib + ######### + #NON-US## + ######### + if ($non_us eq "yes") { + foreach (@comma) { + if (m,^non-us/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice non-us + + } # scalar @comma >= 2 + + # When only one package exists for dir + ############# + ############## + # NO COMMA # + ############## + elsif (scalar(@comma) == 1) { + my $choice_package; + ########## + ## MAIN ## + ########## + if ($main eq "yes") { + # only one package found related to choice section + if (defined $package) { + if ($package !~ m,^non-free/|^contrib/|^non-us/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ############ + ##NON-FREE## + ############ + if ($non_free eq "yes") { + if (defined $package) { + if ($package =~ m,^non-free/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ########### + ##CONTRIB## + ########### + if ($contrib eq "yes") { + if (defined $package) { + if ($package =~ m,^contrib/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ######### + #NON-US## + ######### + if ($non_us eq "yes") { + if (defined $package) { + if ($package =~ m,^non-us/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + + } # @comma = 1 + + ################# + # WRITE TO FILE # + ################# + foreach $package (@packs) { + my ($count,$holder); + for ($count = 0; $count <= $#dirfile; $count++) { + if ($count == 0) { + $holder = "/$dirfile[$count]"; + my $again = "$dirfile[$count] -> $package"; + my $all = "/. -> $package"; + $again{$again}++; + $all{$all}++; + if ($all{$all} == 1) { + print FILEDIR "/. -> $package\n"; + ##repeaters("/.",$package); + } + if ($again{$again} == 1) { + print FILEDIR "/$dirfile[$count] -> $package\n"; + ##repeaters("/$dirfile[$count]",$package); + } + } + else { + $holder = $holder . "/$dirfile[$count]"; + #print "$holder -> $package\n"; + #repeaters($holder,$package); + my $again = "$holder -> $package"; + $again{$again}++; + if ($again{$again} == 1) { + print FILEDIR "$holder -> $package\n"; + ##repeaters($holder,$package); + } + } + } # end for + } + } # does end with / + + ###################### + # DOESN'T END WITH / # + ###################### + # find all files and directories + else { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + # watch this + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); + @comma = split(/,/,$package); + + ################# + # HAS A COMMA # + ################# + if (scalar(@comma) >= 2) { + # humm many packages share this file/dir + my @choice_package; + ########## + ## MAIN ## + ########## + if ($main eq "yes") { + foreach (@comma) { + if (defined $_) { + if ($_ !~ m,^non-free/|^contrib/|^non-us/,) { + push(@choice_package,$_); + } + } + } + @packs = comma_choice(@choice_package); + } # choice in main + ############ + ##NON-FREE## + ############ + if ($non_free eq "yes") { + foreach (@comma) { + if (m,^non-free/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice non-free + ########### + ##CONTRIB## + ########### + if ($contrib eq "yes") { + foreach (@comma) { + if (m,^contrib/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice contrib + ######### + #NON-US## + ######### + if ($non_us eq "yes") { + foreach (@comma) { + if (m,^non-us/,) { + push(@choice_package,$_); + } + } + @packs = comma_choice(@choice_package); + } # choice non-us + + } # scalar @comma == 2 + + # When only one package exists for file + ############# + ############## + # NO COMMA # + ############## + elsif (scalar(@comma) == 1) { + my $choice_package; + ########## + ## MAIN ## + ########## + if ($main eq "yes") { + # only one package found related to choice section + if (defined $package) { + if ($package !~ m,^non-free/|^contrib/|^non-us/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ############ + ##NON-FREE## + ############ + if ($non_free eq "yes") { + if (defined $package) { + if ($package =~ m,^non-free/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ########### + ##CONTRIB## + ########### + if ($contrib eq "yes") { + if (defined $package) { + if ($package =~ m,^contrib/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + ######### + #NON-US## + ######### + if ($non_us eq "yes") { + if (defined $package) { + if ($package =~ m,^non-us/,) { + $choice_package = $package; + @package = split(/\//,$choice_package); + } + } + @packs = choice(@package); + } # end choice main + + + } # @comma = 1 + + ################# + # WRITE TO FILE # + ################# + foreach $package (@packs) { + my ($count,$holder); + for ($count = 0; $count <= $#dirfile; $count++) { + if ($count == 0) { + $holder = "/$dirfile[$count]"; + my $again = "$dirfile[$count] -> $package"; + my $all = "/. -> $package"; + $again{$again}++; + $all{$all}++; + if ($all{$all} == 1) { + print FILEDIR "/. -> $package\n"; + } + if ($again{$again} == 1) { + print FILEDIR "/$dirfile[$count] -> $package\n"; + } + } + # Here's where things really start to turn ugly. + else { + $holder = $holder . "/$dirfile[$count]"; + my $again = "$holder -> $package"; + $again{$again}++; + if ($again{$again} == 1) { + print FILEDIR "$holder -> $package\n"; + } + } + } # end for + } # @packs - more than one package for this file + } # end else not dir + } + } + } + close(FILEDIR); + close(CONTENTS); + + print "Compress contents\n"; + system "$gzip", "-9", "$contentsindex"; + utime(time,$Contents_mtime,$contentsindex); + print "Cleaning up\n"; + # this will add a newline, but better to do a Ctrl-C than to have the + # process hang and respawn itself - something which sometimes happens + kill INT => $$; + print "swim: please press Ctrl-c\n"; # just in case :) + + # probably don't need to do this ends the program + #undef %all; + #undef %again; + +} # end sub nmd + +# this finds the package or none which equal choice section when a +# file/dir is found with one package +sub choice { + + my (@package) = @_; + my @packs; + if ($#package == 1) { + my $what = timing($package[1]); + if (defined $what) { + #$package[1] = version($package[1]); + @packs = $what; + } + } + elsif ($#package == 2) { + my $what = timing($package[2]); + if (defined $what) { + #$package[2] = version($package[2]); + @packs = $what; + } + } + + return @packs; + +} # end sub choice + + +# this finds the package(s) or none which equal choice section when a +# file/dir is found with more than one package +sub comma_choice { + + my (@choice_package) = @_; + my (@package,@packs); + + if (@choice_package) { + if ($#choice_package == 0) { + @package = split(/\//,$choice_package[0]); + if ($#package == 1) { + my $what = timing($package[1]); + if (defined $what) { + #$package[1] = version($package[1]); + push(@packs,$what); + } + } + elsif ($#package == 2) { + my $what = timing($package[2]); + if (defined $what) { + #$package[2] = version($package[2]); + push(@packs,$what); + } + } + } + elsif ($#choice_package > 0) { + # Basically, we will keep all conflicting dirs/files + # because often they are related + foreach (@choice_package) { + @package = split(/\//,$_); + if ($#package == 1) { + my $what = timing($package[1]); + if (defined $what) { + push(@packs,$what); + } + } + elsif ($#package == 2) { + my $what = timing($package[2]); + if (defined $what) { + push(@packs,$what); + } + } + } + } # else more than 1 for choice + } # defined choice + return @packs; + +} # end sub comma_choice + + +# this sub produces a report file..in case Packages is older than Contents +# there will be other reports, ofcourse, like if Packages is newer than +# Contents. Uses version(); +sub timing { + + my ($lookup) = @_; + + my $afterlookup = nversion($lookup); + if ($afterlookup eq 1) { + $watch{$lookup}++; + if ($watch{$lookup} == 1) { + open(REPORT,">>$place/.contentsdiff-$arch-$dist.deb") + or die "can't create a file\n"; + print REPORT "Found in Contents, not in Packages: $lookup\n"; + close(REPORT); + } + return; + } + else { + return $afterlookup; + } + +} # end my timing + +# checks npackage.deb to find version for package found in Contents +sub nversion { + + my ($argument) = @_; + #ndb(); + + if (defined $argument) { + # We will check for more than two..just in case + if ($argument !~ /_/) { + if (defined $ndb{$argument}) { + $argument = $ndb{$argument}; + return $argument; + } + # fixed the space packages + else { + return 1; + } + } + } + #untie %ndb; + +} # end sub nversion + +sub ndb { + #tie %ndb, 'DB_File', "$npackages" or die "DB_File: $!"; +} # end sub ndb diff --git a/bin/slowswim b/bin/slowswim new file mode 100755 index 0000000..150c34c --- /dev/null +++ b/bin/slowswim @@ -0,0 +1,131 @@ +#!/usr/bin/perl -w + +#use diagnostics; +use strict; + +################################################################################ +# Package administration and research tool for Debian # +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum # +# # +# 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.# +################################################################################ + + +=pod + +This program only takes two argument, a temp directory and the name of the +binary sort..sort. You can test a filedir.deb file. + + +=cut + + if ($#ARGV == -1) { + print "swim: slowswim requires arguments, see program for instructions\n"; + exit; + } + +my $tmp = $ARGV[0]; +my $sort = $ARGV[1]; + +pre_md(); + +# This is nmd()'s version of fastswim..also a lowmem method, after making +# long.debian and big.debian, process_md() finishes the job. +sub pre_md { + + my %HL; + my $temp; + my %repeaters; + my $fcount = 0; + my @tempholder; + + print "Sorting everything\n"; + system ("$sort $tmp/filedir.deb > $tmp/sortfiledir.deb"); + unlink("$tmp/filedir.deb"); + + # grab the keys from the sorted file + print "Making the massive hash using lowmem\n"; + $| = 1; my $x = 1; + open(FILEDIR, "$tmp/sortfiledir.deb") or die "where is sortfiledir.deb?\n"; + while () { + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + my ($place, $packname) = split(/ -> /,$_,2); + push(@tempholder,"$place -> $packname"); + if ($fcount != 0) { + my($tplace,$tpackname) = split(/ -> /,$tempholder[$fcount - 1],2); + chomp $tpackname; + # As long as they aren't different add to HL because they + # belong to a group. + if ($tplace eq $place) { + #print "$tplace and $place\n"; + $repeaters{$tplace}++; + if ($repeaters{$tplace} == 1) { + $temp = 0; + } + else { + $temp = $repeaters{$tplace} - 1; + } + $HL{$tplace}[$temp] = $tpackname; + } + # they new guy is different, but the old guy belongs to the + # previous group or not, so finish adding to %HL and then + # print out, and undef %HL + else { + #print "I AM DIFF $tplace\n"; + # finish adding + $repeaters{$tplace}++; + if ($repeaters{$tplace} == 1) { + $temp = 0; + } + else { + $temp = $repeaters{$tplace} - 1; + } + $HL{$tplace}[$temp] = $tpackname; + + # print out + open(BIG, ">>$tmp/big.debian") or die; + open(LONG, ">>$tmp/long.debian") or die; + my $thingo; + foreach $thingo (sort keys %HL ) { + my $tingy = "@{ $HL{$thingo} }"; + if (@{ $HL{$thingo} } > 1 || @{ $HL{$thingo} } eq "") { + print LONG "$thingo -> $tingy\n"; + } + elsif (@{ $HL{$thingo} } == 1) { + print BIG "$thingo -> $tingy\n"; + } + } + close(BIG); + close(LONG); + + # The whole key for lowmem systems + undef %repeaters; + undef %HL; + undef $tempholder[$fcount - 1]; + + } + } # if fcount ne 0 + + $fcount++; + } + + # also do this in db() & ndb() + unlink("$tmp/sortfiledir.deb"); + + +} # end sub pre_md diff --git a/changelog b/changelog new file mode 100644 index 0000000..b9d1ad3 --- /dev/null +++ b/changelog @@ -0,0 +1,78 @@ +swim (0.3.6) - October 20 2000 + +-- Made swim perl-5.6 happy. Thanks to Douglas du Boulay + for pointing this out. + +swim (0.3.5) - January 28 2000 + +-- Fixed a minor bug pertaining to the mtime of Contents which occured + during initial building of the uninstalled filesystem using FDBDF or + DF. This bug arose as a result of a bug fix in 0.3.4. + +swim (0.3.4) - January 23 2000 + +-- Made the changelog and copyright option work properly in relation to + the fsstnd Debian has adopted with backwards compatibility. Fixed a + regexp in Qftp to properly deal with packages which match one another, + but aren't the same. Fixed xyzr to work properly with ps. Fixed share + -d/l output for p option. Added an indication when extraction + succeeds. Now Contents is properly filtered for ndb. Removed extra + output from menu for package option. Added example documentation, + thanks to John Lapeyre for the suggestion. Also, thanks to Joel Soete + for reporting corrupt sources from a faulty upload, and to tucows.com + for adding swim to their archive and awarding swim 5 Penguins. + +swim (0.3.3) - January 15 2000 + +-- Repaired a bug in longswim causing the uninstalled filesystem to be + made with packages which looked like spaces due to a return code error, + which caused some trouble for the virtual directories. ncontents is + now filtered of ./, though it was cool to look at. + +swim (0.3.2) - January 05 2000 + +-- Fixed to properly find documentation in the not-installed new Debian + share directories, perl5 in Depends for the new Debian perl policy, and + year 2000 in help. + +swim (0.3.1) - January 04 2000 + +-- Because of change in Debian's directory structure in Contents, added a + filter so that not-installed database is properly made without repeats. + Fixed a documentation error in QUICKSTART. Made swim@the.netpedia.net + default anonymous login. Minor documentation improvements. + +swim (0.3.0) - June 15 1999 + +-- The cleaned up version of 0.2.9. Rebuild databases if you were using + version 0.2.8 or less. + +swim (0.2.9) - May 14 1999 + +-- This is an interim release until 0.3.0 is released. Major bug fixes, + and some new features, including a history, and updating for + not-installed db. Rebuild databases if you were using an older version. + +swim (0.2.8) - Mar 13 1999 + +-- Fixed a minor bug which was preventing virtual options --xyz and --ftp + from working with searches. +-- Set the $swim_version variable to the right version number, and + automated the release process to avoid problems like the failure to + change this variable in the 0.2.7 release from occurring again. + +swim (0.2.7) - Mar 12 1999 + +-- Fixed a file test in SWIM::Conf which kept the initial directories from + being created on startup, making the program fail. Three names deserve + recognition: John Lapeyre, Jonathan P. Tomer, and Cale Epstein who all + provided their own perspective to the problem, I combined all three + approaches. Shaleh pointed out a packaging error. + +swim (0.2.6) + +-- First initial public offering around the beginning of March, 1999, + includes the main swim program, four exercise programs to help with + database creation, important swim manuals and twenty-five module + members. +-- swimmers ... take your mark ... go! diff --git a/contact_and_website b/contact_and_website new file mode 100644 index 0000000..339ab24 --- /dev/null +++ b/contact_and_website @@ -0,0 +1,7 @@ +email: + +Jonathan D. Rosenbaum + +http: + +the.netpedia.net diff --git a/examples/Cron b/examples/Cron new file mode 100755 index 0000000..5d97708 --- /dev/null +++ b/examples/Cron @@ -0,0 +1,20 @@ +#!/bin/bash + +# This is a simple approach. You could have a monthly Cron for stable and +# then update if any changes were observed, a weekly Cron for frozen, and +# a daily Cron for unstable. + +# For this example a default of unstable is assumed. +# This downloads only one Contents-arch for the unstable distribution. +# Updates the Packages using apt, and grabs the Contents-arch and Packages +# for the stable distribution if there are any changes. +# Update the sources: +swim --ftp --Contents DF --onec >> /var/log/swim.log 2>&1; +swim --apt --update >> /var/log/swim.log 2>&1; +swim --ftp --dists stable --onec >> /var/log/swim.log 2>&1; + +# This will update the database for the default distribution/architecture +# using 'cron' to automatically pick the newest packages. +# Update the databases: +swim --db >> /var/log/swim.log 2>&1; +swim --ndb APT --cron --Contents DF >> /var/log/swim.log 2>&1; diff --git a/lib/Ag.pm b/lib/Ag.pm new file mode 100644 index 0000000..3ae98c8 --- /dev/null +++ b/lib/Ag.pm @@ -0,0 +1,263 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Ag; +use strict; +use SWIM::Global qw(:Info $file_now); +use SWIM::DB_Library qw(:Xyz); +use SWIM::Info; +use SWIM::Pn_print; +use SWIM::Deps; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(description q_description); + + +# stuff to query package names, -a, and groups + +# -qi Anotherwards that big thing of info...also +# -c, -l +sub description { + + my ($commands) = @_; + my %commands = %$commands; + + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + + if (!$commands->{"n"}) { + dbi(\%commands); + } + else { + ndb(\%commands); + } + + + if (defined $argument) { + # We will check for more than two..just in case + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + } + if ($db{"$argument"}){ + my $package = $db{"$argument"}; + print $package; + } + else { + print "package $argument is not installed\n"; + exit; + } + } + untie %db; + + + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + + if ($commands->{"c"} && !($commands->{"l"} || $commands->{"d"})) { + if (conf(\%commands) ne 0) { + print conf(\%commands) if !$commands->{"md5sum"}; + # here for a reason + # if -i because calls from qindexer. + if ($commands->{"i"}) { + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands) + } + } + } + if (($commands->{"c"} && ($commands->{"l"} || $commands->{"d"})) || + ($commands->{"l"} || $commands->{"d"})) { + if ($commands->{"c"} && conf(\%commands) ne 0) { + print conf(\%commands) if !$commands->{"md5sum"}; + } + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + + if (!($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"})) { + if ($commands->{"x"} || $commands->{"ftp"} || $commands->{"source"} || + $commands->{"source_only"} || $commands->{"remove"} || + $commands->{"r"} || $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + +} # end sub description + +# Access Descriptions, and other stuff for known . +# This includes -ql(d)c, -qc or plain -q (just the package name and +# version). Anotherwards if -i isn't used this sub is called. And +# -ql is handled by file. Mostly, this was designed for calling a single +# package name on the command line without a known package title except +# when -q is called by itself, but using -T is an exception since this is +# useful. +sub q_description { + + my ($commands) = @_; + my %commands = %$commands; + + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + + + if (!$commands->{"n"}) { + dbi(\%commands); + } + else { + ndb(\%commands); + } + + + if (defined $argument) { + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + if ($commands->{"c"} && $commands->{"d"}) { + require SWIM::File; + SWIM::File->import(qw(file)); + print "$argument\n" if $commands->{"g"}; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + if (conf(\%commands) ne 0) { + print conf(\%commands) if !$commands->{"md5sum"}; + } + # it's nice to print out -d with -c, so this was added. + file(\%commands); + } + elsif ($commands->{"c"}) { + # this produces annoying spaces + print "$argument\n" if $commands->{"g"} && conf(\%commands) ne 0; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + if (conf(\%commands) ne 0) { + print conf(\%commands) if !$commands->{"md5sum"}; + if ($commands->{"md5sum"}) { + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + } + } + elsif ($db{$argument} && !$commands->{"c"}) { + print "$argument\n" if $commands->{"T"} || + $commands->{"depends"} || $commands->{"pre_depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"conflicts"} || $commands->{"replaces"} || + $commands->{"provides"}; + singular(\%commands); + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + print "\n" if $commands->{"T"} || + $commands->{"depends"} || $commands->{"pre_depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"conflicts"} || $commands->{"replaces"} || + $commands->{"provides"}; + } + else { print "package $argument is not installed\n"; } + } + elsif ($argument =~ /_/) { + if ($commands->{"c"} && $commands->{"d"}) { + print "$argument\n" if $commands->{"g"}; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + print conf(\%commands) if conf(\%commands) ne 0 && !$commands->{"md5sum"}; + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + elsif ($commands->{"c"}) { + my $check = conf(\%commands); + print "$argument\n" if $commands->{"g"} && $check ne 0 || + $commands->{"l"}; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + if (conf(\%commands) ne 0) { + print conf(\%commands) if !$commands->{"md5sum"}; + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + elsif (conf(\%commands) == 0) { + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + } + elsif ($db{$argument} && !$commands->{"c"}) { + # watch this + ##print "$argument\n" if $commands->{"g"}; + print "$argument\n" if $commands->{"T"} || + $commands->{"depends"} || $commands->{"pre_depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"conflicts"} || $commands->{"replaces"} || + $commands->{"provides"}; + singular(\%commands); + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + print "\n" if $commands->{"T"} || + $commands->{"depends"} || $commands->{"pre_depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"conflicts"} || $commands->{"replaces"} || + $commands->{"provides"}; + } + else { print "package $argument is not installed\n"; } + } + + } + untie %db; + + if (!defined $file_now && + !($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"})) { + if ($commands->{"x"} || $commands->{"ftp"} || $commands->{"source"} || + $commands->{"source_only"} || $commands->{"remove"} || + $commands->{"r"} || $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } +} # end sub q_description + + + + + +1; diff --git a/lib/Apt.pm b/lib/Apt.pm new file mode 100644 index 0000000..21d755f --- /dev/null +++ b/lib/Apt.pm @@ -0,0 +1,1219 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Apt; +use strict; +use SWIM::Conf; +use vars qw(@ISA @EXPORT_OK); +use Net::FTP; +use SWIM::Library qw(which_archdist); +use SWIM::F; +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(apt ftp); + + + +# this module hands major modes --apt and --ftp + +=pod + +install is integrated virtually with -q,--search. update allows the +Packages to be upgraded, and these can be used by initndb, rebuildndb and +ndb. apt appears to run a check every time it runs, so check won't be +included for now. -d, -download-only is better done by using virtual ftp, +the package(s) can be temporarily flipped into apts domain for +installation. Other than update and clean, upgrade and dist-upgrade are +included with -xyz for control and to avoid unwanted actions. There are +also the interesting aspects of apt-cache, but this won't be included +presently. + +=cut + + +sub apt { + + + my ($apt_get,$sources,$commands) = @_; + my %commands = %$commands; + my @FTP; + + + if ($commands->{"apt"}) { + + ################ + # UPDATE CLEAN # + ################ + # error correcting and handle --update && --clean + if ($commands->{"update"} && + !($commands->{"upgrade"} || $commands->{"dist_upgrade"} || + $commands->{"x"} || $commands->{"y"} || $commands->{"z"})) { + if ($commands->{"update"}) { + system "$apt_get update"; + if ($commands->{"clean"}) { + system "$apt_get clean"; + } + elsif ($commands->{"autoclean"}) { + system "$apt_get autoclean"; + } + if ($commands->{"check"}) { + system "$apt_get check"; + } + } + } + elsif ($commands->{"clean"} && !($commands->{"upgrade"} || + $commands->{"dist_upgrade"} || $commands->{"x"} || $commands->{"y"} + || $commands->{"z"} || $commands->{"updatenr"})) { + system "$apt_get clean"; + if ($commands->{"check"}) { + system "$apt_get check"; + } + } + elsif ($commands->{"autoclean"} && !($commands->{"upgrade"} || + $commands->{"dist_upgrade"} || $commands->{"x"} || $commands->{"y"} + || $commands->{"z"} || $commands->{"updatenr"})) { + system "$apt_get autoclean"; + if ($commands->{"check"}) { + system "$apt_get check"; + } + } + elsif ($commands->{"check"} && !($commands->{"upgrade"} || + $commands->{"dist_upgrade"} || $commands->{"x"} || $commands->{"y"} + || $commands->{"z"} || $commands->{"updatenr"})) { + system "$apt_get check"; + } + elsif ($commands->{"clean"} || $commands->{"update"}) { + print "swim: --update cannot be used with option"; + print " --upgrade" if $commands->{"upgrade"}; + print " --dist_upgrade" if $commands->{"dist_upgrade"}; + print " -x" if $commands->{"x"}; + print " -y" if $commands->{"y"}; + print " -z" if $commands->{"z"}; + print "\n"; + exit; + } + + + ######################## + # UPGRADE DIST_UPGRADE # + ######################## + if ($commands->{"upgrade"} || $commands->{"dist_upgrade"} || + $commands->{"x"} || $commands->{"y"} || $commands->{"z"} && + !($commands->{"update"} || $commands->{"clean"})) { + if ($commands->{"upgrade"} && $commands->{"dist_upgrade"}) { + print "swim: do not use --upgrade and --dist_upgrade together\n"; + exit; + } + if (($commands->{"upgrade"} || $commands->{"dist_upgrade"}) && + !$commands->{"x"}) { + if ($commands->{"y"} || $commands->{"z"}) { + print "swim: "; + print "-"; + print "y" if $commands->{"y"}; + print "z" if $commands->{"z"}; + print " require -x\n"; + exit; + } + print "swim: "; + print "--upgrade" if $commands->{"upgrade"}; + print "--dist_upgrade" if $commands->{"dist_upgrade"}; + print " require at least -x\n"; + exit; + } + + ################# + # SAFETY CHECK # + ################# + if ($commands->{"upgrade"} || $commands->{"dist_upgrade"}) { + if ($commands->{"z"}) { + print "swim: you are about to install with "; + print "--upgrade" if $commands->{"upgrade"}; + print "--dist_upgrade" if $commands->{"dist_upgrade"}; + print "\n"; + print "swim: are you sure you want to go on? (yes or no): "; + while () { + last if $_ eq "yes\n"; + exit if $_ eq "no\n"; + if ($_ eq "\n" || $_ ne "yes\n" || $_ ne "no\n") { + print "swim: please enter yes or no: "; + } + } + } + } + else { + print "swim: no options for --apt specified\n"; + exit; + } + + my $upgrade; + if ($commands->{"upgrade"} || $commands->{"dist_upgrade"}) { + $upgrade = "upgrade" if $commands->{"upgrade"}; + $upgrade = "dist-upgrade" if $commands->{"dist_upgrade"}; + + if ($commands->{"x"} && !($commands->{"y"} || $commands->{"z"})) { + system "$apt_get $upgrade -qs --ignore-hold"; + } + elsif ($commands->{"y"} && ! $commands->{"z"}) { + print "swim: use -y with -z\n"; + exit; + } + elsif ($commands->{"y"} && $commands->{"z"}) { + system "$apt_get $upgrade -yq --ignore-hold"; + } + elsif ($commands->{"z"} && !$commands->{"y"}) { + system "$apt_get $upgrade -q --ignore-hold"; + } + + } + + } # end upgrade dist_upgrade + + } # if apt + + + +} # end sub apt + + + +=pod + +Packages and Contents files can be acquired in several fashions. If apt +is installed on the system, Packages files can automatically be derived +and ordered according to the dist for the particular architecture being +used on the computer system, but other architectures aren't represented. +Hence the ftp method is provided. This uses information from the +configuration file to update the Contents and Packages file. Contents +file is updated according to distribution and architecture, and Packages +file is updated according to distribution, architecture and section. Both +are renamed appropriately and put into the default directory specified by +the configuration file, in fact the same naming structure that apt uses is +used. + +If only one architecture and one distribution are wanted they can be specified +from the command line overridding the defaults in the conf, but if one is +specified, it is assumed the other is also the default value, basically the +conf values are totally overridden, except for the sites. Likewise the +sections --main, --non-free etc., can also be used to override the defaults..so +use with care since all sites will be visited. Otherwise everything found in +the conf file for --Contents and/or --Packages is downloaded from an available +ftp site. The syntax in the conf file is exactly the same as apt's +sources.list file, except that deb can have a hyphen appended and a name of an +architecture (ex: deb-alpha), deb will be the architecture of the local machine +found with dpkg --print-installation-architecture if a hyphen isn't used. The +ftp, and file method will both be supported at this time, although the cdrom +will need the dist directory for file. + +All the sites are visted, and the databases are downloaded. Although the +goal of swim is to have the newest databases, a person may want to +download older or newer databases, so when initndb, rebuildndb, or ndb are +run, swim will interact with a person and allow them to decide which +database to use, this applies to DF,FDBDF, and APT. If -y is specified +swim will use the newest databases. Swim will also check that the +databases actually exist. Also the DF (default directory and naming) +directory can be overridden by specifing an alternative directory on the +command line, the databases will still be named though. If --ftp is +specified without any options..everything in the conf file is downloaded, +renamed and put into the default directory. The advantage of the default +directory is that is can be found by --initndb, --rebuildndb, and --ndb. +People with apt will only need to specify "swim --ftp --Contents DF", and +swim --apt --update, and then for instance ... swim --initndb APT +--Contents DF. + +=cut +sub ftp { + + my ($commands) = @_; + my %commands = %$commands; + + # Let's find the architecture for the local system, so we know what deb + # is. If dpkg is installed we might as well just use it to find the arch + # otherwise "gcc --print-libgcc-file-name" with a lookup using + # information from the archtable found in apt. + my (@deb,$deb); + if (defined $dpkg) { + system "$dpkg --print-installation-architecture > $tmp/arch.deb"; + open(ARCH, "$tmp/arch.deb") or warn "couldn't find arch\n"; + my @deb = ; chomp $deb[0]; + $deb = $deb[0]; + } + else { + if (defined $gcc) { + my %table = qw(i386 i386 i486 i386 i586 i386 i686 i386 pentium i386 + sparc sparc alpha alpha m68k m68k arm arm powerpc + powerpc ppc powerpc); + system "$gcc --print-libgcc-file-name > $tmp/arch"; + open(AR,"$tmp/arch") or warn "could not find the arch file\n"; + my @argcc; + while() { + @argcc = split(/-/,$_); + } + close(AR); + my ($argcc, $arc); + # this works fine for Debian, but RH has three dashes .. its probably + # safe to say its at $argcc[1], but why be too sure? + #$argcc = (split(m,/,,$argcc[$#argcc - 1]))[1]; + for $arc (0 .. $#argcc) { + $argcc = (split(m,/,,$argcc[$arc]))[1]; + if (defined $table{$argcc}) { + $deb = $table{$argcc}; + last; + } + elsif ($arc == $#argcc) { + print "swim: mis-read your machines architecture\n"; + exit; + } + } + } + else { + print "swim: will not have much swim fun without gcc\n"; + exit; + } + } + + # Check if there is a sources.list specified + if (-e "$swim_conf/swimz.list") { + undef @FTP; + open(SOURCES,"$swim_conf/swimz.list") + or warn "swim: could not find swimz.list\n"; + while () { + if ($_ !~ m,#.*|^\s+,) { + chomp; push(@FTP,$_); + } + } + if ($#FTP == -1) { + print "swim: no sites specified in swimz.list, quiting\n"; + exit; + } + } + + # might as well check for a temporary directory for downloads, if it + # doesn't exist create it. + mkdir("$default_directory/partial",$permission) + if !-d "$default_directory/partial"; + + + # Let's breakup @FTP, and check for ftp or the file method and + # provide support for: + # deb ftp://nonus.debian.org/debian-non-US unstable/binary-i386/ .. although + # ftp://nonus.debian.org/debian-non-US unstable non-US will work, + # ftp://ftp.debian.org/debian project/experimental is the only way to get + # the experimental distribution. This situation exists because non-us is + # essentially a section like contrib in Europe, but it is separated from the + # US distribution. Experimental is a distribution unto itself and has + # no symlinks from dists. + # And add the appropriate symlinks for non-us + + my($arc,$dists) = which_archdist(\%commands); + $arc =~ s,-,,; $dists =~ s,-,,; + if ($commands->{"dists"} || $commands->{"arch"}) { + $dists = $commands->{"dists"} if defined $commands->{"dists"}; + $arc = $commands->{"arch"} if defined $commands->{"arch"}; + } + my %site; my @PLACES; my %plw; + foreach (@FTP) { + ################ + # USER DEFINED # + ################ + # For --dists and --arch just filter out what isn't wanted, sections + # can be adjusted in swimz.list. + if (defined $dists) { + if ((split(/\s/,$_))[2] =~ /\b$dists\b/) { + if (defined $arc) { + if ((split(/\s/,$_))[0] eq "deb") { + if ($deb ne $arc) { + next; + } + } + elsif ((split(/\s/,$_))[0] !~ /$arc/) { + next; + } + } + } + if ((split(/\s/,$_))[2] !~ /\b$dists\b/) { + next; + } + } + elsif (defined $arc) { + if ((split(/\s/,$_))[0] eq "deb") { + if ($deb ne $arc) { + next; + } + } + elsif ((split(/\s/,$_))[0] !~ /$arc/) { + next; + } + } + else { + next; + } + #} + ###################### + # CONFIGURATION FILE # + ###################### + + my @parts = split(' ', $_); + # keep things seqential + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + $plw{$1}++; push(@PLACES,$1) if $plw{$1} == 1; + if ($parts[1] =~ m,^ftp,i) { + my $count = 3; + if ($parts[0] !~ /-/) { + $parts[0] = $deb; + # singlulars + if ($#parts == 2) { + $parts[2] =~ m,(.*/.*)/$,; + my $sdist = "$1"; + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + my $place = $1; + $site{$place}{"$parts[1]!!!!!$deb"}{$sdist}{"single"} = + $deb; + } + else { + # construct a nice structure + for (3 .. $#parts) { + # each site site!!arch -> distributions -> sections = archs + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + my $place = $1; + $site{$place}{"$parts[1]!!!!!$deb"}{$parts[2]}{$parts[$count]} + = $parts[0]; + $count++; + } + } + } + else { + $parts[0] =~ m,^deb-(.*)$,; + $parts[0] = $1; + # singlulars experimental + if ($#parts == 2) { + $parts[2] =~ m,(.*/.*)/$,; + my $sdist = "$1"; + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + my $place = $1; + $site{$place}{"$parts[1]!!!!!$parts[0]"}{$sdist}{"single"} = + $deb; + } + else { + # construct a nice structure + my $count = 3; + for (3 .. $#parts) { + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + my $place = $1; + $site{$place}{"$parts[1]!!!!!$parts[0]"}{$parts[2]}{$parts[$count]} = + $parts[0]; + $count++; + } + } + } + } # ne ftp|http + } # foreach conf line + + + ####### + # FTP # + ####### + # Now we can ftp to each unique site, and decide whether to go on or + # not. If local mtime is the same nothing is downloaded, otherwise if + # local mtime is less than remote mtime or nothing exists, download will + # occur. + my ($the_site,$site,$dist,$section,$arch,$ftp,%complete); + my $distbase; my $cc = 0; + foreach $the_site (@PLACES) { + + # will provide all kinds of options for ftp..like firewall + $ftp = Net::FTP->new($the_site, + Debug => $debug, + Timeout => $timeout, + Passive => $passive, + Firewall => $firewall, + Port => $port + ); + + ########### + # CONNECT # + ########### + if (defined $ftp) { + my $connected = $ftp->code(); + if ($connected == 220) { + print "swim: connected to $the_site\n"; + } + } + else { + print "swim: could not find $the_site\n"; + next; + } + + ######### + # LOGIN # + ######### + $ftp->login("anonymous","swim\@the.netpedia.net"); + my $logged = $ftp->code(); + # we are logged, but what is the time difference. + if ($logged == 230 || $logged == 332) { + print "swim: logged in to $the_site\n"; + $ftp->binary; + } + else { + # 530 "not logged in" will have to test this + $ftp->code(); + print "swim: not logged in to $the_site\n"; + next; + } + + ################### + # LOOP SITE ARCHS # + ################### + foreach $site (keys %{ $site{$the_site} } ) { + + ################## + # GET THE THINGS # + ################## + foreach $dist (keys %{ $site{$the_site}{$site} } ) { + # We can look for Contents now for each distribution if Contents was + # specified. + + + (my $tsite = $site) =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + $distbase = $2; + my ($distbe,$distb); + ($distbe,$arch) = (split(/!!!!!/,$distbase))[0,1]; + $distbase = (split(/!/,$distbase))[0]; + my @distb = split(m,/,,$distbe); + + for (1 .. $#distb) { + if ($_ == 1) { + $distb = $distb[$_]; + } + else { + $distb = $distb . "_" .$distb[$_]; + } + } + + # figure out experimental's name + if ($dist =~ /experimental/) { + my @dist = split(m,/,,$dist); + my $ddist; + $dist =~ m,^.*/(.*)$,; + for (0 .. $#dist) { + if ($_ == 0) { + $ddist = $dist[$_]; + } + else { + $ddist = $ddist . "_" . $dist[$_]; + } + } + $distb = $distb . "_" . $ddist; + } + + + ############## + # --CONTENTS # + ############## + my @distg = split(m,/,,$dist); + my $Go_on; + if (defined $commands->{"Contents"} && + !defined $commands->{"Release_only"}) { + if ($cc < 1) { + if ($commands->{"Contents"} eq "DF") { + # watch for undefined values here when conf file only refers + # to a non-standard dist. + my $localfile = "$default_directory/partial/$the_site" . "_" . + "$distb" . "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + my $home = "$default_directory/$the_site" . "_" . "$distb" . + "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + if (-e "$home") { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my ($lmtime) = (stat($home))[9]; + my $file_exist = $ftp->code(); + print "swim: $distg[0]/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + utime(time,$rmtime,$home); + } + elsif ($lmtime == $rmtime) { + $cc++ if $commands->{"onec"}; + } + } + else { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my $file_exist = $ftp->code(); + print "swim: $distg[0]/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($file_exist != 550) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + if (-e $home) { + utime(time,$rmtime,$home); + } + } + } + } + elsif ($commands->{"Contents"} ne "DF") { + my $place = $commands->{"Contents"}; + make_dir($place); + my $localfile = "$default_directory/partial/$the_site" . "_" . + "$distb" . "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + my $home = "$place/$the_site" . "_" . "$distb" . + "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + if (-e "$home") { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my ($lmtime) = (stat($home))[9]; + my $file_exist = $ftp->code(); + print "swim: $distg[0]/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + utime(time,$rmtime,$home); + } + else { + $cc++ if $commands->{"onec"}; + } + } + else { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my $file_exist = $ftp->code(); + print "swim: $distg[0]/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($file_exist != 550) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + if (-e $home) { + utime(time,$rmtime,$home); + } + } + } + } + $Go_on = "yes"; + } # if only 1 Contents wanted + } # if defined Contents + + ################################ + # NOT --CONTENTS && --PACKAGES # + ################################ + if (!defined $commands->{"Contents"} && + !defined $commands->{"Packages"} && + !defined $commands->{"Release_only"}) { + my $localfile = "$default_directory/partial/$the_site" . "_" . + "$distb" . "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + my $home = "$default_directory/$the_site" . "_" . "$distb" . + "_dists_" . "$dist" . "_" . "Contents-$arch.gz"; + if (-e "$home") { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my ($lmtime) = (stat($home))[9]; + my $file_exist = $ftp->code(); + print "swim: $dist/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + utime(time,$rmtime,$home); + } + else { + $cc++ if $commands->{"onec"}; + } + } + else { + my $size = + $ftp->size("$distbase/dists/$dist/Contents-$arch.gz"); + my $rmtime = + $ftp->mdtm("$distbase/dists/$dist/Contents-$arch.gz"); + my $file_exist = $ftp->code(); + print "swim: $distg[0]/Contents-$arch.gz does not exist on the server\n" + if $file_exist == 550 && $distbase !~ /non-US/ && + $distg[0] !~ /project/; + if ($file_exist != 550) { + print "swim: downloading $dist/Contents-$arch.gz ($size)\n"; + get($ftp,"$distbase/dists/$dist/Contents-$arch.gz",$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226) { + print "swim: successful retrieval of $dist/Contents-$arch.gz\n"; + $cc++ if $commands->{"onec"}; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/Contents-$arch.gz\n"; + } + if (-e $home) { + utime(time,$rmtime,$home); + } + } + } + } # if !defined Contents && Packages + + foreach $section (keys %{ $site{$the_site}{$site}{$dist} } ) { + my $sectcount = 0; + $arch = $site{$the_site}{$site}{$dist}{$section}; + + ############## + # --PACKAGES # + ############## + if (defined $commands->{"Packages"}) { + if ($commands->{"Packages"} eq "DF") { + my ($home,$localfile,$release_home,$release_localfile); + my $nue = (split(m,/,,$dist))[0]; + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($home = + "$default_directory/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($home = + "$default_directory/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($home = + "$default_directory/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + ($release_home = $home) =~ s,Packages.gz,Release,; + ($release_localfile = $localfile) =~ s,Packages.gz,Release,; + if (-e "$home") { + my ($lmtime) = (stat($home))[9]; + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $size = $ftp->size("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + utime(time,$rmtime,$home); + } + } + else { + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $size = $ftp->size("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + if (-e $home) { + utime(time,$rmtime,$home); + } + } + ########### + # RELEASE # + ########### + # this will not be very verbose + if ((-e "$release_home" && $section ne "non-US") && + (-e $release_home && $distb !~ /non-US|experimental/)) { + my ($lmtime_r) = (stat($release_home))[9]; + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + if ($lmtime_r < $rmtime_r) { + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home); + } + } + elsif ((!-e "$release_home" && $section ne "non-US") && + (!-e $release_home && $distb !~ /non-US|experimental/)) { + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home) if -e $release_home; + } + } + elsif ($commands->{"Packages"} ne "DF") { + my $place = $commands->{"Packages"}; + make_dir($place); + my($home,$localfile,$release_home,$release_localfile); + my $nue = (split(m,/,,$dist))[0]; + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($home = + "$place/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($home = + "$place/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($home = + "$place/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + ($release_home = $home) =~ s,Packages.gz,Release,; + ($release_localfile = $localfile) =~ s,Packages.gz,Release,; + if (-e "$home") { + my ($lmtime) = (stat($home))[9]; + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $size = $ftp->size("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + utime(time,$rmtime,$home); + } + } + else { + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $size = $ftp->size("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + if (-e $home) { + utime(time,$rmtime,$home); + } + } + ########### + # RELEASE # + ########### + # this will not be very verbose + if ((-e "$release_home" && $section ne "non-US") && + (-e $release_home && $distb !~ /non-US|experimental/)) { + my ($lmtime_r) = (stat($release_home))[9]; + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + if ($lmtime_r < $rmtime_r) { + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home); + } + } + elsif ((!-e "$release_home" && $section ne "non-US") && + (!-e $release_home && $distb !~ /non-US|experimental/)) { + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home) if -e $release_home; + } + } + } # if defined Packages + + ################################ + # NOT --CONTENTS && --PACKAGES # + ################################ + if ((!defined $commands->{"Contents"} && + !defined $commands->{"Packages"}) || defined $Go_on) { + my ($home,$localfile,$release_home,$release_localfile); + my $nue = (split(m,/,,$dist))[0]; + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($home = + "$default_directory/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($home = + "$default_directory/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($home = + "$default_directory/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + $section ne "single" && $distb !~ /non-US|experimental/ + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_dists_" . + "$dist" . "_" . "$section" . "_" . "binary-$arch" . + "_" . "Packages.gz") + : $nue eq "project" + ? ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . + "_" . "Packages.gz") + : ($localfile = + "$default_directory/partial/$the_site" . "_" . "$distb" . "_" + . "$nue" . "_" . "binary-$arch" . "_" . "Packages.gz"); + ($release_home = $home) =~ s,Packages.gz,Release,; + ($release_localfile = $localfile) =~ s,Packages.gz,Release,; + if (-e "$home" && !$commands->{"Release_only"} && + !defined $Go_on) { + my ($lmtime) = (stat($home))[9]; + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $size = $ftp->size("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + if ($lmtime < $rmtime || $lmtime > $rmtime) { + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $lsize = (stat($localfile))[7]; + my $complete = $ftp->code(); + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + utime(time,$rmtime,$home); + } + } + elsif (!-e "$home" && !$commands->{"Release_only"} && + !defined $Go_on ) { + my $remotefile; + $section ne "single" + ? ($remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Packages.gz") + : ($remotefile = "$distbase/$dist/Packages.gz"); + my $size = $ftp->size("$remotefile"); + my $rmtime = $ftp->mdtm("$remotefile"); + my $file_exist = $ftp->code(); + five50($file_exist,$section,$arch,$dist,$distb); + next if $file_exist == 550; + download($file_exist,$section,$arch,$dist,$distb,$size); + get($ftp,$remotefile,$localfile); + my $complete = $ftp->code(); + my $lsize = (stat($localfile))[7]; + two26($complete,$size,$lsize,$home,$localfile, + $section,$arch,$dist,$distb); + if (-e $home) { + utime(time,$rmtime,$home); + } + } + ########### + # RELEASE # + ########### + # this will not be very verbose + if ((-e "$release_home" && $section ne "non-US") && + (-e $release_home && $distb !~ /non-US|experimental/)) { + my ($lmtime_r) = (stat($release_home))[9]; + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + if ($lmtime_r < $rmtime_r) { + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home); + } + } + elsif ((!-e "$release_home" && $section ne "non-US") && + (!-e $release_home && $distb !~ /non-US|experimental/)) { + my $remotefile = + "$distbase/dists/$dist/$section/binary-$arch/Release"; + my $rmtime_r = $ftp->mdtm("$remotefile"); + my $size_r = $ftp->size("$remotefile"); + my $file_exist_r = $ftp->code(); + five50_r($file_exist_r,$section,$arch,$dist); + next if $file_exist_r == 550; + get($ftp,$remotefile,$release_localfile); + my ($lsize_r) = (stat($release_localfile))[7]; + my $complete = $ftp->code(); + two26_r($complete,$size_r,$lsize_r,$release_home, + $release_localfile,$section,$arch,$dist); + utime(time,$rmtime_r,$release_home) if -e $release_home; + } + } # if !defined Contents && Packages + $sectcount++; + } + #undef $distb; + } + } # same site by architecture + $ftp->quit(); + my $good_bye = $ftp->code(); + print "swim: logged out\n" if $good_bye == 221; + } # foreach site + + + +} # end sub ftp + +# Packages printout for ftp 550 error +sub five50 { + + + my ($file_exist,$section,$arch,$dist,$distb) = @_; + + if ($file_exist == 550) { + my @distp = split(m,/,,$dist); + print "swim: $dist/$section/binary-$arch/Packages.gz does not exist on the server\n" + if $section ne "single"; + print "swim: $dist/Packages.gz does not exist on the server\n" + if $section eq "single" && $distb !~ /non-US/; + print "swim: $distp[0]/non-US/$distp[1]/Packages.gz does not exist on the server\n" + if $distb =~ /non-US/ && $section !~ "non-US"; + } + +} #end sub five50 + +# error check for Release file +sub five50_r { + + my ($file_exist,$section,$arch,$dist) = @_; + + if ($file_exist == 550) { + print "swim: $dist/$section/binary-$arch/Release does not exist on the server\n"; + } + +} # end sub five50_r + + +# this marks the beginning of the download +sub download { + + my ($file_exist,$section,$arch,$dist,$distb,$size) = @_; + + if ($file_exist != 550) { + my @distp = split(m,/,,$dist); + print "swim: downloading $dist/$section/binary-$arch/Packages.gz ($size)\n" + if $section ne "single"; + print "swim: downloading $dist/Packages.gz ($size)\n" + if $section eq "single" && $distb !~ /non-US/; + print "swim: downloading $distp[0]/non-US/$distp[1]/Packages.gz ($size)\n" + if $distb =~ /non-US/ && $section !~ "non-US"; + } + +} # end sub download + + + +# Packages printout for ftp 226 success and the correct size +sub two26 { + + my ($complete,$size,$lsize,$home,$localfile,$section,$arch,$dist,$distb) + = @_; + + if ($complete == 226 && $size == $lsize) { + my @distp = split(m,/,,$dist); + print "swim: successful retrieval of $dist/$section/binary-$arch/Packages.gz\n" + if $section ne "single"; + print "swim: successful retrieval of $dist/Packages.gz\n" + if $section eq "single" && $distb !~ /non-US/; + print "swim: successful retrieval of $distp[0]/non-US/$distp[1]/Packages.gz\n" + if $distb =~ /non-US/ && $section !~ "non-US"; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + my @distp = split(m,/,,$dist); + print "swim: unsuccessful retrieval of $dist/$section/binary-$arch/Packages.gz\n" + if $section ne "single"; + print "swim: unsuccessful retrieval of $dist/Packages.gz\n" + if $section eq "single" && $distb !~ /non-US/; + print "swim: unsuccessful retrieval of $distp[0]/non-US/$distp[1]/Packages.gz\n" + if $distb =~ /non-US/ && $section !~ "non-US"; + } + +} # end sub two26 + + +# check download of Release file +sub two26_r { + + my ($complete,$size,$lsize,$home,$localfile,$section,$arch,$dist) = @_; + + if ($complete == 226 && $size == $lsize) { + #print "swim: successful retrieval of $dist/$section/binary-$arch/Packages.gz\n"; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + } + else { + print "swim: unsuccessful retrieval of $dist/$section/binary-$arch/Packages.gz\n"; + } + +} # end sub two26_r + +sub make_dir { + + my ($what) = @_; + + if (!-e $what) { + my @DRD = split(m,/,,$what); + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + mkdir("$placement",$permission) + or warn "swim: could not create $what\n"; + } + } + + +} # end sub make_dir + +1; diff --git a/lib/Compare.pm b/lib/Compare.pm new file mode 100644 index 0000000..58675f4 --- /dev/null +++ b/lib/Compare.pm @@ -0,0 +1,358 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Compare; +use strict; +use SWIM::Conf qw($dpkg); +use SWIM::Library; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(comparison compare_versions); + +# comparison function and checking function (-v) for not-installed databases + +=pod + +DEVELOPMENTAL + +This uses the comparison method mentioned in the packaging manual. It +will look for an epoch *: or the absence, and a revision -* or the +absence. First the epoch is compared, then the upstream-version, than +the debian-revision. The sub will stop and return a value as soon as +a difference is found. A look in the dpkg attic helped out (compare_vnumbers) +here, but lib.pl used separate subs, and doesn't appear to check for +an epoch separately, ofcourse there may have not been an epoch. This +uses the special variable $&, but apparently this isn't as big a waste +of resources in later versions of Perl, but there will be some +experiments and benchmarks for alternatives in the future for this sub. +There some rules built into comparison() to deal with patch to non-patch, +more than one hyphen (-). This involves a little transformation. +You can verify that this sub is working by doing perl -e '$five =\ +system "dpkg --compare-versions 10 gt 1.0.17"; print "nop\n" if $five\ +== 256; print "yes\n" if $five == 0', take a look at the scripts, too. +Also, use -v (compare_versions()) when using --initndb or --rebuildndb +for a report. + +=cut + +sub comparison { + + # $pversion = version from Packages.gz + # $eversion = version from nstatusindex-arch-dist.deb + + my($pversion,$eversion) = @_; + my($epoch, $upstream, $revision); + my($eepoch, $eupstream, $erevision); + my($revisiond,$erevisiond); + my $result; + + # If the two versions "eq" one another no reason to go on + if ($pversion ne $eversion) { + + # check epoch first, go on if the same + ######### + # EPOCH # + ######### + if ($pversion =~ /:/ || $eversion =~ /:/) { + if ($pversion =~ /:/) { + ($epoch,$upstream) = split(/:/,$pversion,2); + } + else { + $epoch = 0; $upstream = $pversion; + } + if ($eversion =~ /:/) { + ($eepoch,$eupstream) = split(/:/,$eversion,2); + } + else { + $eepoch = 0; $eupstream = $eversion; + } + do { + + $epoch =~ s/^\d*//; my $epochd = $&; + $eepoch =~ s/^\d*//; my $eepochd = $&; + $result = $epochd <=> $eepochd; + return "<" if $result == -1; + return ">" if $result == 1; + + } while (length ($epoch) && length ($eepoch)); + #return length ($a) cmp length ($b); + } # end if epoch + else { + $epoch = 0; $upstream = $pversion; + $eepoch = 0; $eupstream = $eversion; + } + + # Check the upstream-revision next + ##################### + # UPSTREAM-REVISION # + ##################### + if ($upstream || $eupstream) { + # we need to run a little test in case hyphens exists more than once + if ($upstream =~ /-/) { + my $hyphen = ($upstream =~ tr/-//); + if ($hyphen > 1) { + $upstream =~ m,(^.*)-(.*$),; + $upstream = $1; + $revision = $2; + } + else { + ($upstream,$revision) = split(/-/,$upstream,2); + } + } + else { + # because the absence is considered earlier, and the convention + # is to use -1. + $revision = 0; + } + # we need to run a little test in case hyphens exists more than once + if ($eupstream =~ /-/) { + my $hyphen = ($eupstream =~ tr/-//); + if ($hyphen > 1) { + $eupstream =~ m,(^.*)-(.*$),; + $eupstream = $1; + $erevision = $2; + } + else { + ($eupstream,$erevision) = split(/-/,$eupstream,2); + } + } + else { + # because the absence is considered earlier, and the convention + # is to use -1. + $erevision = 0; + } + do { + # letters + $upstream =~ s/^\D*//; my $upstreamd = $&; + $eupstream =~ s/^\D*//; my $eupstreamd = $&; + + # hopefully this handles nasty beta situations + if ($upstreamd eq "b" and $eupstreamd eq "." ) { + return "<"; + } + elsif ($upstreamd eq "." and $eupstreamd eq "b" ) { + return ">"; + } + elsif ($upstreamd eq "beta" and $eupstreamd eq "." ) { + return "<"; + } + elsif ($upstreamd eq "." and $eupstreamd eq "beta" ) { + return ">"; + } + elsif ($upstreamd eq "." and $eupstreamd eq "-pre-") { + return ">"; + } + elsif ($eupstreamd eq "." and $upstreamd eq "-pre-") { + return "<"; + } + + # solves problems when "." is compared to letters, and also a weird + # case involving a patched version changing to a non-patched version. + if ($upstreamd =~ /\./) { + if ($eupstreamd =~ /\w/) { + if ($eupstreamd =~ /pl/ && $upstreamd !~ /pl/) { + $eupstreamd = ""; + } + elsif ($upstreamd !~ /\.\w{2,10}/) { + $eupstreamd = "."; + } + } + elsif ($eupstreamd eq "") { + $eupstreamd = "."; + } + } + # the weird -pre situation + elsif ($upstreamd =~ /-pre/ || $eupstreamd =~ /-pre/) { + $upstreamd = ""; $eupstreamd = ""; + } + + if ( $eupstreamd =~ /\./) { + if ($upstreamd =~ /\w/) { + if ($upstreamd =~ /pl/ && $eupstreamd !~ /pl/) { + $upstreamd = ""; + } + elsif ($upstreamd !~ /\.\w{2,10}/) { + $upstreamd = "."; + } + } + elsif ($upstreamd eq "") { + $upstreamd = "."; + } + } + # the weird -pre situation + elsif ($upstreamd =~ /-pre/ || $eupstreamd =~ /-pre/) { + $upstreamd = ""; $eupstreamd = ""; + } + + $result = $upstreamd cmp $eupstreamd; + return "<" if $result == -1; + return ">" if $result == 1; + # it's importantant to realize that . & + are being checked for + # above. : and - have already been dealt with. cmp seems to deal with + # these characters with no problems. + + + # numbers + + # found a little problem with <=> when number's eq "", + # but this doesn't effect cmp. + if ($upstream eq "") { + if ($eupstream eq ".") { + $upstream = "."; + } + else { + $upstream = 0; + } + } + if ( $eupstream eq "") { + if ($upstream eq ".") { + $eupstream = "."; + } + else { + $eupstream = 0; + } + } + + $upstream =~ s/^\d*//; $upstreamd = $&; + $eupstream =~ s/^\d*//; $eupstreamd = $&; + $result = $upstreamd <=> $eupstreamd; + return "<" if $result == -1; + return ">" if $result == 1; + } while (length ($upstream) || length ($eupstream)) + } # end if upstream + else { + $revision = 0; + $erevision = 0; + } + + # Finally, check the revision + ############ + # REVISION # + ############ + if ($revision || $erevision) { + do { + # letters + $revision =~ s/^\D*//; $revisiond = $&; #$revisiond =~ s/\W/ /g; + $erevision =~ s/^\D*//; $erevisiond = $&; #$erevisiond =~ s/\W/ /g; + + # pre in the revision + if ($revisiond eq "." and $erevisiond eq "pre") { + return "r>"; + } + elsif ($erevisiond eq "." and $revisiond eq "pre") { + return "r<"; + } + $result = $revisiond cmp $erevisiond; + return "r<" if $result == -1; + return "r>" if $result == 1; + # it's importantant to realize that . & + are being checked for + # above. : and - have already been dealt with. cmp seems to deal with + # these characters with no problems. + + # numbers + # found a little problem with <=> when number's eq "", + # but this doesn't effect cmp. + if ($revision eq "") { + if ($erevision eq ".") { + $revision = "."; + } + else { + $revision = 0; + } + } + if ( $erevision eq "") { + if ($revision eq ".") { + $erevision = "."; + } + else { + $erevision = 0; + } + } + + $revision =~ s/^\d*//; $revisiond = $&; + $erevision =~ s/^\d*//; $erevisiond = $&; + $result = $revisiond <=> $erevisiond; + return "r<" if $result == -1; + return "r>" if $result == 1; + } while (length ($revision) && length ($erevision)); + } # end if revision + + # still 0? check the remainder..this is just for letters which may have + # been mulled over because they looked like words \w. + if ($result == 0) { + $result = $epoch cmp $eepoch || $upstream cmp $eupstream || + $revision cmp $erevision; + return "<" if $result == -1; + return ">" if $result == 1; + } + } + +} # end sub comparison + + +# This produces a report to make sure that comparison() is up to par, and +# is called with -v. It uses dpkg's --compare-versions. The advantage of +# not normally running --compare-versions is portability. People using +# other distribution's don't need dpkg installed, and people using weird +# Oses who can't use dpkg can still explore a virtual installation. +sub compare_versions { + + # The test result is put in .version_compare + + # $result = operand (result from comparison) + # $virtual = version from Packages.gz + # $installed = version from nstatusindex-arch-dist.deb + # $name = packagename + # $commands = options + + my ($result, $virtual, $installed, $name, $commands) = @_; + my %commands = %$commands; + my ($cv, $cv_result, $cresult); + my $place = finddb(\%commands); + + # usually it will be greater + if (defined $dpkg) { + $cv = system "$dpkg", "--compare-versions", "$virtual", "gt", "$installed"; + + $cv_result = "no" if $cv == 256; + $cv_result = "yes" if $cv == 0; + #$cresult = "no" if $result =~ m,[r]?<,; + #$cresult = "yes" if $result =~ m,[r]?>,; + $cresult = "no" if $result eq "<" || $result eq "r<"; + $cresult = "yes" if $result eq ">" || $result eq "r>"; + + open(CV,">>$place/.version_compare") + or warn "couldn't create version compare report\n"; + if ($cresult eq "yes" && $cv_result eq "no") { + print CV "$name:\ndpkg - $virtual < $installed\nswim - $virtual > $installed\n\n"; + } + elsif ($cresult eq "no" && $cv_result eq "yes") { + print CV "$name:\ndpkg - $virtual > $installed\nswim - $virtual < $installed\n\n"; + } + else { + return; + } + close(CV); + } + +} # end sub compare_versions + + + +1; diff --git a/lib/Conf.pm b/lib/Conf.pm new file mode 100644 index 0000000..657da30 --- /dev/null +++ b/lib/Conf.pm @@ -0,0 +1,672 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Conf; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); + +@EXPORT = qw($my_number $tmp $architecture $distribution @user_defined_section + $default_directory $default_root_directory $permission $dpkg + $dpkg_deb $ar $gcc $apt_get $apt_cache $sources @FTP $spl $cat + $sort $md5sum $zcat $tar $grep $gzip $fastswim $slowswim $longswim + $mount $umount $mke2fs $copy $pager $base $pwd $parent $library + $splt $mv $imswim $swim_conf $debug $port $timeout + $firewall $passive $apt_sources $HISTORY $alt); +%EXPORT_TAGS = ( + Path => [ qw($tmp $parent $base $library) ], + Deb => [ qw($pwd $dpkg_deb $ar $tar $grep $tmp $md5sum $cat $mv) ], + Qftp => [ qw($default_root_directory $permission @FTP + $default_directory $swim_conf) ], + Info => [ qw($parent $base $zcat) ] + ); + + + +############################# +# DEFAULT PROGRAM VARIABLES # +############################# + +# You can change this to how many lines you would like "swim -qf <>" to +# print out, before asking for -t or --total, it will automatically ask +# though, if there is more than one package and you used the option -i. +# Remember -t can be used with --scripts family members to view the +# title of the script file regardless of this setting, and if -t has to be +# used, the titles will be displayed, which makes sense. +$my_number = 23; + +# Just like a shell, you can keep a history of whatever length you want. +$HISTORY = 10; + +# For not-installed: +# This part supplies the default value for --arch. +# +# You can determine the default architecture used when -n is +# called or a not-installed database is made. Architectures are always +# being added so check with Debian to find a list. There is alpha, arm, +# hurd (alternative kernel to linux), i386, m68k, powerpc, sparc. Just use +# the arch found after the hyphen in the Contents-(arch) file. +$architecture = "i386"; + +# For not-installed: +# This part supplies the default value for --dists. +# +# The default distribution can be either stable, unstable, frozen, or +# experimental (rare). These represent the state of development that the +# packages are under. The unstable distribution can have lot's of changes +# within a very short time period, and frozen may or may not be available. +$distribution = "unstable"; + + +#For not-installed: +#This part supplies the default value for --main, --contrib, --non-free, +#and --non-us. + +# Distributions are divided into the sections. These sections are called +# distributions in the version 2.4.1.0 packaging manual, because they were at +# one time separate distributions, but this has since changed. You can +# determine which of these sections (main, non-free, contrib or non-US) to +# pull out of the Contents file if you don't want to use --main, --contrib, +# --non-free, and --non-us to selectively pick sections. Basically, whatever +# you pull out should match the Package(s) file(s) you are targetting, this +# program is friendly if you make a mistake, but it's more effecient to pull +# out just what you want. If the same package happens to exist in two +# different sections, main and non-us for example (which is really a +# situation that shouldn't exist, yet it does), you will still be able to +# find this package in the non-us group, but its section and locations will be +# the one which main recognizes assuming that you use the order in the example +# below. + +# Setting it up: +# Example: You just want to pull out main and contrib every time you run +# --initndb, --rebuildndb, or --ndb. +# @user_defined_section = qw(main contrib non-US); +# remember "non-US" not "non-us". + +# untill non-US is fixed the second is better +#@user_defined_section = qw(main contrib non-free non-US); +@user_defined_section = qw(main contrib non-free); + +# Usually, this is +$alt = "debian"; + +################ +# DF LOCATION # +################ + +# A little philosophy: +# swim was developed for maximum versatility, so whether you are just +# interested in researching, and keeping tabs on the newest packages, +# or maintaining a Debian virtual distribution on a non-Debian real +# distribution, or you are a using swim for distribution development, swim +# provides a way. The default directory (DF - which can also mean +# directory/file) keeps track of Contents and Packages files downloaded +# using --ftp, and gives the files names specific to the distribution and +# architectures they represent. But, you also have the freedom not to use +# the default directory in this case swim will still do the renaming and +# keeping track of the mtime, but you will have to remember where you put +# the files. On the other hand, if you use apt, you won't even have to use +# the DF directory for Packages files because you can get the ones specific +# to your own systems architecture from apt, but if you want to look at +# other architectures you will need to use the DF directory or one of your +# own choice. +# Naming Convention: Contents = Contents-dist.gz +# Packages = Packages-arch-dist-section.gz +$default_directory = '/root/.swim'; + + +# The default root directory is the key to easy management of packages +# downloaded through --ftp and --file, and provides an easy way to put together +# a personalized distribution. Future implementations of swim will provide +# a distribution called personal..Packages and Contents files specific to +# this distribution will automatically be made. This directory can be a +# real ftp site on your computer, or put where ever else you are allowed +# to have directories. dists/distribution/section/architecture/subject will be +# placed above this directory. No matter what, debian must be the final +# directory before dists. Other distributions are placed alongside debian, +# like debian-non-US or personal. +# Feel free to change the permissions. This directory is above your default_ +# directory. +$default_root_directory = '/pub/debian'; + +# Because you may be using a real ftp site, this configuration allows you +# to determine what permissions swim will set for directories it creates +# above the default root directory. +$permission = '0755'; + + +############### +# AR or DPKG? # +############### + +# NOTE: users set these next two with the $package_tool variable. + +# packaging friends dpkg and dpkg-deb come from the essential and +# required dpkg package. ar from the package binutils can also be used (below). +# This is the archival program used for deb packages, but binutils is just +# a standard non-essential package, and the ar capabilities are built into +# dpkg-deb, and it's better not to assume that the standard packages are +# even established, yet. +$dpkg = (); +$dpkg_deb = (); + + +# If you don't have the dpkg package on your system then you can use ar +# from the package binutils. This would be a standard, but not an essential +# package in Debian, but this package is also fairly standard amongst all +# distributions, and can even be found in the free djgpp for M$ Oses. +# Since people who have both dpkg and ar may want to try the ar method, +# rather than creating an automatic check, just assign a value to either +# ($dpkg & $dpkg_deb) or just $ar. +#my $ar = '/usr/bin/ar'; # same for RH +$ar = '/usr/bin/ar'; + + +####### +# APT # +####### + +# NOTE: users set apt-get and apt-cache with the $apt variable + +# If you have apt you are in luck. +$apt_get = (); +$apt_cache = (); +$sources = '/etc/apt/sources.list'; +$apt_sources = '/var/state/apt/lists'; + +######### +# PAGER # +######### + +# less is a nice pager, unless you like more! There is an option +# --nopager or -n. Pager is used for --help and swim called without any +# options. more comes from the required package util-linux, whereas +# less comes from a standard package called less. In the future there is +# a possiblity that a large percentage of swim may use an internal pager. +# less, more, or most or... +#$ENV{PAGER} = "/usr/bin/less"; # same RH +$ENV{PAGER} = "less"; +$pager = $ENV{PAGER}; + + + +################# +# SWIM PROGRAMS # +################# + +# This is replaced by the Makefile. +$pre="/usr"; + +# This is the hash making program fastswim. +$fastswim = "$pre/lib/SWIM/fastswim"; + +# imswim in an alternative to fastswim for --lowmem +$imswim = "$pre/lib/SWIM/imswim"; + +# This is the low memory program slowswim. +$slowswim = "$pre/lib/SWIM/slowswim"; + +# This is the dir/file making program longswim. +$longswim = "$pre/lib/SWIM/longswim"; + +############ +# TEMP DIR # +############ + +# If you want to set an alternative directory for the temporary files +# created when the databases are made, change here. You may want to make +# $tmp a RAM disk. See package loadlin for initrd documentation and an +# explanation for making such a disk. There is also +# /usr/src/kernel-source.version/Documentation. Whether this will speed +# things up is a subject of experimentation. +$tmp = '/tmp'; + +################## +# MAIN CONFFILES # +################## + +# if configuration files are not kept in /etc change this +# and set up the directories by hand. + +$swim_conf = '/etc/swim'; + + +############# +# UTILITIES # +############# + + +# This probably never will have to be changed. +$pwd = `pwd`; +chomp $pwd; + +# If the command split is somewhere else besides /usr/bin change this. +# The required package textutils provides this. +#my $splt = '/usr/bin/split'; # same RH +$splt = 'split'; + +# cat comes from the essential and required package textutils. +#my $cat = '/bin/cat'; # same RH +$cat = 'cat'; + +# This command also omes from the required and essential package textutils. +#my $sort = '/usr/bin/sort'; # same RH +$sort = 'sort'; + +# This program uses md5sum from the dpkg package, it can also use md5sum +# from the RH package. +#my $md5sum = '/usr/bin/md5sum'; # same RH +$md5sum = 'md5sum'; + +# If you want to view compressed files make sure this is correct. +# The required package gzip provides this. +#my $zcat = '/bin/zcat'; # same RH +$zcat = 'zcat'; + +# tar comes from the essential and required package tar. +#my $tar = '/bin/tar'; # same RH +$tar = 'tar'; + +# grep comes from the essential and required package grep. This seems +# to require a path. +$grep = '/bin/grep'; # same RH + +# gzip comes from the essential and required package gzip. +#my $gzip = "/bin/gzip"; # same RH +$gzip = "gzip"; + +# mount comes from the essential and required package mount. +#my $mount = '/bin/mount'; # same RH +#my $umount = '/bin/umount'; # same RH +$mount = 'mount'; +$umount = 'umount'; + +# If your file system isn't an ext2 filesystem, you may want to change +# this. mke2fs comes from the essential and required package e2fsprogs. +#my $mke2fs = '/sbin/mke2fs'; # same RH +$mke2fs = 'mke2fs'; + +# cp and mv from the essential and required package fileutils +#my $copy = '/bin/cp'; # same RH +$copy = 'cp'; +$mv = 'mv'; + +# Your system definitely has gcc if you have ar. gcc is a standard package +# in debian. +$gcc = 'gcc'; + + +###### +# FTP # +####### + +# Major mode --ftp and --file automates the download of Contents and Packages +# files. Even if you have apt installed, you may still want to download Packages +# from alternative architectures, and the Contents file for your own architecture +# or other architectures. If you want virtual and/or -ld capabilities you need +# the Contents file. You specify a list of ftp or file sites using urls (like +# apt). For your system's architecture specify the type deb, for other +# architectures specify deb(hyphen)architecture (ex: deb-alpha). Regardless of +# whether or not you specify an architecture, deb implies /dist* found under the +# base directory specified by the ftp url, except in the case of experimental, +# and to a degree non-us. minor mode --ftp, and --file will use the sites in this +# configuration as well, on a fifo (first in first out) basis, so choose the +# order of sites based on which are closest, most current, as well as fast. + +# IMPORTANT: It is a BIG MISTAKE to use the distributions name (slink,po,etc) +# anywhere in the sources list, or in swim's configuration file..in fact swim +# won't work properly, not to mention the fact that someday your favorite name +# will suddenly disappear. This is because swim thinks in terms of the real +# distribution name (stable,unstable,frozen, experimental). The problem goes +# like this - slink remains slink, but goes from unstable to frozen to stable. +# At first, using the distributions alias may seem appropriate, but the +# purpose of swim is to keep tabs on the dists, and not to ignore changes in +# the states, this also makes managing swim's databases much easier and +# intuitive...more about this later. + +# Fun experiments: Swim uses the naming conventions of apt, but leaves the +# Package files compressed in the DF directory. So you can always decompress +# the databases and move them to /var/state/apt/lists. This ofcourse assumes +# that the appropriate changes to the sources.list reflecting these Packages +# (need to be the same architecture as your system) existed before you +# update. (author needs to do this experiment :*) + +$ftp1 = "deb ftp://localhost/pub/debian unstable main contrib non-free non-US"; +$ftp2 = "deb ftp://localhost/pub/debian unstable main contrib non-free"; +$ftp3 = "deb ftp://localhost/pub/debian project/experimental/"; +@FTP = ($ftp1,$ftp2,$ftp3); + +# These next variables allow some characteristics of the ftp client +# to be altered. See Net::FTP for ways of altering some of these +# variables through the environment. + +$firewall = 0; +$port = 0; +$timeout = 120; +$debug = 0; +$passive = 0; + + +######################################## +# STUFF THAT NEVER NEEDS TO BE CHANGED # +######################################## + +# You will never need to change this unless for some weird reason all the +# files under dpkg are somewhere else (including /info*) , see --dbpath as +# an alternative if you decide to access or make the databases somewhere +# else. +$base = '/var/lib/dpkg'; + +# --dbpath takes care of this so don't touch. +$parent = '/'; +$library = '/var/lib/dpkg'; + + +############################# +# LOAD CUSTOM CONFIGURATION # +############################# + + +# Here we load in the customized configuration which override the defaults +# Might as well use do, let the world learn Perl ... compare this to apt's +# configuation file with scopes. Swim's sources.list file (/etc/swim/swimz.list), +# will be grabbed at SWIM::Apt and SWIM::Qftp if it exists. + +do "$swim_conf/swimrc"; +do "$ENV{HOME}/.swim/swimrc"; +if ((defined $dpkg && !defined $dpkg_deb) || + (!defined $dpkg && defined $dpkg_deb)) { + print "swim: need to give both \$dpkg and \$dpkg_deb a value if you want dpkg\n"; + exit; +} +if (defined $package_tool) { + if ($package_tool =~ /ar/) { + $ar = $ar; + } + else { + $dpkg = 'dpkg'; + $dpkg_deb = 'dpkg-deb'; + undef $ar; + } +} +if (defined $apt) { + $apt_get = 'apt-get'; + $apt_cache = 'apt-cache'; +} + + +############################### +# MAKE ANY NEEDED DIRECTORIES # +############################### + +# make sure all the appropriate directories are made +if (!-d $default_directory) { + if (-e $default_directory) { + print "swim: can not create default directory because a file exists\n"; + exit; + } + my @DRD = split(m,/,,$default_directory); + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + -d $placement or mkdir("$placement",0755); + } +} + +if (!-d "$default_directory$default_root_directory") { + my @DRD = split(m,/,,$default_root_directory); + print "swim: debian must be the final directory before dists\n" + if $DRD[$#DRD] ne "debian"; + exit if $DRD[$#DRD] ne "debian"; + my $placement = "/"; + for (1 .. $#DRD) { + $_ == 1 ? ($placement = "/$DRD[$_]") + : ($placement = $placement . "/" . $DRD[$_]); + unless (-d "$default_directory$placement") { + mkdir("$default_directory$placement",0755) + or die "swim: could not create root default directory\n"; + } + } +} + +# Makefile will make sure these directories exist, unless for some strange +# reason you have to change them. + +if (!-d $library) { + mkdir($library,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $base) { + mkdir($base,0755) or die "Couldn't create default directory\n"; +} + +if (!-d $swim_conf) { + mkdir($swim_conf,0666) or die "Couldn't create configuration file directory, + please make the directories which are needed.\n"; +} + +1; + +__END__ + +=head1 NAME + +swimrc - swim configuration file + +=head1 DESCRIPTION + +B is the configuartion file for swim allowing many default values +to be set so that they do not have to be mentioned on the command line. +Swimrc interacts directly with Perl allowing a wide variety of variables +found in B to be altered. + +=cut + +=head1 USAGE + +Values for variable can be altered for B by assigning different +values enclosed in quotes or quoted whitespace (qw()), and ended with a +semi-colon. + + $variable = "value"; + $variable = "qw(value1 value2 ..)"; + +=head1 VARIABLES + +This is a list of variables with explanations. The default values for +B are shown. + +=head2 OUTPUT VARIABLE + +$my_number can be changed to how many lines you would like "swim -qf <>" +to print out, before the program asks for C<-t> or C<--total>. Exception: +If C<-i> is used in the query and there is more than one package then the +total will be presented. + +Hint: C<-t> can be used with all the various C<--scripts> family members +to view the title of the script file regardless of this variable setting, +and if C<-t> has to be used, the titles will be displayed, which makes +sense. + +B<$my_number = 23;> + +=head2 HISTORY + +This is a shell-like history kept in relation to searches and the most +recent edit when C<--stdin> is used. + +B<$HISTORY = 10;> + +=head2 AR or DPKG? + +Debian packages are ar archives. If you are using a Debian Distribution +assign "dpkg" to $package_tool, otherwise assign "ar" to $package_tool. + +B<$package_tool = "/usr/bin/ar";> + +=head2 APT + +B does not assign a value for apt. To use C<--apt> and C<-xyz> +assign $apt the value "yes". + +Example: B<$apt = "yes";> + +=head2 PAGER + +less is a nice pager, unless you like more! Pager is used for C<--help> +and B called without any options. There is an option C<--nopager> or +C<-n>. more comes from the required package util-linux, whereas less +comes from a standard package called less. Values: "less", "more", or +"most" or... + +B<$ENV{PAGER} = "less";> + +=head2 NOT-INSTALLED VARIABLES + +Assign values for $architecture and/or $distribution to avoid having to +use C<--arch> and C<--dists> everytime the not-installed databases are +accessed with C<-n> or made or altered. + +Architectures are always being added so check with Debian to find a list. +There is I. Just use the arch found after the hyphen in the +Contents-(arch) file. + +B<$architecture = "i386";> + +The distribution can be either I. These represent the state of development that the packages are +under. The unstable distribution can have lot's of changes within a very +short time period, and frozen may or may not be available. + +B<$distribution = "unstable";> + +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at one time separate distributions, but this has since changed. + +You can determine which of the sections I to pull out of the Contents file if you don't want to use +C<--main>, C<--contrib>, C<--non-free>, and C<--non-us> to selectively +pick the sections. + +For efficiency, you should choose the sections which you will be pulling +out of the Packages file(s) being targetted. + +Rule: Use "non-US" not "non-us". + +B<@user_defined_section = qw(main contrib non-free non-US);> + +=head2 DF LOCATION + +A little philosophy: B was developed for maximum versatility, so +whether you are just interested in researching, and keeping tabs on the +newest packages, or maintaining a Debian virtual distribution on a +non-Debian distribution, or you are a using B for distribution +development, B provides a way. + +The next two variables determine the location of the DF (default +directory/file system) + +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release +file are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim will still do the renaming and keeping track of the mtime, but you +will have to remember where you put the files. + +B<$default_directory = '/root/.swim';> + +The default root directory (DRD) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be a real ftp site on your computer, or put wherever else you are +allowed to have directories. The DRD is always placed below the value +assigned to $default_directory. According to the previous assignment to +$default_directory, if the DRD is "/pub/a/debian" then the full path +would be "/root/.swim/pub/a/debian". + +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the DRD. + +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-US or +personal (specialized distribution). + +B<$default_root_directory = '/pub/debian';> + +Because you may be using a real ftp site, this variable allows you to +determine what permissions B will assign for directories it creates +below the DRD. + +B<$permission = '0755';> + +=head2 TEMPORARY DIRECTORY + +If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +$tmp a RAM disk. See package loadlin for initrd documentation and an +explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. + +B<$tmp = "/tmp";> + +=head2 FTP + +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in Net::FTP(3pm) by providing +arguments to these variables. All variables but $timeout are set to untrue +by default. + + $firewall = 0; (FTP firewall machine name) + $port = 0; (defaults to 23) + $timeout = 120; (120 seconds) + $debug = 0; (1 will turn on STDERR) + $passive = 0; (1 will enable) + +=head1 OTHER VARIABLES + +see SWIM::Conf + +=head1 FILES + + /etc/swim/swimrc + ~/.swim/swimrc + +=head1 SEE ALSO + +swim(8), Net::FTP(3pm) + +=head1 BUGS + +Send directly to mttrader@access.mountain.net. + +=head1 AUTHOR + +Jonathan D. Rosenbaum + +=head1 COPYRIGHT + + +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +=cut diff --git a/lib/DB.pm b/lib/DB.pm new file mode 100644 index 0000000..6df4a18 --- /dev/null +++ b/lib/DB.pm @@ -0,0 +1,947 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::DB; +use strict; +use SWIM::DB_Library qw(:Db); +use SWIM::Format; +use SWIM::Conf qw(:Path); +use SWIM::Global; +use vars qw(@ISA @EXPORT_OK); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(db rebuildflatdb); + + +# --db --rebuildflatdb db() rebuildflatdb() + +# The goal here is to save some time by just updating the database rather +# than rebuilding it. Generally, though, swim -i would be the +# favorable way of doing this, and ultimately may become the primary way of +# setting up the databases after the required packages for this program are +# set-up. This is because --db has to check the status file, whereas -i +# uses statusindex.db, and grabs package information right from the +# package, there are exceptions to this, certain things like the status +# will have to be found from the status file or some other method. +sub db { + + # Well, we better check for any changes in the status file, before we + # attempt anything. This is made easy by the version reference hash created + # when --initdb or --rebuilddb is run, and then comparing this to the new + # results when --db is run. Only then will we process, add, and remove + # packages when we know what is gone, and what is new (whether its a + # new package name, or a package with a new version or older version). + # The statusindex.deb could be used for version checking, instead the + # important status field is compared, so if we have situations like + # "deinstall ok config-file" this will be recognized as a CHANGE. The + # update takes place so that the status field remain proper. + + my ($commands) = @_; + my %commands = %$commands; + + # description stuff + my (@description, @ldescription); + # my @dpackage; # not needed here + + # does status exist + my $the_status; + + # Keep track of changes to the status file + my $rootsky = "/."; + my @package; + my @name; + my $status; + my @changed_packages; + my @gone; + my (@GONE, @CHANGED, @NEW); + my @before; + my %compare; + + # The mys for NEW + my $count = 0; + # a special one to deal with package[1] version change. + my $packv; + my (@essential,$priority,$section,$installed_size,$maintainer,$source); + my (%group, $group); + + # Keeps a package->version database + # to save time over using status + my @status; + my ($replaces, $provides, $depends, $pre_depends, $recommends, $suggests, + $conflicts); + my (@conffiles,$line_before,@conf,@complete,@form,@formly); + my $format_deb = "$tmp/format.deb"; + + dbi(\%commands); ib(\%commands); sb(\%commands); + # Check differences now. + print "checking for new, changed, and removed packages\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + open(DIFFERENCE,"$parent$library/status"); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + open(DIFFERENCE,"$parent$base/status"); + } + while () { + # Package name + if (/^Package:/i) { + @package = split(/: /,$_); + chomp $package[1]; + } + elsif (/^Status:/) { + chomp; + $status = substr($_,8); + # a test + #if ($status eq "purge ok not-installed") { + # if (defined $db{$package[1]}) { + # print "$db{$package[1]}\n"; + # } + #} + } + # hold ok not-installed - may want to change this just to + # non-installed. + ########### + # VERSION # + ########### + elsif (/^Version:/ && $status !~ /not-installed/) { + my $version = $_; chomp $version; + my $ver = m,Version:\s(.*),; my $statusname; + if (defined $sb{$package[1]}) { + $statusname = (split(/\s/,$sb{$package[1]}))[3]; + $statusname =~ s/:/ /g; + } + ######## + # GONE # + ######## + if (defined $db{$package[1]}) { + push(@gone,"$package[1]_$1"); + if ("$package[1]_$1" ne $db{$package[1]}) { + $compare{$package[1]} = "$package[1]_$1"; + } + # Version remained the same, but status changed + # even though $statusname may be undefined..this + # routine is only done when it does exist. + ###### + # CR # + ###### + elsif ("$package[1]_$1" eq $db{$package[1]} && + $statusname ne $status) { + push(@changed_packages, "$package[1]"); + $compare{$package[1]} = "$package[1]_$1"; + } + } + ####### + # NEW # + ####### + elsif (!defined $db{$package[1]}) { + push(@NEW,$package[1]); + $compare{$package[1]} = "$package[1]_$1"; + push(@gone,"$package[1]_$1"); + } + } + } + close(DIFFERENCE); + + # lets find what existed before, ofcourse mistakes in /. better be + # taken care of beforehand, because this ignores those here. Some time + # may have been saved by using a separate database rather than /., but, + # this keeps things clean. + if ($ib{$rootsky}){ + @before = split(/\s/,$ib{$rootsky}); + my %tracker; + grep($tracker{$_}++,@gone); + my @goners = grep(!$tracker{$_},@before); + foreach (@goners) { + m,(^.*)_.*$,; + if (!defined $compare{$1}) { + push(@GONE,$1); + } + else { + # these will be process like @GONE for original, and @NEW for + # new + push(@CHANGED,$1); + } + } + } + else { + print "swim: missing important database\n"; exit; + } + + foreach (@GONE) { + print "GONE $_\n"; + } + foreach (@CHANGED) { + print "CHANGED $_\n"; + } + foreach (@changed_packages) { + push(@CHANGED,$_); + print "CHANGED STATUS $_\n"; + } + foreach (@NEW) { + print "NEW $_\n"; + } + + my $new=$#NEW + 1; my $cr=$#changed_packages + 1; + my $ch=($#CHANGED + 1) - $cr; my $gon= $#GONE + 1; + if ($commands->{"check"}) { + print "\n TOTAL\n -----\n"; + print "NEW $new\n"; print "GONE $gon\n"; + print "CHANGED $ch\n"; print "CHANGED STATUS $cr\n"; exit; + } + print "\n TOTAL\n -----\n"; + print "NEW $new\n"; print "GONE $gon\n"; + print "CHANGED $ch\n"; print "CHANGED STATUS $cr\n"; + + + @GONE = (@GONE,@CHANGED); + @NEW = (@NEW,@CHANGED); + + undef @before; # can use below. + untie %db; + undef %db; + untie %ib; + undef %ib; + + # Going to be adding some stuff to nsearchindex.deb and ndirindex.deb + # so better remove any compressed versions if they exist + if (defined @GONE || defined @NEW) { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/searchindex.deb") { + unlink("$parent$library/searchindex.deb.gz"); + unlink("$parent$library/dirindex.deb.gz"); + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/searchindex.deb") { + unlink("$parent$base/searchindex.deb.gz"); + unlink("$parent$base/dirindex.deb.gz"); + } + } + } + + + # Time for some fun stuff + # There are three states: GONE - all information about this package + # needs to be removed from the databases. NEW - all information about + # this package needs to be put in the databases. CHANGED - a + # combination of the two previous, information could be cross + # referenced and checked for changes, but it's probably no saving of + # time, so first remove information from the same package of a + # different version, then add the information about the package of the + # new version (older or newer) + + ############# + # # + # GONE # + # # + ############# + # GONE. (reverse applies to NEW) + # For package.deb - Delete description + # (packagename_version), packagenameREP, packagenamePRO, + # packagenameDEP, packagenamePRE, packagenameREC, + # packagenameSUG, packagenameCON, packagenameCONF. delete package -> + # version. + # + # for fileindex.deb - + # Find all files and directories associated with the package. Delete + # these files (keys). Find all directories where the file + # exists..delete package name from value, delete whole key if it is the + # only package name. + # + # for groupindex - delete package name (value) from Section + # it belonged to..humm, find section package belongs to in + # statusuindex.deb, and delete whole Section key if only one. + # + # for statusindex.deb - + # delete package -> version group. + # + # for flat files dirindex and searchindex - + # the removal of files and/or directories can be put on hold, and + # done with an option at a later time, since fileindex.deb remembers + # current state, at a later time the old state of the flat files can be + # compared to the new state of fileindex, and these files can be + # rewritten. This is all o.k. because these extra files or directories + # will return undef in search() if the packages don't exist. + + ping(\%commands); # uses $ping for package.deb + zing(\%commands); # uses $zing for fileindex.deb + ging(\%commands); # uses $ging for groupindex.deb + sing(\%commands); # uses $sing for statusindex.deb + + $| = 1; my $x = 1; + foreach (@GONE) { + print "G|C|CS $x $_.list\r"; + $x++; + #first delete keys from package.deb + # If I kept this the name_version would be remembered. + $ping->del($_); + my $orig_argument = $_; + my $packname_version = (split(/\s/,$sb{$orig_argument}))[0]; + $packname_version =~ s,\+,\\\+,g; + $argument = "$_"; + ver(\%commands); + $ping->del($argument); + my $conf = $argument . "CONF"; + $ping->del($conf); + $conf = $argument . "REP"; + $ping->del($conf); + $conf = $argument . "PRO"; + $ping->del($conf); + $conf = $argument . "DEP"; + $ping->del($conf); + $conf = $argument . "PRE"; + $ping->del($conf); + $conf = $argument . "REC"; + $ping->del($conf); + $conf = $argument . "SUG"; + $ping->del($conf); + $conf = $argument . "CON"; + $ping->del($conf); + untie $ping; + + # next let's go into fileindex.deb and hunt down all directories and + # files associated with this package. It would be kind of nice to use + # package_name.list, but it's probably more realistic not to depend on + # the existence of these file..unless a backup is made. Now if -i is used + # this would be a simple matter, but in this case things are different. + # A database to accomplish this wasn't realistic, so the backup + # files for *.list are in ./info/backup/*.list.bk. We will also have to + # deal with those rare cases that forget /. (smail 2.0v). We should remove + # this file as well as the packagename-conf.md5sums file below. + my $file = "$parent$base/info/backup/$_.list.bk"; + my $md5sum_file = "$parent$base/info/$_-conf.md5sums"; + open(LIST,"$file"); + while () { + chomp; + if (defined $ib{$_}) { + my $status = ($ib{$_} =~ s,$packname_version ,,); + if ($status eq "") { + $status = ($ib{$_} =~ s, $packname_version,,); + if ($status eq "") { + $ib{$_} =~ s,$packname_version,,; + } + } + if ($ib{$_} eq "") { + $zing->del($_); + } + } # if defined + } + close(LIST); + unlink("$file"); + + ####################### + # deinstall situation # + ####################### + my $yit = (split(/\s/,$sb{$orig_argument}))[3]; + if ($yit eq "deinstall:ok:config-files" || + $yit eq "purge:ok:config-files") { + if (defined $ib{"/."}) { + my $status = ($ib{"/."} =~ s,$packname_version ,,); + if ($status eq "") { + $status = ($ib{"/."} =~ s, $packname_version,,); + if ($status eq "") { + $ib{"/."} =~ s,$packname_version,,; + } + } + if ($ib{"/."} eq "") { + $zing->del($_); + } + } # if defined + } # deinstall situation + + if (-e $md5sum_file) { + unlink("$md5sum_file"); + } + + # remove from the group, and if only one remove the group. + # Let's first find out which group this monster belongs to. + if (defined $sb{$orig_argument}) { + (my $oa = $orig_argument) =~ s,\+,\\\+,g; + my($section) = (split(/\s/,$sb{$orig_argument}))[1]; + if (defined $gb{$section}) { + my $status = ($gb{$section} =~ s,$oa ,,); + if ($status eq "") { + $status = ($gb{$section} =~ s, $oa,,); + if ($status eq "") { + $gb{$section} =~ s,$oa,,; + } + } + if ($gb{$section} eq "") { + $ging->del($section); + } + } + } + + # Now ditch the package->version group in statusindex.deb + $sing->del($orig_argument); + untie $sing; + + } # end foreach OLD + + print "\n" if $#GONE != -1 && $#NEW == -1; + + ############# + # # + # NEW # + # # + ############# + if (-e "$parent$base/status" && -e "$parent$base/info") { + $the_status = "$parent$base/status"; + } + else { + print "swim: crucial file(s)/directories are missing in $parent\n"; + exit; + } + my %exacts; + my $goon; + print "\n" if $#NEW != -1; $x = 1; + foreach (@NEW) { + $exacts{$_} = "yes"; + } + # first let's find the fields to put into packages.deb + # We'll have to go through the status file again, something we + # wouldn't have had to do with swim -i. As it turns out, a good + # percentage of the information can be processed into the database + # while going through status. + open(PRETTY, ">$format_deb"); + open(AVAIL, "$the_status"); + while () { + # here's the difference with database(), we just find the packages + # which belong to the hash %exacts + # Package name + if (/^Package:|^PACKAGE:/) { + @package = split(/: /,$_); + chomp $package[1]; + if (defined $exacts{$package[1]}) { + print "N|C|CS $x\r"; $x++; + $goon = "yes"; + } + else { + $goon = "no"; + undef @package; + next; + } + } + elsif ($goon eq "no") { + next; + } + elsif (/^Status:/) { + $status = $_; + } + elsif (/^Essential/) { + @essential = split(/: /,$_); + } + # missing priority and section will be dealt with below + elsif (/^Priority:/) { + $priority = $_; + } + elsif (/^Section:/) { + $section = $_; + # make the hash for the groupindex.deb + $group = substr($section,9); + chomp $group; + # we will put not-installed in their own group for reference + if ($status !~ /not-installed/) { + if (!defined $gb{$group}) { + $ging->put($group,$package[1]); + } + else { + my $change_group = "$gb{$group} $package[1]"; + $ging->del($group); + $ging->put($group,"$change_group"); + } + } + } + elsif (/^Installed-Size:/) { + $installed_size = $_; + } + elsif (/^Maintainer:/) { + $maintainer = $_; + } + elsif (/^Source:/) { + $source = $_; + } + # hold ok not-installed - may want to change this just to + # non-installed. + elsif (/^Version:/ && $status !~ /not-installed/) { + my $version = $_; + chomp $version; + ########### + # SECTION # + ########### + if (defined $section) { + chomp $section; + } + else { + nsb(\%commands); + if (defined $nsb{$package[1]}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$package[1]}",3); + $group = $ngname; + } + else { + $group = "unavailable"; + } + } + $col1 = "Package: $package[1]"; + $col2 = $status; + write PRETTY; + $col1 = $version; + my $ver = m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # run. + $packv = "$package[1]_$1"; + $ping->put($package[1],$packv); + my ($priory,$statusy); + ############ + # PRIORITY # + ############ + if (defined $priority) { + $priory = substr($priority,10); + } + else { + nsb(\%commands); + if (defined $nsb{$package[1]}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$package[1]}",3); + $priory = $npriorname; + } + else { + $priory = "unavailable"; + } + } + chomp $priory; + $statusy = substr($status,8); + chomp $statusy; + $statusy =~ s/\s/:/g; + my $thimk = "$packv $group $priory $statusy"; + $sing->put($package[1],$thimk); + $package[1] = "$packv"; + if(defined($essential[1])) { + $col2 = "Essential: $essential[1]"; + @essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + ###################### + # SECTION & PRIORITY # + ###################### + if (defined $section) { + $col1 = $section; + } + else { + nsb(\%commands); + $package[1] =~ m,(.*)_.*,; + my $packthing = $1; + if (defined $nsb{$packthing}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$packthing}",3); + $col1 = "Section: $ngname"; + # we can put it in now, no deletion needed + if (!defined $gb{$group}) { + $ging->put($group,$packthing); + } + else { + my $change_group = "$gb{$group} $packthing"; + $ging->del($group); + $ging->put($group,"$change_group"); + } + } + else { + $col1 = "Section: unavailable"; + } + } + if (defined $priority) { + $col2 = $priority; + } + else { + nsb(\%commands); + $package[1] =~ m,(.*)_.*,; + my $packthing = $1; + if (defined $nsb{$packthing}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$packthing}",3); + $col2 = "Section: $npriorname"; + } + else { + $col2 = "Priority: unavailable\n"; + } + } + write PRETTY; + #my $cool = $installed_size . $maintainer; + #print PRETTY $cool; + $col1 = $installed_size; + if (defined $source) { + $col2 = $source; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + print PRETTY $maintainer + } + + # This stuff will be available with seperate query flags or All + elsif (/^Replaces:/) { + $replaces = $_; + if (defined($replaces)) { + $ping->put("$package[1]REP",$replaces); + } + } + elsif (/^Provides:/) { + $provides = $_; + if (defined($provides)) { + $ping->put("$package[1]PRO",$provides); + } + } + elsif (/^Depends:/) { + $depends = $_; + if (defined($depends)) { + $ping->put("$package[1]DEP",$depends); + } + } + elsif (/^Pre-Depends:/) { + $pre_depends = $_; + if (defined($pre_depends)) { + $ping->put("$package[1]PRE",$pre_depends); + } + } + elsif (/^Recommends:/) { + $recommends = $_; + if (defined($recommends)) { + $ping->put("$package[1]REC",$recommends); + } + } + elsif (/^Suggests:/) { + $suggests = $_; + if (defined($suggests)) { + $ping->put("$package[1]SUG",$suggests); + } + } + elsif (/^Conflicts:/) { + $conflicts = $_; + if (defined($conflicts)) { + $ping->put("$package[1]CON",$conflicts); + } + } + # Gather the Configuration Files, Description comes after. + # Available with a single flag. + elsif (/^Conffiles:/) { + my $line = ; + while ($line !~ /^Description:/) { + push(@conffiles,$line); + $line = ; + if ($line =~ /^Description/) { + $line_before = $line; + # put conffiles into one variable + if (defined $package[1]) { + } + my ($c, $cool); + if ($#conffiles != 0) { + for ($c = $#conffiles; $c >= 0; $c--) { + if ($c > 0) { + $cool = $conffiles[$c-1] .= $conffiles[$c]; + } + } #end for + } + else { + $cool = $conffiles[0]; + } + @conffiles = (); + $ping->put("$package[1]CONF",$cool); + } #if ($line =~ /^Desc + } # while ($line ! /^Desc + } # elsif (/^Conffiles + untie %nsb; + + # Only interested in available packages..so this is fine. + # To be combined with first fields. + if (/Description:|^\s\w*|^\s\.\w*/ || + defined($line_before) =~ /^Description/){ + my $many_lines; + if (defined($line_before)) { + push(@ldescription, $line_before); + push(@ldescription, $_); + $line_before = (); + } + else { + $many_lines = $_; + } + if ($_ !~ /^\n$/) { + $count++; + if ($count == 1) { + if (defined $package[1]) { + #chomp $package[1]; + #push(@dpackage,$package[1]); + push(@description,$package[1]); + } + } + if (defined($many_lines)) { + push(@ldescription,$many_lines); + } + } # end if ($_ !~ /^\n$/ + else { + $count = 0; + # let's put each description into one scalar + my ($c, $cool); + if ($#ldescription != 0) { + for ($c = $#ldescription; $c >= 0; $c--) { + if ($c > 0) { + $cool = $ldescription[$c-1] .= $ldescription[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $ldescription[0]; + } + if (defined $cool) { + push(@description,$cool); + } + @ldescription = (); + } # end else + $line_before = (); + } + untie $ping; + untie $ging; + untie $sing; + } # end while () + close(PRETTY); + + + # Let's put together the description with the rest of its fields. + open(FIELDS,"$format_deb"); + while () { + push(@form,$_); + } + close(FIELDS); + + foreach (@form) { + push(@formly,$_); + my ($cool); + $count++; + if ($count == 5) { + my ($c, $cool); + if ($#formly != 0) { + for ($c = $#formly; $c >= 0; $c--) { + if ($c > 0) { + $cool = $formly[$c-1] .= $formly[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $formly[0]; + } + push(@complete,$cool); + @formly = (); + $count = 0; + } + } + + my $name_version; + foreach (@description) { + if ($count == 1) { + # -i + my $lingo = shift(@complete); + $lingo = $lingo . $_; + #push(@Tdescription, $lingo); + $ping->put($name_version,$lingo); + $lingo = (); + $count = 1; + } + else { + # packagename_version + #push(@Tdescription, $_); + $name_version = $_; + $count = 0; + } + $count++; + untie $ping; + } + undef $ping; + + unlink($format_deb); + + # Now time to do some file/dir stuff. A backup of *list needs to be + # made, might as well use this. There is a possibility this can be + # used instead of fastswim for initial fileindex.deb. + my $package_name; + if (!-d "$parent$base/info/backup") { + mkdir("$parent$base/info/backup",0666); + } + print "\n" if $#NEW != -1; $x = 1; + + foreach $package_name (@NEW) { + open(FILENAME,"$parent$base/info/$package_name.list"); + open(CP,">$parent$base/info/backup/$package_name.list.bk"); + while () { + print CP $_; + } + close(FILENAME); + close(CP); + + my $file = "$parent$base/info/backup/$package_name.list.bk"; + print "#$x"; print " N|C $package_name.list \r"; + $x++; + open(LIST,"$file"); + while () { + chomp; + + # Better add the new stuff to the flat files first + if (!defined $ib{$_}) { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + open(SEARCHINDEX,">>$parent$library/searchindex.deb"); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + open(SEARCHINDEX,">>$parent$base/searchindex.deb"); + } + if (!-d) { + print SEARCHINDEX "$_\n"; + } + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + open(DIRINDEX,">>$parent$library/dirindex.deb"); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + open(DIRINDEX,">>$parent$base/dirindex.deb"); + } + if (-d) { + print DIRINDEX "$_\n"; + } + } # !defined + + # If the directory already exists we can just append + # to the end of the value + if (defined $ib{$_}) { + dbi(\%commands); + my $cvalue = $ib{$_} . " $db{$package_name}"; + # put overwrites by default! + $zing->put($_,$cvalue); + } # if defined + else { + dbi(\%commands); + $zing->put($_,$db{$package_name}); + } + untie %db; + untie $zing; + } + close(LIST); + close(SEARCHINDEX); + close(DIRINDEX); + + my $zit; my ($nit,$yit) = (split(/\s/,$sb{$package_name}))[0,3]; + if ($yit eq "deinstall:ok:config-files" || + $yit eq "purge:ok:config-files") { + ($zit = $nit) =~ s,\+,\\\+,; + if ($ib{"/."} !~ m,$zit,) { + $ib{"/."} = $ib{"/."} . " $zit"; + } + } + + } # end foreach NEW + print "\n" if $#NEW != -1; + +} # end sub db + +# Generally, it's unecessary to rebuild the flat databases unless major +# changes have occurred to a person's installation, and the database has +# become very repetitive, or a file has changed into a directory. This +# function has also been tried by tieing the flat file to an array, but +# there doesn't seem to be that much of a speed advantage unless ib() +# happens to be in memory, but more experimentation will be tried in the +# future. +sub rebuildflatdb { + + my($commands) = @_; + my %commands = %$commands; + ib(\%commands); + + print scalar(localtime), "\n"; + + my $file; + my $dir; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + !($commands->{"dbpath"} && $commands->{"root"})) { + if (-e "$parent$library/searchindex.deb") { + $dir = "$parent$library/dirindex.deb"; + $file = "$parent$library/searchindex.deb"; + unlink($file); + unlink("$file.gz") if -e "$file.gz"; + unlink($dir); + unlink("$dir.gz") if -e "$dir.gz"; + } + else { + print "swim: operation only implemented for installed system\n"; + exit; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/searchindex.deb") { + $file = "$parent$base/searchindex.deb"; + $dir = "$parent$base/dirindex.deb"; + unlink($file); + unlink("$file.gz") if -e "$file.gz"; + unlink($dir); + unlink("$dir.gz") if -e "$dir.gz"; + } + else { + print "swim: operation only implemented for installed system\n"; + exit; + } + } + + + open(DIR,">$dir"); + open(FILE,">$file"); + # We need to reconstruct long.debian & DEBIAN*, but can't take into account + # weirdisms with the database - NEW packages which aren't NEW. + foreach (keys %ib) { + if (defined $ib{$_}) { + my $filedir = $_; + my $package = $ib{$_}; + #$package =~ s/\s/\n/g; + my @the_amount = split(/\s/, $package); + if ($#the_amount > 0) { + print DIR "$filedir\n"; + } + elsif ($#the_amount == 0) { + print FILE "$filedir\n"; + } + } + } + untie %ib; + print scalar(localtime), "\n"; + +} # end sub rebuildflatdb + + + +1; diff --git a/lib/DB_Init.pm b/lib/DB_Init.pm new file mode 100644 index 0000000..c864e86 --- /dev/null +++ b/lib/DB_Init.pm @@ -0,0 +1,648 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::DB_Init; +use strict; +use SWIM::Conf qw(:Path $fastswim $imswim $slowswim $sort); +#use SWIM::Global; +use SWIM::Format; +use SWIM::MD; +use DB_File; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(database); + + +# database() md() --initdb --rebuilddb + +# Time to get serious and make a database +sub database { + + + my ($commands) = @_; + my %commands = %$commands; + print scalar(localtime), "\n"; + + #my whatever that is + my @dpackage; # passes name_version to md() + my @Tdescription; + my @description; + my @ldescription; + my @package; + my %db; + my @name; + my $count = 0; + + my $the_status; + + my $status; + my @essential; + my $priority; + my $section; + my $installed_size; + my $maintainer; + my $source; + my $version; + my $ver; + + my %gb; + my %group; + my $group; + + # Keeps a package->version database + # to save time over using status + my %sb; + my @status; + + my ($replaces, @REPLACE, $provides, $depends, $pre_depends, + $recommends, $suggests, $conflicts); + + my @conffiles; + my $line_before; + my @conf; + my @complete; + my @form; + my @formly; + my $format_deb = "$tmp/format.deb"; + +# Let's decide whether we should even go on. If it is --initdb, and +# the databases already exist, nothing should be touched, but if it is +# --rebuilddb and they exist, then they are removed and remade from +# scratch. + + # But first, better clean up any files in $tmp in case of an aborted + # database formation + unlink(<$tmp/DEBIAN*>) if -e "$tmp/DEBIANaa"; + unlink("$tmp/transfer.deb") if -e "$tmp/transfer.deb"; + unlink("$tmp/big.debian") if -e "$tmp/big.debian"; + unlink("$tmp/long.debian") if -e "$tmp/long.debian"; + + + if (-e "$parent$base/status" && -e "$parent$base/info") { + $the_status = "$parent$base/status"; + } + else { + print "swim: crucial file(s)/directories are missing in $parent\n"; + exit; + } + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if ($commands->{"initdb"}) { + if (-e "$parent$library/packages.deb" && + -e "$parent$library/fileindex.deb") { + print "swim: use --rebuilddb\n"; + exit; + } + else { + # if a database happens to be missing + if (-e "$parent$library/packages.deb") { + unlink("$parent$library/packages.deb"); + } + if (-e "$parent$library/fileindex.deb") { + unlink("$parent$library/fileindex.deb"); + } + if (-e "$parent$library/groupindex.deb") { + unlink("$parent$library/groupindex.deb"); + } + if (-e "$parent$library/statusindex.deb") { + unlink("$parent$library/statusindex.deb"); + } + if (-e "$parent$library/searchindex.deb") { + unlink("$parent$library/searchindex.deb"); + } + if (-e "$parent$library/searchindex.deb.gz") { + unlink("$parent$library/searchindex.deb.gz"); + } + if (-e "$parent$library/dirindex.deb") { + unlink("$parent$library/dirindex.deb"); + } + if (-e "$parent$library/dirindex.deb.gz") { + unlink("$parent$library/dirindex.deb.gz"); + } + } + } + # this only works if all databases exist. + elsif ($commands->{"rebuilddb"}) { + if (-e "$parent$library/packages.deb" && + -e "$parent$library/fileindex.deb") { + unlink("$parent$library/packages.deb"); + unlink("$parent$library/fileindex.deb"); + unlink("$parent$library/groupindex.deb"); + unlink("$parent$library/statusindex.deb"); + unlink("$parent$library/searchindex.deb"); + unlink("$parent$library/searchindex.deb") + if -e "$parent$library/searchindex.deb"; + unlink("$parent$library/dirindex.deb"); + unlink("$parent$library/dirindex.deb") + if -e "$parent$library/dirindex.deb.gz"; + } + else { + print "swim: use --initdb to create databases\n"; + exit; + } + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if ($commands->{"initdb"}) { + if (-e "$parent$base/packages.deb" && + -e "$parent$base/fileindex.deb") { + print "swim: use --rebuilddb\n"; + exit; + } + else { + # if a database happens to be missing + if (-e "$parent$base/packages.deb") { + unlink("$parent$base/packages.deb"); + } + if (-e "$parent$base/fileindex.deb") { + unlink("$parent$base/fileindex.deb"); + } + if (-e "$parent$base/groupindex.deb") { + unlink("$parent$base/groupindex.deb"); + } + if (-e "$parent$library/statusindex.deb") { + unlink("$parent$library/statusindex.deb"); + } + if (-e "$parent$library/searchindex.deb") { + unlink("$parent$library/searchindex.deb"); + } + if (-e "$parent$library/searchindex.deb.gz") { + unlink("$parent$library/searchindex.deb.gz"); + } + if (-e "$parent$library/dirindex.deb") { + unlink("$parent$library/dirindex.deb"); + } + if (-e "$parent$library/dirindex.deb.gz") { + unlink("$parent$library/dirindex.deb.gz"); + } + } + } + # this only works if all databases exist. + elsif ($commands->{"rebuilddb"}) { + if (-e "$parent$base/packages.deb" && + -e "$parent$base/fileindex.deb") { + unlink("$parent$base/packages.deb"); + unlink("$parent$base/fileindex.deb"); + unlink("$parent$base/groupindex.deb"); + unlink("$parent$base/statusindex.deb"); + unlink("$parent$library/searchindex.deb"); + unlink("$parent$library/searchindex.deb") + if -e "$parent$library/searchindex.deb"; + unlink("$parent$library/dirindex.deb"); + unlink("$parent$library/dirindex.deb") + if -e "$parent$library/dirindex.deb.gz"; + } + else { + print "swim: use --initdb to create databases\n"; + exit; + } + } + } + + # This makes a backup of all the *.list files in ./backup. When + # --initdb/--rebuilddb runs these files should be built or rebuilt, + # but if changes have occured and --db(-i wasn't used) wasn't run + # this won't cause problems because everything is rebuilt, there may + # just be some lingering small files in backup. + + # Seems like both approaches are about the same speed. + #use File::Copy; + print "Making backups of *.list\n"; + if (!-d "$parent$base/info/backup") { + mkdir("$parent$base/info/backup",0666); + } + opendir(COPY,"$parent$base/info"); + foreach (sort grep(/\.list$/, readdir(COPY))) { + #copy ("$parent$base/info/$_","$parent$base/info/backup/$_.bk"); + open(FILENAME,"$parent$base/info/$_"); + open(CP,">$parent$base/info/backup/$_.bk"); + while () { + print CP $_; + } + } + closedir(COPY); + + print "Description Database is being made\n"; + + $| = 1; my $x = 0; + open(PRETTY, ">$format_deb"); + open(AVAIL, "$the_status"); + while () { + # Package name + if (/^Package:|^PACKAGE:/) { + @package = split(/: /,$_); + chomp $package[1]; + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + } + # Some other pertinent fields + # All this stuff can be placed together..since it is generally nice + # to know these things at one glance, in this order. + # Package: Status: + # Version: Essential: (yes or no) + # Section: Priority: + # Installed-Size: + # Maintainer: + # Description: + + elsif (/^Status:/) { + $status = $_; + } + elsif (/^Essential/) { + @essential = split(/: /,$_); + } + elsif (/^Priority:/) { + $priority = $_; + } + elsif (/^Section:/) { + $section = $_; + # make the hash for the groupindex.deb + $group = substr($section,9); + chomp $group; + # we will put not-installed in their own group for reference + if ($status !~ /not-installed/) { + if (!defined $group{$group}) { + $group{$group} = $package[1]; + } + else { + $group{$group} = "$group{$group} $package[1]"; + } + } + } + elsif (/^Installed-Size:/) { + $installed_size = $_; + } + elsif (/^Maintainer:/) { + $maintainer = $_; + } + elsif (/^Source:/) { + $source = $_; + } + # hold ok not-installed - may want to change this just to + # non-installed. + elsif (/^Version:/ && $status !~ /not-installed/) { + $version = $_; + chomp($version, $section); + $col1 = "Package: $package[1]"; + $col2 = $status; + write PRETTY; + $col1 = $version; + $ver = m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # ran. + push(@name, $package[1]); + push(@status, $package[1]); + $package[1] = "$package[1]_$1"; + push(@name, $package[1]); + my $priory = substr($priority,10); + chomp $priory; + my $statusy = substr($status,8); + chomp $statusy; + $statusy =~ s/\s/:/g; + my $thimk = "$package[1] $group $priory $statusy"; + push(@status, $thimk); + if(defined($essential[1])) { + $col2 = "Essential: $essential[1]"; + @essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + if (defined $section) { + $col1 = $section; + } + else { + $col1 = "Section: unavailable"; + } + if (defined $priority) { + $col2 = $priority; + } + else { + $col2 = "Priority: unavailable\n"; + } + write PRETTY; + #my $cool = $installed_size . $maintainer; + $col1 = $installed_size; + if (defined $source) { + $col2 = $source; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + print PRETTY $maintainer + } + + # This stuff will be available with seperate query flags or All + elsif (/^Replaces:/) { + $replaces = $_; + if (defined($replaces)) { + push(@REPLACE, "$package[1]REP"); + push(@REPLACE, $replaces); + } + } + elsif (/^Provides:/) { + $provides = $_; + if (defined($provides)) { + push(@REPLACE, "$package[1]PRO"); + push(@REPLACE, $provides); + } + } + elsif (/^Depends:/) { + $depends = $_; + if (defined($depends)) { + push(@REPLACE, "$package[1]DEP"); + push(@REPLACE, $depends); + } + } + elsif (/^Pre-Depends:/) { + $pre_depends = $_; + if (defined($pre_depends)) { + push(@REPLACE, "$package[1]PRE"); + push(@REPLACE, $pre_depends); + } + } + elsif (/^Recommends:/) { + $recommends = $_; + if (defined($recommends)) { + push(@REPLACE, "$package[1]REC"); + push(@REPLACE, $recommends); + } + } + elsif (/^Suggests:/) { + $suggests = $_; + if (defined($suggests)) { + push(@REPLACE, "$package[1]SUG"); + push(@REPLACE, $suggests); + } + } + elsif (/^Conflicts:/) { + $conflicts = $_; + if (defined($conflicts)) { + push(@REPLACE, "$package[1]CON"); + push(@REPLACE, $conflicts); + } + } + # Gather the Configuration Files, Description comes after. + # Available with a single flag. + elsif (/^Conffiles:/) { + my $line = ; + while ($line !~ /^Description:/) { + push(@conffiles,$line); + $line = ; + if ($line =~ /^Description/) { + $line_before = $line; + # put conffiles into one variable + if (defined $package[1]) { + #chomp $package[1]; + push(@conf,"$package[1]CONF"); + } + my ($c, $cool); + if ($#conffiles != 0) { + for ($c = $#conffiles; $c >= 0; $c--) { + if ($c > 0) { + $cool = $conffiles[$c-1] .= $conffiles[$c]; + } + } #end for + } + else { + $cool = $conffiles[0]; + } + @conffiles = (); + push(@conf,$cool); + } #if ($line =~ /^Desc + } # while ($line ! /^Desc + } # elsif (/^Conffiles + + # Only interested in available packages..so this is fine. + # To be combined with first fields. + if (/Description:|^\s\w*|^\s\.\w*/ || + defined($line_before) =~ /^Description/){ + my $many_lines; + if (defined($line_before)) { + push(@ldescription, $line_before); + push(@ldescription, $_); + $line_before = (); + } + else { + $many_lines = $_; + } + if ($_ !~ /^\n$/) { + $count++; + if ($count == 1) { + if (defined $package[1]) { + #chomp $package[1]; + push(@dpackage,$package[1]); + push(@description,$package[1]); + } + } + if (defined($many_lines)) { + push(@ldescription,$many_lines); + } + } # end if ($_ !~ /^\n$/ + else { + $count = 0; + # let's put each description into one scalar + my ($c, $cool); + if ($#ldescription != 0) { + for ($c = $#ldescription; $c >= 0; $c--) { + if ($c > 0) { + $cool = $ldescription[$c-1] .= $ldescription[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $ldescription[0]; + } + if (defined $cool) { + push(@description,$cool); + } + @ldescription = (); + } # end else + $line_before = (); + } + } # end while () + close(PRETTY); + + # Let's put together the description with the rest of its fields. + open(FIELDS,"$format_deb"); + while () { + push(@form,$_); + } + close(FIELDS); + + foreach (@form) { + push(@formly,$_); + my ($cool); + $count++; + if ($count == 5) { + my ($c, $cool); + if ($#formly != 0) { + for ($c = $#formly; $c >= 0; $c--) { + if ($c > 0) { + $cool = $formly[$c-1] .= $formly[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $formly[0]; + } + push(@complete,$cool); + @formly = (); + $count = 0; + } + } + + foreach (@description) { + if ($count == 1) { + my $lingo = shift(@complete); + $lingo = $lingo . $_; + push(@Tdescription, $lingo); + $lingo = (); + $count = 1; + } + else { + push(@Tdescription, $_); + $count = 0; + } + $count++; + + } + unlink($format_deb); + + # We'll keep databases local so that md() doesn't get confused with + # database(). + + # Put the groups into the groupindex.deb database. + print "Group Database is being made\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %gb, 'DB_File', "$parent$library/groupindex.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %gb, 'DB_File', "$parent$base/groupindex.deb" or die "DB_File: $!"; + } + + %gb = %group; + + untie %gb; + undef %gb; + undef %group; + + # Create the important status database. + print "Status Database is being made\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %sb, 'DB_File', "$parent$library/statusindex.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %sb, 'DB_File', "$parent$base/statusindex.deb" or die "DB_File: $!"; + } + + %sb = @status; + + untie %sb; + undef %sb; + undef @status; + + # Put everything into the package.deb database. + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %db, 'DB_File', "$parent$library/packages.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %db, 'DB_File', "$parent$base/packages.deb" or die "DB_File: $!"; + } + + %db = (@name,@Tdescription,@conf,@REPLACE); + untie %db; + undef @Tdescription; + undef @conf; + undef @REPLACE; + undef %db; + + + # To the total db thing. + if ($commands->{"initdb"} || $commands->{"rebuilddb"}) { + md(\@dpackage,\%commands); + } + + +} # end sub database + + +# Basically, this writes @dpackage to transfer.deb, which is processed by +# either fastswim into two files big.debian and long.debian for further +# processing by process_md() or is processed by imswim, then slowswim into +# the two files big.debian and long.debian then finished by process_md() +sub md { + + my($dpackage,$commands) = @_; # creates transfer.deb + my %commands = %$commands; + + + unless (-e "$parent$base/info") { + die 'This program requires the /var/lib/dpkg/info directory set-up by dpkg'; + } + + # Put all file/dir(*.list)->package_name(s) into an massive array. + # fastswim runs this process separately. + + # This enables info files to be used from a different root system + my $argument2 = "$parent$base/info"; + + # This is just for testing purposes, and serves no real purpose. + if (!defined(@$dpackage)) { + system("$fastswim"); + } + # This is what is used. + else { + open(TRANSFER, ">$tmp/transfer.deb"); + foreach (@$dpackage) { + print TRANSFER "$_\n"; + } + close(TRANSFER); + if (!$commands->{"lowmem"}) { + system $fastswim, "--transfer", $argument2, $tmp; + } + else { + print "Gathering the file(s)/dir(s)\n"; + system $imswim, $argument2, $tmp; + system $slowswim, $tmp, $sort; + } + } + undef @$dpackage; + process_md(\%commands); + +} # end sub md + + + +1; diff --git a/lib/DB_Library.pm b/lib/DB_Library.pm new file mode 100644 index 0000000..07d44d7 --- /dev/null +++ b/lib/DB_Library.pm @@ -0,0 +1,497 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::DB_Library; +use strict; +use SWIM::Conf; +use SWIM::Global; +use SWIM::Library; +use DB_File; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(ib nib dbi ndb sb exist_sb nsb ping zing nzing ging gb + ngb sing ram_on version ver nver nping nzing nging nsing); +%EXPORT_TAGS = ( + Search => [ qw(ib dbi nib nsb ndb gb ram_on version ngb) ], + Db => [ qw(sb ib gb nsb ver dbi zing ging ping sing) ], + Md => [ qw(sb ib nsb nzing) ], + Deb => [ qw(sb nsb ndb) ], + NDb => [ qw(ndb nsb ngb nver nping nzing nging nsing + exist_sb sb) ], + Groups => [ qw(gb ngb) ], + Xyz => [ qw(dbi ndb) ] + ); + + +# functions which use DB_File + + +sub ib { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/fileindex.deb") { + tie %ib, 'DB_File', "$parent$library/fileindex.deb" or die "DB_File: $!"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/fileindex.deb") { + tie %ib, 'DB_File', "$parent$base/fileindex.deb" or die "DB_File: $!"; + } + } +} # end sub ib + +sub dbi { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/packages.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %db, 'DB_File', "$parent$library/packages.deb" or die "DB_File: $!"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/packages.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %db, 'DB_File', "$parent$base/packages.deb" or die "DB_File: $!"; + } + } +} # end sub dbi + + + +sub nib { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (!-e "$parent$library/nfileindex$arch$dist.deb") { + return; + } + tie %ib, 'DB_File', "$parent$library/nfileindex$arch$dist.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (!-e "$parent$base/nfileindex$arch$dist.deb") { + return; + } + tie %ib, 'DB_File', "$parent$base/nfileindex$arch$dist.deb" or die "DB_File: $!"; + } +} # end sub nib + + +sub ndb { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/npackages$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"} || + $commands->{"ndb"})) { + tie %db, 'DB_File', "$parent$library/npackages$arch$dist.deb" + or die "swim: use pre-existing databases for this option"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/npackages$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"} || + $commands->{"ndb"})) { + tie %db, 'DB_File', "$parent$base/npackages$arch$dist.deb" + or die "swim: use pre-existing databases for this option"; + } + } +} # end sub ndb + + +sub sb { + + my ($commands) = @_; + my %commands = %$commands; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/statusindex.deb") { + tie %sb, 'DB_File', "$parent$library/statusindex.deb" + or die "DB_File: $!"; + } + else { + return; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/statusindex.deb") { + tie %sb, 'DB_File', "$parent$base/statusindex.deb" + or die "DB_File: $!"; + } + else { + return; + } + } +} # end sub sb + +# exist_sb & sb seem to be used primarily in NDB_Init + +# This first looks in the immediate directory for statusindex.deb, if it +# isn't found here, it look in the default directory. It then returns +# undef, or initializes the database based on its findings. +sub exist_sb { + + my ($commands) = @_; + my %commands = %$commands; + + my $yep; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/statusindex.deb") { + $yep = "yes"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/statusindex.deb") { + $yep = "yes"; + } + } + + if (!defined $yep) { + if (-e "$parent$base/statusindex.deb") { + tie %sb, 'DB_File', "$parent$base/statusindex.deb" + or die "DB_File: $!"; + return "yes"; + } + else { + return; + } + } + elsif (defined $yep) { + sb(\%commands); + return "yes"; + } + +} # end sub exist_sb + +sub nsb { + + my ($commands) = @_; + my %commands = %$commands; + + my($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/nstatusindex$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"} || + $commands->{"ndb"})) { + tie %nsb, 'DB_File', "$parent$library/nstatusindex$arch$dist.deb" + or die "swim: use pre-existing databases for this option"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/nstatusindex$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"} || + $commands->{"ndb"})) { + tie %nsb, 'DB_File', "$parent$base/nstatusindex$arch$dist.deb" or die + or die "swim: use pre-existing databases for this option"; + } + } +} # end sub nsb + +sub ping { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $ping = tie %db, 'DB_File', "$parent$library/packages.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $ping = tie %db, 'DB_File', "$parent$base/packages.deb" or die "DB_File: $!"; + } +} + +sub nping { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $ping = tie %db, 'DB_File', "$parent$library/npackages$arch$dist.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $ping = tie %db, 'DB_File', "$parent$base/npackages$arch$dist.deb" + or die "DB_File: $!"; + } +} # end sub nping + + +sub zing { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $zing = tie %ib, 'DB_File', "$parent$library/fileindex.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $zing = tie %ib, 'DB_File', "$parent$base/fileindex.deb" + or die "DB_File: $!"; + } +} # end sub zing + +sub nzing { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $zing = tie %ib, 'DB_File', "$parent$library/nfileindex$arch$dist.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $zing = tie %ib, 'DB_File', "$parent$base/nfileindex$arch$dist.deb" + or die "DB_File: $!"; + } +} # end sub nzing + + +sub ging { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $ging = tie %gb, 'DB_File', "$parent$library/groupindex.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $ging = tie %gb, 'DB_File', "$parent$base/groupindex.deb" or die "DB_File: $!"; + } +} #end sub ging + + +sub nging { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $ging = tie %gb, 'DB_File',"$parent$library/ngroupindex$arch$dist.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $ging = tie %gb, 'DB_File', "$parent$base/ngroupindex$arch$dist.deb" + or die "DB_File: $!"; + } +} # end sub nging + + +sub gb { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/groupindex.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %gb, 'DB_File', "$parent$library/groupindex.deb" or die "DB_File: $!"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/groupindex.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %gb, 'DB_File', "$parent$base/groupindex.deb" or die "DB_File: $!"; + } + } +} + +sub ngb { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/ngroupindex$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %gb, 'DB_File', "$parent$library/ngroupindex$arch$dist.deb" + or die "DB_File: $!"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/ngroupindex$arch$dist.deb" || + ($commands->{"initndb"} || $commands->{"rebuildndb"})) { + tie %gb, 'DB_File', "$parent$base/ngroupindex$arch$dist.deb" + or die "DB_File: $!"; + } + } +} + +sub sing { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sing = tie %sb, 'DB_File', "$parent$library/statusindex.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sing = tie %sb, 'DB_File', "$parent$base/statusindex.deb" or die "DB_File: $!"; + } +} # sub sing + +sub nsing { + + my ($commands) = @_; + my %commands = %$commands; + + my ($arch,$dist) = which_archdist(\%commands); + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sing = tie %nsb, 'DB_File', "$parent$library/nstatusindex$arch$dist.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sing = tie %nsb, 'DB_File', "$parent$base/nstatusindex$arch$dist.deb" + or die "DB_File: $!"; + } +} # end sub nsing + + +# This doesn't depend on DB so it can be placed somewhere else if it is used by more +# than SWIM::Search. + +# checks to see if ramdisk is on, searchdf() & nfile()-process_nfile() +# (used by file()) uses this +sub ram_on { + + my $ramdisk; + + # this monster runs for every argument + my $rambo = "$cat /proc/mounts|"; + open(RAM, "$rambo"); + while () { + if (/ram/) { + my($device,$mount) = split(/\s/,$_,2); + if ($mount =~ /dramdisk/) { + $ramdisk = "yes"; + return $ramdisk; + } + } + } + close(RAM); +} # end sub ram_on + + + +# finds package name and version +sub version { + + my ($commands) = @_; + my %commands = %$commands; + + if (!$commands{"n"}) { + dbi(\%commands); + } + else { + ndb(\%commands); + } + + if (defined $argument) { + # We will check for more than two..just in case + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + } + } + +} # end sub version +# returns version but and then is untied +sub ver { + + my ($commands) = @_; + my %commands = %$commands; + dbi(\%commands); + + if (defined $argument) { + # We will check for more than two..just in case + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + } + } + + untie %db; + +} # end sub ver + +sub nver { + + my ($commands) = @_; + my %commands = %$commands; + ndb(\%commands); + + if (defined $argument) { + # We will check for more than two..just in case + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + } + } + + untie %db; + +} # end sub nver + diff --git a/lib/Deb.pm b/lib/Deb.pm new file mode 100644 index 0000000..14b92b9 --- /dev/null +++ b/lib/Deb.pm @@ -0,0 +1,1752 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Deb; +use strict; +use SWIM::Dir; +use SWIM::Global qw($argument %nsb %db %sb); +use SWIM::Conf qw(:Deb); +use SWIM::Format; +use SWIM::DB_Library qw(:Deb); +use SWIM::Compare; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(deb_package md5sumo); + +$| = 1; + +# this should be re-written to access the functions differently, because +# it was written to go into every function, then SelfLoader could be used. + +# query Debian packages using dpkg-deb and dpkg, or ar for non dpkg +# installations. +sub deb_package { + + my ($commands) = @_; my %commands = %$commands; + + # this routine will read in single or more packages at the command line + # and/or directories with or without a wild card, taking into account + # such weird things as ../dir1/dir2/*. Wild cards - in case a package + # doesn't end in deb. rpm has error output when things aren't correct, + # and STDOUT when thing are, swim doesn't do this..but it could, actually + # the STDOUT is nicer, well maybe. Ofcourse, --md5sum won't work here, + # it's not necessary, actually it will under certain conditions + # described in swim's manual. + + # This provides the full path of dir/file. ../ not implemented yet. + # So, the queries can occur within each situation. + if ($#ARGV != -1) { + foreach (@ARGV) { + + ############### + # SITUATION 0 # + ############### + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/[\w-+]+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + } + else { print "swim: not implemented yet\n"; exit; } + dir(\%commands); + fir(\%commands); + # we will first check to see if $argument really is a Debian + # package + my $real; + if (defined $dpkg_deb) { + $real = system("$dpkg_deb -f $argument Package 2&>/dev/null"); + } + elsif (defined $ar) { + $real = system "$ar -p $argument debian-binary 2&>/dev/null"; + } + # construct the fields to the standard of swim + if ($real == 0) { + printme(\%commands); + scripto(\%commands); + menuo(\%commands); + copyrighto(\%commands); + changelogo(\%commands); + if ($commands->{"i"}) { + shbang(\%commands); + package_processor(\%commands); + if (defined $dpkg_deb) { + print "Description: "; + system "$dpkg_deb -f $argument Description"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep -E \"Description: \w*|[.]\$|^ [\w-]*\""; + } + if (!($commands->{"T"} || $commands->{"pre_depends"} || + $commands->{"depends"} || $commands->{"recommends"} || + $commands->{"suggests"} || $commands->{"provides"} || + $commands->{"replaces"} || $commands->{"conflicts"} || + $commands->{"c"} || $commands->{"l"})) { + print "\n"; + } + } + shlibso(\%commands); + md5sumo(\%commands); + deps(\%commands); + # nothing fancy here, no md5sums, no indenting. + if ($commands->{"c"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$dpkg_deb --info $argument conffiles"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$ar -p $argument control.tar.gz \| + $tar xOz conffiles"; + undef $real; + } + } + } + listing(\%commands); + print "\n"; + extract(\%commands); + } + elsif ($real != 0) { + $argument =~ m,.*\/(.*$),; + if (!-d $argument) { + print "$1 is not a debian package\n\n"; + } + else { + print "$1 is a directory\n\n"; + } + } + } + + ############### + # SITUATION I # + ############### + elsif ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + dir(\%commands); + fir(\%commands); + # we will first check to see if $argument really is a Debian + # package + my $real; + if (defined $dpkg_deb) { + $real = system("$dpkg_deb -f $argument Package 2&>/dev/null"); + } + elsif (defined $ar) { + $real = system "$ar -p $argument debian-binary 2&>/dev/null"; + } + # construct the fields to the standard of swim + if ($real == 0) { + printme(\%commands); + scripto(\%commands); + menuo(\%commands); + copyrighto(\%commands); + changelogo(\%commands); + if ($commands->{"i"}) { + shbang(\%commands); + package_processor(\%commands); + if (defined $dpkg_deb) { + print "Description: "; + system "$dpkg_deb -f $argument Description"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep -E \"Description: \w*|[.]\$|^ [\w-]*\""; + } + if (!($commands->{"T"} || $commands->{"pre_depends"} || + $commands->{"depends"} || $commands->{"recommends"} || + $commands->{"suggests"} || $commands->{"provides"} || + $commands->{"replaces"} || $commands->{"conflicts"} || + $commands->{"c"} || $commands->{"l"})) { + print "\n"; + } + } + shlibso(\%commands); + md5sumo(\%commands); + deps(\%commands); + # nothing fancy here, no md5sums, no indenting. + if ($commands->{"c"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$dpkg_deb --info $argument conffiles"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$ar -p $argument control.tar.gz \| + $tar xOz conffiles"; + undef $real; + } + } + } + listing(\%commands); + print "\n"; + extract(\%commands); + } + elsif ($real != 0) { + $argument =~ m,.*\/(.*$),; + if (!-d $argument) { + print "$1 is not a debian package\n\n"; + } + else { + print "$1 is a directory\n\n"; + } + } + } + + ################ + # SITUATION II # + ################ + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + dir(\%commands); + fir(\%commands); + # we will first check to see if $argument really is a Debian + # package + my $real; + if (defined $dpkg_deb) { + $real = system("$dpkg_deb -f $argument Package 2&>/dev/null"); + } + elsif (defined $ar) { + $real = system "$ar -p $argument debian-binary 2&>/dev/null"; + } + # construct the fields to the standard of swim + if ($real == 0) { + printme(\%commands); + scripto(\%commands); + menuo(\%commands); + copyrighto(\%commands); + changelogo(\%commands); + if ($commands->{"i"}) { + shbang(\%commands); + package_processor(\%commands); + if (defined $dpkg_deb) { + print "Description: "; + system "$dpkg_deb -f $argument Description"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep -E \"Description: \w*|[.]\$|^ [\w-]*\""; + } + if (!($commands->{"T"} || $commands->{"pre_depends"} || + $commands->{"depends"} || $commands->{"recommends"} || + $commands->{"suggests"} || $commands->{"provides"} || + $commands->{"replaces"} || $commands->{"conflicts"} || + $commands->{"c"} || $commands->{"l"})) { + print "\n"; + } + } + shlibso(\%commands); + md5sumo(\%commands); + deps(\%commands); + # nothing fancy here, no md5sums, no indenting. + if ($commands->{"c"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$dpkg_deb --info $argument conffiles"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$ar -p $argument control.tar.gz \| + $tar xOz conffiles"; + undef $real; + } + } + } + listing(\%commands); + print "\n"; + extract(\%commands); + } + elsif ($real != 0) { + $argument =~ m,.*\/(.*$),; + if (!-d $argument) { + print "$1 is not a debian package\n\n"; + } + else { + print "$1 is a directory\n\n"; + } + } + } + + ################# + # SITUATION III # + ################# + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + dir(\%commands); + fir(\%commands); + # we will first check to see if $argument really is a Debian + # package + my $real; + if (defined $dpkg_deb) { + $real = system("$dpkg_deb -f $argument Package 2&>/dev/null"); + } + elsif (defined $ar) { + $real = system "$ar -p $argument debian-binary 2&>/dev/null"; + } + # construct the fields to the standard of swim + if ($real == 0) { + printme(\%commands); + scripto(\%commands); + menuo(\%commands); + copyrighto(\%commands); + changelogo(\%commands); + if ($commands->{"i"}) { + shbang(\%commands); + package_processor(\%commands); + if (defined $dpkg_deb) { + print "Description: "; + system "$dpkg_deb -f $argument Description"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep -E \"Description: \w*|[.]\$|^ [\w-]*\""; + } + if (!($commands->{"T"} || $commands->{"pre_depends"} || + $commands->{"depends"} || $commands->{"recommends"} || + $commands->{"suggests"} || $commands->{"provides"} || + $commands->{"replaces"} || $commands->{"conflicts"} || + $commands->{"c"} || $commands->{"l"})) { + print "\n"; + } + } + shlibso(\%commands); + md5sumo(\%commands); + deps(\%commands); + # nothing fancy here, no md5sums, no indenting. + if ($commands->{"c"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$dpkg_deb --info $argument conffiles"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz conffiles >/dev/null 2>&1"; + if ($real == 0) { + system "$ar -p $argument control.tar.gz \| + $tar xOz conffiles"; + undef $real; + } + } + } + listing(\%commands); + print "\n"; + extract(\%commands); + } + elsif ($real != 0) { + $argument =~ m,.*\/(.*$),; + if (!-d $argument) { + print "$1 is not a debian package\n\n"; + } + else { + print "$1 is a directory\n\n"; + } + } + } + } + } + + # NO ARGUMENTS + else { + print "swim: no arguments given for query\n"; + exit; + } + +} # end sub deb_package + + +# It's nice to be able to quickly extract a file from a package in the +# immediate directory or the path above where swim is being run from. This +# will be integrated with the DF directory. Probably the ability to enter just +# filename(s) will replace the PWD\! method. +sub extract { + + my ($commands) = @_; my %commands = %$commands; + + + if ($commands->{"extract"}) { + + my ($file,$same); + $commands->{"extract"} =~ /!/ + ? (($same,$file) = (split(/!/,$commands->{"extract"}))[0,1]) + : ($file = $commands->{"extract"}); + + + # extract files into the current directory + if (defined $same) { + # this is one of these instances where not being precise is o.k. + print "swim: specify PWD before ! :*}\n" if $same ne "PWD"; + print "swim: PWD is used for extracting files into the current directory\n" + if $file =~ m,.*/$,; exit if $file =~ m,.*/$,; + chdir($tmp); + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar x $file 2> fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xz $file 2> fields.deb"; + } + + if (!-z "fields.deb") { + print "swim: archive does not exist\n"; + exit; + } + + $file =~ m,.*/(.*)$,; + rename("$tmp/$file","$pwd/$1") + or system "$mv","$tmp/$file", "$pwd/$1"; + my @ddirs = split(m,/,,$file); + if (defined @ddirs) { + chdir("$tmp/$ddirs[0]"); + system "rm -rf *"; + chdir($tmp); + rmdir($ddirs[0]); + } + else { + unlink($file); + } + print "swim: $1 has been extracted\n"; + } + + # extract full path of archive above pwd + elsif ($file ne "ALL") { + + chdir($pwd); + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar x $file 2> $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xz $file 2> $tmp/fields.deb"; + } + + if (!-z "$tmp/fields.deb") { + print "swim: archive does not exist\n"; + exit; + } + else { + print "swim: $file has been extracted\n"; + } + + } + + # extract everything + else { + + chdir($pwd); + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar x 2> $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xz 2> $tmp/fields.deb"; + } + $argument =~ m,.*/(.*)$,; + print "swim: $1 has been extracted\n"; + } + + } + +} # end sub extract + + +# This checks the md5sum for a package if the not-installed database has +# the information. The --arch --dist can be specified until a match is +# made +sub md5sumo { + + my ($commands) = @_; my %commands = %$commands; + + # first grab the md5sum for this package and put it into a temporary file + # to be processed by md5sum + if ($commands->{"md5sum"}) { + + ndb(\%commands); + $argument =~ m,^.*/(.*).deb$,; + my $one = $1; + my (@underlines, $nv); + my $underlines = $1; + my $unc = ($underlines =~ tr/_//); + if ($unc > 1) { + @underlines = split(/_/,$underlines); + $one = $underlines[0] . "_" . $underlines[1]; + } + my $md = $one . "MD"; + if (defined $db{"$md"}) { + # revision: situation + if ($db{"$md"} =~ /REVISION/) { + $md = (split(/\s/,$db{$md}))[0]; + } + open(MD5SUM,">$tmp/md5sum.deb") or die "no such place\n"; + print MD5SUM $db{"$md"}, " $argument\n"; + my $numbers = $db{"$md"}; + close(MD5SUM); + system "$md5sum -c $tmp/md5sum.deb 2> $tmp/md5sumcheck"; + $argument =~ m,^.*/(.*.deb$),; + open(MD5SUMCHECK, "$tmp/md5sumcheck"); + if (!defined ) { + print "$one $numbers OK\n"; + } + else { + while () { + if ($_ !~ /no files checked/) { + if (/failed/) { + print "$one $numbers FAILED\n"; + } + # just in case + elsif (/can't open/) { + print "$one $numbers MISSING\n"; + } + } + } + } + close(MD5SUMCHECK); + } + + + } + + +} # end sub md5sumo + + +# This just shows the name and version of the package if no other options +# are used for -p +sub printme { + + my ($commands) = @_; my %commands = %$commands; + + if ($commands->{"p"} && !($commands->{"i"} || $commands->{"l"} || + $commands->{"df"} || $commands->{"d"} || $commands->{"c"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Package: > $tmp/temp.deb"; + system "perl -pi -e \"s/Package: //\" $tmp/temp.deb"; + } + open (PRINTME,"$tmp/temp.deb"); + while () { + chomp; + print; + } + print "_"; + if (defined $dpkg_deb) { + system "$dpkg_deb", "-f", "$argument", "Version"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Version: > $tmp/temp.deb"; + system "perl -pi -e \"s/Version: //\" $tmp/temp.deb"; + system "$cat", "$tmp/temp.deb"; + } + print "\n"; + } + elsif ($commands->{"p"} && ($commands->{"l"} || $commands{"d"} || + $commands{"c"}) + && !($commands->{"i"} || $commands->{"df"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Package: > $tmp/temp.deb"; + system "perl -pi -e \"s/Package: //\" $tmp/temp.deb"; + } + open (PRINTME,"$tmp/temp.deb"); + while () { + chomp; + print; + } + print "_"; + if (defined $dpkg_deb) { + system "$dpkg_deb", "-f", "$argument", "Version"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Version: > $tmp/temp.deb"; + system "perl -pi -e \"s/Version: //\" $tmp/temp.deb"; + system "$cat", "$tmp/temp.deb"; + } + print "\n"; + } +=pod + +A little over-kill, but leaving this for now, just in case I figure out +that there was a reason for doing it this way. + + elsif ($commands->{"p"} && $commands {"c"} && !($commands->{"i"} || + $commands->{"df"} || $commands->{"d"} || $commands->{"l"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} && + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Package: > $tmp/temp.deb"; + system "perl -pi -e \"s/Package: //\" $tmp/temp.deb"; + } + print "\n"; + open (PRINTME,"$tmp/temp.deb"); + while () { + chomp; + print; + } + print "_"; + if (defined $dpkg_deb) { + system "$dpkg_deb", "-f", "$argument", "Version"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Version: > $tmp/temp.deb"; + system "perl -pi -e \"s/Version: //\" $tmp/temp.deb"; + system "$cat", "$tmp/temp.deb"; + } + } + elsif ($commands->{"p"} && $commands {"c"} && $commands->{"d"} && + !($commands->{"i"} || $commands->{"df"} || $commands->{"l"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Package: > $tmp/temp.deb"; + system "perl -pi -e \"s/Package: //\" $tmp/temp.deb"; + } + print "\n"; + open (PRINTME,"$tmp/temp.deb"); + while () { + chomp; + print; + } + print "_"; + if (defined $dpkg_deb) { + system "$dpkg_deb", "-f", "$argument", "Version"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Version: > $tmp/temp.deb"; + system "perl -pi -e \"s/Version: //\" $tmp/temp.deb"; + system "$cat", "$tmp/temp.deb"; + } + } + elsif ($commands->{"p"} && $commands {"c"} && $commands->{"d"} && + $commands->{"l"} && !($commands->{"i"} || $commands->{"df"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Package: > $tmp/temp.deb"; + system "perl -pi -e \"s/Package: //\" $tmp/temp.deb"; + } + print "\n"; + open (PRINTME,"$tmp/temp.deb"); + while () { + chomp; + print; + } + print "_"; + if (defined $dpkg_deb) { + system "$dpkg_deb", "-f", "$argument", "Version"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar Oxz |\ + $grep Version: > $tmp/temp.deb"; + system "perl -pi -e \"s/Version: //\" $tmp/temp.deb"; + system "$cat", "$tmp/temp.deb"; + } + } +=cut + +} # end sub printme + + +sub copyrighto { + + # maybe + $argument =~ m,(.*\/)(.*$),; + my ($commands) = @_; my %commands = %$commands; + + + if ($commands->{"copyright"}) { + # find everything with change + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar t |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -Ei \"copy|license\" > $tmp/fields.deb"; + + # Maybe just do this once, faster. + # occasionally a changelog is linked to another file..so that file has + # to be used instead, this routine checks for this situation. + system "$dpkg_deb --fsys-tarfile $argument | $tar tv |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -Ei \"copy|license\" > $tmp/linkto.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar tz |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -Ei \"copy|license\" > $tmp/fields.deb"; + + system "$ar -p $argument data.tar.gz | $tar tvz |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -Ei \"copy|license\" > $tmp/linkto.deb"; + } + + my @links; + my $whattodo; + open (LINKTO,"$tmp/linkto.deb") || die "humm, not created"; + while () { + m,.*[\d|to]\s(.*$),; + push(@links,$1); + if (/link to/) { + $whattodo = "yes"; + } + } + if (defined $whattodo) { + open(FIELDS, ">$tmp/fields.deb"); + foreach (@links) { + print FIELDS; + print FIELDS "\n"; + } + close(FIELDS); + } + + + # extract and read the files + chdir("$tmp"); + open(TAR,"$tmp/fields.deb"); + my $name = $2; + while () { + chomp; + # An easier way - xO, for .gz.. | gzip -d or zcat + $_ =~ m,.*\/(.*$),; + my $change = $1; + if ($_ =~ m,\.gz$,) { + print "#####$change for $name#####\n\n"; + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument |\ + $tar xO $_ | gzip -d"; + print "\n"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar xOz $_ | gzip -d"; + print "\n"; + } + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + print "#####$change for $name#####\n\n"; + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar xO $_"; + print "\n"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xOz $_"; + print "\n"; + } + } + } + } + +} # end copyrighto + + + +# we get to use --fsys-tarfile in this one, tar and grep. +sub changelogo { + + # maybe + $argument =~ m,(.*\/)(.*$),; + my ($commands) = @_; my %commands = %$commands; + + + if ($commands->{"changelog"}) { + # find everything with change + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar t |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -i change > $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar tz |\ + $grep -E \"usr/doc\|usr/share/doc\" |\ + $grep -i change > $tmp/fields.deb"; + } + + # Maybe just do this once, faster. + # occasionally a changelog is linked to another file..so that file has + # to be used instead, this routine checks for this situation. + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar tv | $grep usr/doc |\ + $grep -i change > $tmp/linkto.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar tvz | $grep usr/doc |\ + $grep -i change > $tmp/linkto.deb"; + } + + my @links; + my $whattodo; + open (LINKTO,"$tmp/linkto.deb") || die "humm, not created"; + while () { + m,.*[\d|to]\s(.*$),; + push(@links,$1); + if (/link to/) { + $whattodo = "yes"; + } + } + if (defined $whattodo) { + open(FIELDS, ">$tmp/fields.deb"); + foreach (@links) { + print FIELDS; + print FIELDS "\n"; + } + close(FIELDS); + } + + + # extract and read the files + chdir("$tmp"); + open(TAR,"$tmp/fields.deb"); + my $name = $2; + while () { + chomp; + # An easier way - xO, for .gz.. | gzip -d or zcat + $_ =~ m,.*\/(.*$),; + my $change = $1; + if ($_ =~ m,\.gz$,) { + print "#####$change for $name#####\n\n"; + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar xO $_ |\ + gzip -d"; + print "\n"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xOz $_ |\ + gzip -d"; + print "\n"; + } + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + print "#####$change for $name#####\n\n"; + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar xO $_"; + print "\n"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz | $tar xOz $_"; + print "\n"; + } + } + } + } + +} # end changelogo + +# show the menu script from /usr/lib/menu +sub menuo { + + $argument =~ m,(.*\/)(.*$),; + my ($commands) = @_; my %commands = %$commands; + + if ($commands->{"menu"} || $commands->{"m"}) { + # find everything with change + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar t |\ + $grep -E usr/lib/menu/[0-9A-Za-z\+\.-] > $tmp/fields.deb"; + + # extract and read the files + chdir("$tmp"); + open(MENU,"$tmp/fields.deb"); + my $name = $2; + while (

) { + #print "$_\n"; + if (m,^usr\/lib\/menu\/(.*[\w-\+\.]$),) { + print "#####menu for $name($1)#####\n"; + system "$dpkg_deb --fsys-tarfile $argument | $tar xO $_"; + print "\n"; + } + } + close(MENU); + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOz usr/lib/menu/[0-9A-Za-z\+\.-]* 2> $tmp/fields.deb"; + + # extract and read the files + chdir("$tmp"); + open(MENU,"$tmp/fields.deb"); + my $name = $2; + while () { + #print "$_\n"; + if (m,^usr\/lib\/menu\/(.*[\w-\+\.]$),) { + print "#####menu for $name($1)#####\n"; + system "$ar -p $argument data.tar.gz | $tar xOz $_"; + print "\n"; + } + } + close(MENU); + } + } + +} # end sub menuo + + +# grab all the scripts or a particular one +sub scripto { + + my ($commands) = @_; my %commands = %$commands; + $argument =~ m,.*\/(.*)_.*$,; + my $real; + + # Give a title. + if ($commands->{"scripts"} && !($commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerem"} || + $commands->{"postrm"})) { + + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument preinst >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.preinst#####\n"; + $real = system "$dpkg_deb -I $argument preinst"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz preinst >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.preinst#####\n"; + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz preinst"; + undef $real; + } + } + + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument postinst >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.postinst#####\n"; + system "$dpkg_deb -I $argument postinst"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz postinst >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.postinst#####\n"; + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz postinst"; + undef $real; + } + } + + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument prerm >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.prerm#####\n"; + $real = system "$dpkg_deb -I $argument prerm"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz prerm >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.prerm#####\n"; + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz prerm"; + undef $real; + } + } + + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument postrm >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.postrm#####\n"; + $real = system "$dpkg_deb -I $argument postrm"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz postrm >/dev/null 2>&1"; + if ($real == 0) { + print "#####$1.postrm#####\n"; + $real = system "$dpkg_deb -I $argument postrm"; + undef $real; + } + } + } + + # no titles here + if ($commands->{"preinst"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument preinst >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$dpkg_deb -I $argument preinst"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz preinst >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz preinst"; + undef $real; + } + } + } + + if ($commands->{"postinst"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument postinst >/dev/null 2>&1"; + if ($real == 0) { + system "$dpkg_deb -I $argument postinst"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz postinst >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz postinst"; + undef $real; + } + } + } + + if ($commands->{"prerm"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument prerm >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$dpkg_deb -I $argument prerm"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz prerm >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz prerm"; + undef $real; + } + } + } + + if ($commands->{"postrm"}) { + if (defined $dpkg_deb) { + $real = system "$dpkg_deb -I $argument postrm >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$dpkg_deb -I $argument postrm"; + undef $real; + } + } + elsif (defined $ar) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz postrm >/dev/null 2>&1"; + if ($real == 0) { + $real = system "$ar -p $argument control.tar.gz |\ + $tar xOz postrm"; + undef $real; + } + } + } + +} # end scripto + +# this is the format for packages which provide shared libraries. The +# default form is shown, although it would be posibble to show the +# *.so.digits library depends (what version) +sub shlibso { + + my ($commands) = @_; my %commands = %$commands; + + if ($commands->{"shlibs"}) { + if (defined $dpkg_deb) { + my $real = system "$dpkg_deb -I $argument shlibs >/dev/null 2>&1"; + if ($real == 0) { + print "Shlibs:\n"; + system "$dpkg_deb", "-I", "$argument", "shlibs"; + print "\n"; + } + } + elsif (defined $ar) { + my $real = system "$ar -p $argument control.tar.gz |\ + $tar tOz shlibs >/dev/null 2>&1"; + if ($real == 0) { + print "Shlibs:\n"; + system "$ar -p $argument control.tar.gz |\ + tar xOz shlibs"; + print "\n"; + } + } + } + + +} # end shlibso + + +# This presents two types of listings, the default one provided by +# dpkg_deb, and a short listing which equates to what is found in *.list. +# This is important for do it yourself comparison purposes. There is a +# chance a comparison routine will be built into --db in the near future. +sub listing { + + my ($commands) = @_; my %commands = %$commands; + + # These next to print out the verbose ls -la listing when -v is used + if (($commands->{"l"} && $commands->{"v"}) && !$commands->{"d"}) { + if ($commands->{"df"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --contents $argument"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOzv 2> $tmp/fields.deb; \ + $cat $tmp/fields.deb"; + } + } + elsif (!$commands->{"df"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --contents $argument > $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOzv 2> $tmp/fields.deb"; + } + open(LISTING,"$tmp/fields.deb"); + while () { + if ($_ !~ /drwx/) { + print; + } + } + } + } + if (($commands->{"l"} && $commands->{"v"} && $commands->{"d"}) || + $commands->{"d"} && $commands->{"v"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --contents $argument > $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOzv 2> $tmp/fields.deb"; + } + open(LISTING,"$tmp/fields.deb"); + while () { + if (m,usr\/man|usr\/doc|usr\/info, && $_ !~ /drwx/) { + print; + } + } + } + + # These next two print out a short listing + if (($commands->{"l"} && !$commands->{"v"}) && !$commands->{"d"}) { + if ($commands->{"df"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument | $tar t"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOz 2> $tmp/fields.deb; \ + $cat $tmp/fields.deb"; + } + } + elsif (!$commands->{"df"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument |\ + $tar t > $tmp/fields.deb"; + system "$dpkg_deb --fsys-tarfile $argument |\ + $tar tv > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOz 2> $tmp/fields.deb"; + system "$ar -p $argument data.tar.gz |\ + $tar tOzv 2> $tmp/temp.deb"; + } + open(LISTING,"$tmp/fields.deb"); + open(TEMP,"$tmp/temp.deb"); + my(@list,@temp); + @list = ; + @temp = ; + my $count = 0; + foreach (@temp) { + chomp $list[$count]; + print "$list[$count]\n" if $_ !~ /drwx/; + $count++; + } + } + } + if (($commands->{"l"} && !$commands->{"v"} && $commands->{"d"}) || + $commands->{"d"} && !$commands->{"v"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb --fsys-tarfile $argument |\ + $tar t > $tmp/fields.deb"; + system "$dpkg_deb --fsys-tarfile $argument |\ + $tar tv > $tmp/temp.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument data.tar.gz |\ + $tar tOz 2> $tmp/fields.deb"; + system "$ar -p $argument data.tar.gz |\ + $tar tOzv 2> $tmp/temp.deb"; + } + open(LISTING,"$tmp/fields.deb"); + open(TEMP,"$tmp/temp.deb"); + my(@list,@temp); + @list = ; + @temp = ; + my $count = 0; + foreach (@temp) { + chomp $list[$count]; + # the directory check assumes such a directory already exists + if (m,usr\/man|usr\/share\/man|usr\/doc|usr\/share\/doc|usr\/info|usr\/share\/info,) { + print "$list[$count]\n" if $_ !~ /drwx/; + } + $count++; + } + } + + +} # end sub listing + + +# Just to save some room, and handle -T, there is no error returned when a +# field isn't found, so this sub will have to check things out itself. +sub deps { + + my ($commands) = @_; my %commands = %$commands; + + # will print out the .deb part + $argument =~ m,.*\/(.*$),; + my %title; + + if (!$commands->{"T"}) { + if ($commands->{"pre_depends"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Pre-Depends: "; + system "$dpkg_deb -f $argument Pre-Depends"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Pre-Depends: \w*\""; + } + print "\n"; + } + if ($commands->{"depends"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Depends: "; + system "$dpkg_deb -f $argument Depends"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Depends: \w*\""; + } + print "\n"; + } + if ($commands->{"recommends"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Recommends: "; + system "$dpkg_deb -f $argument Recommends"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Recommends: \w*\""; + } + print "\n"; + } + if ($commands->{"suggests"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Suggests: "; + system "$dpkg_deb -f $argument Suggests"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Suggests: \w*\""; + } + print "\n"; + } + if ($commands->{"provides"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Provides: "; + system "$dpkg_deb -f $argument Provides"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Provides: \w*\""; + } + print "\n"; + } + if ($commands->{"replaces"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Replaces: "; + system "$dpkg_deb -f $argument Replaces"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Replaces: \w*\""; + } + print "\n"; + } + if ($commands->{"conflicts"}) { + if (!defined $title{$1}) { + print "$1\n"; + } + $title{$1}++; + if (defined $dpkg_deb) { + print "Conflicts: "; + system "$dpkg_deb -f $argument Conflicts"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz |\ + $tar xOz control | $grep \"Conflicts: \w*\""; + } + print "\n"; + } + } + elsif ($commands->{"T"}) { + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Pre-Depends 2&> $tmp/fields.deb"; + system "$dpkg_deb -f $argument Depends 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Recommends 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Suggests 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Provides 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Replaces 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Conflicts 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Pre-Depends: \w*\" > $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Depends: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Recommends: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Suggests: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Provides: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Replaces: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Conflicts: \w*\" >> $tmp/fields.deb"; + } + + + if (-e "$tmp/fields.deb") { + open (DEPS, "$tmp/fields.deb"); + if (!$commands->{"i"}) { + print "$1\n"; + } + while () { + print; + } + } + close(DEPS); + unlink("$tmp/fields.deb"); + } # elsif T + +} # end sub deps + + +# This takes out the pertinent fields and puts them into the PRETTY format. +# There are more shell calls then one would like..but that's the way it +# goes. An easier way would be to have a extensive available file +# produced from a Packages file, this provides package md5sum. +# This also provides status and section when -f doesn't provide it, and +# already has the right order. +sub shbang { + + # just one call needed here + if (defined $dpkg_deb) { + system "$dpkg_deb -f $argument Package 2&> $tmp/fields.deb"; + system "$dpkg_deb -f $argument Essential 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Priority 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Section 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb;"; + system "$dpkg_deb -f $argument Installed-Size 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb"; + system "$dpkg_deb -f $argument Maintainer 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb"; + system "$dpkg_deb -f $argument Source 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb"; + system "$dpkg_deb -f $argument Version 2&> $tmp/temp.deb; \ + $cat $tmp/temp.deb >> $tmp/fields.deb"; + } + elsif (defined $ar) { + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Package: \w*\" > $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Essential: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Priority: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Section: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Installed-Size: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Maintainer: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Source: \w*\" >> $tmp/fields.deb"; + system "$ar -p $argument control.tar.gz | $tar xOz control |\ + $grep \"Version: \w*\" >> $tmp/fields.deb"; + } +} # end sub shbang + + +# This processes fields from individual Debian packages +sub package_processor { + + my ($commands) = @_; + my %commands = %$commands; + my $count = 0; + my @package; + my $status; + my @essential; + my $priority; + my $section; + my $installed_size; + my $maintainer; + my $source; + + my $format_deb = "$tmp/format.deb"; + my $fields = "$tmp/fields.deb"; + + $~ = "PRETTY"; + #open(PRETTY, ">$format_deb"); + open(AVAIL, "$fields"); + while () { + # here's the difference with database(\%commands), we just find the packages + # which belong to the hash %exacts + # Package name + if (/^Package:|^PACKAGE:/) { + @package = split(/: /,$_); + chomp $package[1]; + } + # no Status: yet + elsif (/^Essential/) { + @essential = split(/: /,$_); + } + elsif (/^Priority:/) { + $priority = $_; + } + elsif (/^Section:/) { + $section = $_; + } + elsif (/^Installed-Size:/) { + $installed_size = $_; + } + elsif (/^Maintainer:/) { + $maintainer = $_; + } + elsif (/^Source:/) { + $source = $_; + } + # hold ok not-installed - may want to change this just to + # non-installed. + elsif (/^Version:/) { + my $version = $_; + my ($same, $different); + my ($vname, $gname, $priorname, $statusname); + chomp $version; + if (defined $section) { + chomp $section; + } + $col1 = "Package: $package[1]"; + # to be made pc, we need to look in sb(\%commands) or nsb(\%commands). + sb(\%commands); + $argument =~ m,.*\/(.*)_[\d\+\.].*$,; + my $pname = $1; + + ############### + # STATUSINDEX # + ############### + # if statusindex is around we will check here, and in + # nstatus* if the version is different, or the information + # is unavailable. + if (defined $pname) { + if (defined $sb{$pname}) { + ($vname,$gname,$priorname,$statusname) = + split(/\s/,"$sb{$pname}",4); + $statusname =~ s/:/ /g; + # a way to test + #$version = "Version: 1:5.0-2"; + my $pver = substr($version,9); + my $cname = $pname . "_" . $pver; + if ($vname eq $cname) { + $status = "Status: $statusname\n"; + $same = "yes"; undef($different); + } + else { + # here's where we get to do some comparisons + # we will have to compare sections. 1). may have changed + # 2). may be an unfair comparison free vs non-free, on the + # other-hand this should be in the person's awareness + # making the check. 1) will provide the answer to both. + $vname =~ m,^.*_(.*)$,; + my $ever = $1; + $status = + "Status: " . comparison($pver,$ever) . " $statusname ($ever)\n"; + $different = "yes"; undef($same); + } + } + else { + $status = "Status: not-installed\n"; + } + } + $col2 = $status; + write STDOUT; + $col1 = $version; + my $ver = m,Version:\s(.*),; + my $verzion = $1; + $package[1] = "$package[1]_$1"; + if(defined($essential[1])) { + $col2 = "Essential: $essential[1]"; + @essential = (\%commands); + } + else { + $col2 = "Essential: no\n"; + } + write STDOUT; + # We will try to fill things in for Section: and Priority: + if (defined $section) { + $col1 = $section; + } + else { + if (defined $same) { + if ($gname eq "unavailable") { + nsb(\%commands); + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col1 = "Section: $ngname"; + } + } + else { + $col1 = "Section: $gname"; + } + } + elsif (defined $different) { + # look first in available, and next in a specified Packages + # file, we will also compare this to the existing Section, + # because this is known to change. + nsb(\%commands); + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col1 = "Section: $ngname"; + } + else { + $col1 = "Section: unavailable"; + } + } + else { + # This may be in available or Packages + nsb(\%commands); + if (defined $pname) { + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col1 = "Section: $ngname"; + } + else { + $col1 = "Section: unknown"; + } + } + } + } + if (defined $priority) { + $col2 = $priority; + } + else { + if (defined $same ) { + if ($gname eq "unavailable") { + nsb(\%commands); + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col2 = "Priority: $npriorname"; + } + } + else { + $col2 = "Priority: $priorname\n"; + } + } + elsif (defined $different) { + # look first in available, and next in a specified Packages + # file + nsb(\%commands); + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col2 = "Priority: $npriorname"; + } + else { + $col2 = "Priority: unavailable\n"; + } + } + else { + # This is not in available or Packages + nsb(\%commands); + if (defined $pname) { + if (defined $nsb{$pname}) { + my ($nvname,$ngname,$npriorname) = + split(/\s/,"$nsb{$pname}",3); + $col2 = "Priority: $npriorname"; + } + else { + $col2 = "Priority: unknown\n"; + } + } + } + + } + write STDOUT; + #my $cool = $installed_size . $maintainer; + $col1 = $installed_size; + if (defined $source) { + $col2 = $source; + } + else { + $col2 = ""; + } + write STDOUT; + undef $source; + print STDOUT $maintainer; + } + } # end while AVAIL + close(PRETTY); + + unlink($format_deb); + +} # end sub package_processor + + + + +1; diff --git a/lib/Deps.pm b/lib/Deps.pm new file mode 100644 index 0000000..12c1741 --- /dev/null +++ b/lib/Deps.pm @@ -0,0 +1,456 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Deps; +use strict; +use SWIM::Global qw(:Info); +use SWIM::DB_Library qw(:Xyz); +use vars qw(@ISA @EXPORT); +@ISA = qw(Exporter); +@EXPORT = qw(character s_character which_character the_character); + +# the -T and siblings + +# process the database for replaces +sub replaces { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "REP"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub replaces + +# process the database for provides +sub provides { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "PRO"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub provides + +# process the database for depends +sub depends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "DEP"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub depends + +# process the database for replaces +sub pre_depends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "PRE"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub pre_depends + +# process the database for replaces +sub recommends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "REC"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub recommends + +# process the database for replaces +sub suggests { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "SUG"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub suggests + +# process the database for replaces +sub conflicts { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "CON"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return ""; } + } + untie %db; +} # end sub conflicts + +#These subroutines are for cases where only packages related to the +# characteristics are printed out. +# process the database for replaces +sub s_replaces { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "REP"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_replaces + +# process the database for provides +sub s_provides { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "PRO"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_provides + +# process the database for depends +sub s_depends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "DEP"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_depends + +# process the database for replaces +sub s_pre_depends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "PRE"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_pre_depends + +# process the database for replaces +sub s_recommends { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "REC"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_recommends + +# process the database for replaces +sub s_suggests { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "SUG"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_suggests + +# process the database for replaces +sub s_conflicts { + my ($commands) = @_; + my %commands = %$commands; + !$commands->{"n"} ? dbi(\%commands) : ndb(\%commands); + if (defined $argument) { + my $conf = $argument . "CON"; + if (defined $db{$conf}) { + return "$argument\n$db{$conf}"; + } + else { return ""; } + } + untie %db; +} # end sub s_conflicts + + +# This figures out which characteristics (Replaces, Provides, etc) the +# options are pointing to. Isn't choosey, prints all packages +sub character { + + my ($commands) = @_; + my %commands = %$commands; + + # for singular cases + if ($commands->{"g"} && ($commands->{"T"} || $commands->{"pre_depends"} || + $commands->{"depends"} || $commands->{"recommends"} || + $commands->{"suggests"} || $commands->{"provides"} || + $commands->{"replaces"} || $commands->{"conflicts"}) && + !($commands->{"c"} || $commands->{"d"} || $commands->{"l"} || + $commands->{"i"})) { + print "$argument\n"; + } + + # all the characteristics + if (defined $commands->{"T"}) { + print pre_depends(\%commands); + print depends(\%commands); + print recommends(\%commands); + print suggests(\%commands); + print provides(\%commands); + print replaces(\%commands); + print conflicts(\%commands); + } + else { + + if (defined $commands->{"pre_depends"}) { + print pre_depends(\%commands); + delete $commands{"pre_depends"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"depends"}) { + print depends(\%commands); + delete $commands{"depends"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"recommends"}) { + print recommends(\%commands); + delete $commands{"recommends"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"suggests"}) { + print suggests(\%commands); + delete $commands{"suggests"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"replaces"}) { + print replaces(\%commands); + delete $commands{"replaces"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"provides"}) { + print provides(\%commands); + delete $commands{"provides"} if !($commands->{"S"} || $commands->{"g"}); + } + + if (defined $commands->{"conflicts"}) { + print conflicts(\%commands); + delete $commands{"conflicts"} if !($commands->{"S"} || $commands->{"g"}); + } + } + +} # end sub character + +# Prints out the characteristics only for the packages which have them. +sub s_character { + + my ($commands) = @_; + my %commands = %$commands; + + if ($commands->{"pre_depends"}) { + print s_pre_depends(\%commands); + delete $commands{"pre_depends"}; + if (s_pre_depends(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"depends"}) { + print s_depends(\%commands); + delete $commands{"depends"}; + if (s_depends(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"recommends"}) { + print s_recommends(\%commands); + delete $commands{"recommends"}; + if (s_recommends(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"suggests"}) { + print s_suggests(\%commands); + delete $commands{"suggests"}; + if (s_suggests(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"replaces"}) { + print s_replaces(\%commands); + delete $commands{"replaces"}; + if (s_replaces(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"provides"}) { + print s_provides(\%commands); + delete $commands{"provides"}; + if (s_provides(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + elsif ($commands->{"conflicts"}) { + print s_conflicts(\%commands); + delete $commands{"conflicts"}; + if (s_conflicts(\%commands) ne "") { + character(\%commands); + } +# else { s_character(\%commands) } + } + + # all the characteristics + if ($commands->{"T"}) { + print s_pre_depends(\%commands); + print s_depends(\%commands); + print s_recommends(\%commands); + print s_suggests(\%commands); + print s_provides(\%commands); + print s_replaces(\%commands); + print s_conflicts(\%commands); + } + + +} # end sub s_character + + +# helps to determine if character(\%commands) should be used +sub which_character { + my ($commands) = @_; + if ($commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"replaces"} || $commands->{"provides"} || + $commands->{"conflicts"}) { + return 1; + } +} # end sub which_character + +# This runs a test to see whether or not the characters being asked for +# apply to this package. +sub the_character { + + my ($commands) = @_; + my %commands = %$commands; + + if (defined $commands->{"pre_depends"}) { + if (pre_depends(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"depends"}) { + if (depends(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"recommends"}) { + if (recommends(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"suggests"}) { + if (suggests(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"replaces"}) { + if (replaces(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"provides"}) { + if (provides(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + + if (defined $commands->{"conflicts"}) { + if (conflicts(\%commands) eq "") { + print ""; + } + else { return "ok"; } + } + +} # end sub the_character + +1; diff --git a/lib/Dir.pm b/lib/Dir.pm new file mode 100644 index 0000000..6452915 --- /dev/null +++ b/lib/Dir.pm @@ -0,0 +1,110 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Dir; +use strict; +use SWIM::Global qw($argument); +use SWIM::Conf qw($pwd); +use vars qw(@ISA @EXPORT @EXPORT_OK); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(dir fir); + +# dir() fir() + +# When --dir is used checks argument (when -f is called) and determines dir +# stuff..is it real or not. +sub dir { + + my ($commands) = @_; + + if ($commands->{"dir"}) { + if (! -d $argument) { + if (! -e $argument) { + print "$argument is not a directory or file\n"; + } + else { + print "$argument is not a directory\n"; + } + exit; + } + elsif ($argument =~ m,\/$,) { + if ($argument !~ m,^\/,) { + if ($pwd =~ m,^\/$,) { + $argument =~ m,(.*)\/$,; + $argument = "$pwd$1"; + } + else { + $argument =~ m,(.*)\/$,; + $argument = "$pwd/$1"; + } + } + else { + $argument =~ m,(.*)\/$,; + $argument = $1; + } + } + elsif ($argument !~ m,\/$|^\/, && $argument =~ m,\/,) { + if ($pwd =~ m,^\/$,) { + $argument = "/$argument"; + } + else { + $argument = "$pwd/$argument"; + } + } + } +} # end sub dir + +# when --dir isn't called...does the same thing as dir. +sub fir { + + my ($commands) = @_; + + if ($argument =~ m,\/$,) { + # Let's test to see whether it really is a file or directory. + if (! -d $argument) { + print "$argument is not a file\n"; + exit; + } + if ($argument !~ m,^\/,) { + if ($pwd =~ m,^\/$,) { + $argument =~ m,(.*)\/$,; + $argument = "$pwd$1"; + } + else { + $argument =~ m,(.*)\/$,; + $argument = "$pwd/$1"; + } + } + else { + $argument =~ m,(.*)\/$,; + $argument = $1; + } + } + elsif ($argument !~ m,\/$|^\/, && $argument =~ m,\/,) { + if ($pwd =~ m,^\/$,) { + $argument = "/$argument"; + } + else { + $argument = "$pwd/$argument"; + } + } +} # end sub fir + +1; + diff --git a/lib/F.pm b/lib/F.pm new file mode 100644 index 0000000..a63ecce --- /dev/null +++ b/lib/F.pm @@ -0,0 +1,92 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::F; +use Carp; +use strict; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(get); + + +# This is Net::FTP::get with minor modifications. Not all the features +# are used, but are kept, just in case they will be. + +sub get +{ + my($ftp,$remote,$local,$where) = @_; + + my($loc,$len,$buf,$resp,$localfd,$data); + local *FD; + $| = 1; + $localfd = ref($local) ? fileno($local) + : undef; + + ($local = $remote) =~ s#^.*/## + unless(defined $local); + + ${*$ftp}{'net_ftp_rest'} = $where + if ($where); + + delete ${*$ftp}{'net_ftp_port'}; + delete ${*$ftp}{'net_ftp_pasv'}; + + $data = $ftp->retr($remote) or + return undef; + + if(defined $localfd) + { + $loc = $local; + } + else + { + $loc = \*FD; + + unless(($where) ? open($loc,">>$local") : open($loc,">$local")) + { + carp "Cannot open Local file $local: $!\n"; + $data->abort; + return undef; + } + } + + if($ftp->type eq 'I' && !binmode($loc)) + { + carp "Cannot binmode Local file $local: $!\n"; + $data->abort; + return undef; + } + + $buf = ''; my $amt = 0; + #print "\n"; + do + { + $len = $data->read($buf,1024); + $amt = $len + $amt; + print "[$amt]\r"; + } + while($len > 0 && syswrite($loc,$buf,$len) == $len); + + close($loc) + unless defined $localfd; + + $data->close(); # implied $ftp->response + + return $local; +} diff --git a/lib/File.pm b/lib/File.pm new file mode 100644 index 0000000..d17d510 --- /dev/null +++ b/lib/File.pm @@ -0,0 +1,877 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::File; +use strict; +use SWIM::Global; +use SWIM::DB_Library qw(:Xyz ram_on nsb); +use SWIM::Library; +use SWIM::Conf qw(:Path $md5sum); +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(file); + + +#=pod +# +#This provides the list of files belonging to a package. Although a +#database could be used..it's probably faster, and cheaper on space +#accessing from the /var/lib/dpkg/info* files. And if --md5sum is +#called, the md5sums are shown for the -d ,-l, or -c files they exist for. +#md5sums are checked for, and reported back as OK or FAILED. -l or +#-d(overrides l). -qd(l) md5sum from RH has a slightly different +#output.. filepath/filename: file OK before swim's output..this can be +#altered +# +#=end + +sub file { + + + my ($commands) = @_; + my %commands = %$commands; + + my $file; + my $md5; + my @md5; + my $path; + my @path; + my $md5sums; + my $md5sums_conf; + my %md5sums = (); + my $orig_argument; + my $count = 0; + + + if (!$commands->{"n"}) { + dbi(\%commands); + } + # files/dirs will be found from contents.deb (compressed) + else { + ndb(\%commands); + } + + if (defined $argument) { + if ($argument =~ /_/) { + my $check; + if (defined $db{"$argument"}) { + $check = $db{"$argument"}; + } + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {} + } + } + + + + if (defined $argument) { + if (!$commands->{"n"}) { + $file = "$parent$base/info/$argument.list"; + if (-e "$parent$base/info/$argument.md5sums") { + $md5sums = "$parent$base/info/$argument.md5sums"; + } + if (-e "$parent$base/info/$argument-conf.md5sums" && $commands->{"c"}) { + $md5sums_conf = "$parent$base/info/$argument-conf.md5sums"; + } + + + ################## + # MD5SUMS FOR -C # + ################## + if ($commands->{"md5sum"} && $commands->{"c"} && !($commands->{"d"} || + $commands->{"l"})) { + if (!defined $md5sums_conf && $commands->{"c"}) { + $md5sums_conf = make_conf(\%commands); + } + # now we can process $md5sums and $md5sums_conf assuming one or + # both actually exist + if (defined $md5sums_conf) { + chdir("/"); + my %path; + open (MD5SUM, "$md5sums_conf"); + open (MD5SUMCHECK, "|$md5sum -c 2>$tmp/md5sumcheck"); + while () { + if ($_ =~ /newconffile/) { + $path = substr($_, 13); + push(@path,$path); + $md5 = substr($_, 0, 11); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"$path"} = $md5; + print MD5SUMCHECK $_; + next; + } + $path = substr($_, 34); + push(@path,$path); + $md5 = substr($_, 0, 32); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"$path"} = $md5; + print MD5SUMCHECK $_; + } + close(MD5SUMCHECK); + close(MD5SUM); + #now check with md5sum from the dpkg package + my $check_md5sum; + # won't bother going into this while unless there is a reason + if (defined "$tmp/md5sumcheck" && $md5 ne "newconffile") { + open(MD5SUMFILE, "$tmp/md5sumcheck"); + while () { + if ($_ !~ /no files checked/) { + if (/failed/) { + # Humm may be two situations watch or due to coding change + #$check_md5sum = substr($_,39); + $check_md5sum = substr($_,30); + $check_md5sum =~ s/'//; + chomp $check_md5sum; + $md5sums{"$check_md5sum"} = "FAILED"; + } + elsif (/can't open/) { + # Humm may be two situations watch or due to coding change + #$check_md5sum = substr($_,28); + $check_md5sum = substr($_,19); + chomp $check_md5sum; + $md5sums{"$check_md5sum"} = "MISSING"; + } + } + } + } + close(MD5SUMCHECK); + unlink("$tmp/md5sumcheck"); + # This finishes everything + open (LIST,"$md5sums_conf"); + while () { + if ($_ =~ /newconffile/) { + $_ = substr($_, 13); + chomp; + } + else { + $_ = substr($_, 34); + chomp; + } + if (defined $path{$_}) { + # humm file_now() not necessary here + if (defined $md5sums{$_}) { + print " /$_ $path{$_} $md5sums{$_}\n"; + } + elsif ($path{$_} ne "newconffile") { + print " /$_ $path{$_} OK"; + print "\n"; + } + else { + print " /$_ $path{$_}\n"; + } + } + } # last while + close(LIST); + %md5sums = (); + %path = (); + @path = (); + @md5 = (); + } # do the md5sum files even exist? + } + + ######################## + # MD5SUMS FOR -C &| -L # + ######################## + # checking for -e $md5sums is a questionable practice because it + # may not exist, but the conf files do. + if ($commands->{"md5sum"} && !$commands->{"d"} && + (($commands->{"l"} && $commands->{"c"}) || $commands->{"l"})) { + # I decided on three while loops, because it was the most practical + # way to handle STDERR from md5sum, and all types of + # experimentation didn't yield a better way of doing it, but there + # is probably a better way. + # first do things normally, and no chomping + # but, first grab conf info. + if (!defined $md5sums_conf && $commands->{"c"}) { + $md5sums_conf = make_conf(\%commands); + } + # now we can process $md5sums and $md5sums_conf assuming one or + # both actually exist + if (defined $md5sums || defined $md5sums_conf) { + #if ($md5sums_conf ne 1) { + chdir("/"); + my %path; + if ($commands->{"c"} && $md5sums_conf) { + open (MD5SUM,"$md5sums_conf"); + } + else { + open (MD5SUM,"$md5sums"); + $count = 1; + } + while ($count <= 1) { + if (($count == 1 && defined $md5sums) || $count == 0) { + open (MD5SUMCHECK, "|$md5sum -c 2>$tmp/md5sumcheck"); + while () { + if ($_ =~ /newconffile/) { + $path = substr($_, 13); + push(@path,$path); + $md5 = substr($_, 0, 11); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"/$path"} = $md5; + print MD5SUMCHECK $_; + next; + } + $path = substr($_, 34); + push(@path,$path); + $md5 = substr($_, 0, 32); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"/$path"} = $md5; + print MD5SUMCHECK $_; + } + close(MD5SUMCHECK); + close(MD5SUM); + #now check with md5sum from the dpkg package + my $check_md5sum; + #my $count = 0; + # won't bother going into this while unless there is a reason + if (defined "$tmp/md5sumcheck" && $md5 ne "newconffile") { + open(MD5SUMFILE, "$tmp/md5sumcheck"); + while () { + if ($_ !~ /no files checked/) { + if (/failed/) { + $check_md5sum = substr($_,30); + $check_md5sum =~ s/'//; + chomp $check_md5sum; + $md5sums{"/$check_md5sum"} = "FAILED"; + } + elsif (/can't open/) { + $check_md5sum = substr($_,19); + #$check_md5sum =~ s/'//; + chomp $check_md5sum; + $md5sums{"/$check_md5sum"} = "MISSING"; + } + } + } + } + close(MD5SUMCHECK); + unlink("$tmp/md5sumcheck"); + } + # This finishes everything + # This prunes stuff out and assumes that *.list and *.md5sums + # overlap. + open (LIST,"$file"); + ###### + # -L # + ###### + if ($commands->{"l"} && !$commands->{"df"}) { + while () { + chomp; + if (!-d $_ && $argument ne "base-files") { + my $line = $_; + file_now(\%commands); + md5_print(\%path,\%md5sums,$line,$count); + } + ############## + # BASE-FILES # + ############## + elsif ($argument eq "base-files") { + my $line = $_; + md5_print(\%path,\%md5sums,$line,$count); + } + } # last while + } + ############# + # -L & --DF # + ############# + elsif ($commands->{"l"} && $commands->{"df"}) { + while () { + chomp; + my $line = $_; + file_now(\%commands); + md5_print(\%path,\%md5sums,$line,$count); + } # last while + } + close(LIST); + %md5sums = (); + %path = (); + @path = (); + @md5 = (); + $count++; + if ($count == 1) { + open (MD5SUM,"$md5sums") if $md5sums; + } + } # loop through -c or not + } # do the md5sum files even exist? + #} + } + #@@ got to watch this for -l's called directly, will allow -l to + # be seen whether or not --md5sum is used, changed elsif to if. + # if already found above don't use below here. + # && ||'s tricky here + if (-e $file && !$commands->{"d"} && (!defined $md5sums && + !defined $md5sums_conf) || -e $file && + (!$commands->{"md5sum"} && !$commands->{"d"})) { + file_now(\%commands) if !$commands->{"f"}; + open (LIST,"$file"); + while () { + chomp; + if ($commands->{"l"} && !$commands->{"df"}) { + if (!-d $_ && $argument ne "base-files") { + print "$_\n"; + } + elsif ($argument eq "base-files") { + print "$_\n"; + } + } + elsif ($commands->{"l"} && $commands->{"df"}) { + if ($argument ne "base-files") { + print "$_\n"; + } + elsif ($argument eq "base-files") { + print "$_\n"; + } + } + } + } + + ######################## + # MD5SUMS FOR -C &| -D # + ######################## + # for Documentation. + elsif ($commands->{"md5sum"} && ($commands->{"d"} || ($commands->{"d"} && + $commands->{"c"}))) { + if (!defined $md5sums_conf && $commands->{"c"}) { + $md5sums_conf = make_conf(\%commands); + } + # now we can process $md5sums and $md5sums_conf assuming one or + # both actually exist + if (defined $md5sums || defined $md5sums_conf) { + chdir("/"); + my %path; + if ($commands->{"c"} && $md5sums_conf) { + open (MD5SUM,"$md5sums_conf"); + } + else { + open (MD5SUM,"$md5sums"); + $count = 1; + } + while ($count <= 1) { + if (($count == 1 && defined $md5sums) || $count == 0) { + open (MD5SUMCHECK, "|$md5sum -c 2>$tmp/md5sumcheck"); + while () { + if ($_ =~ /newconffile/) { + $path = substr($_, 13); + push(@path,$path); + $md5 = substr($_, 0, 11); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"/$path"} = $md5; + print MD5SUMCHECK $_; + next; + } + $path = substr($_, 34); + push(@path,$path); + $md5 = substr($_, 0, 32); + push(@md5,$md5); + chomp $path; + chomp $md5; + $path{"/$path"} = $md5; + print MD5SUMCHECK $_; + } + close(MD5SUMCHECK); + close(MD5SUM); + #now check with md5sum from the dpkg package + my $check_md5sum; + # won't bother going into this while unless there is a reason + if (defined "$tmp/md5sumcheck") { + open(MD5SUMFILE, "$tmp/md5sumcheck"); + while () { + if ($_ !~ /no files checked/) { + if (/failed/) { + $check_md5sum = substr($_,30); + $check_md5sum =~ s/'//; + chomp $check_md5sum; + $md5sums{"/$check_md5sum"} = "FAILED"; + } + elsif (/can't open/) { + $check_md5sum = substr($_,19); + chomp $check_md5sum; + $md5sums{"/$check_md5sum"} = "MISSING"; + } + } + } + } + close(MD5SUMCHECK); + unlink("$tmp/md5sumcheck"); + } + # This finishes everything + open (LIST,"$file"); + while () { + chomp; + # humm, checking for existence? + #if (-e $_ && $argument ne "base-files") { + if ($argument ne "base-files") { + #@@ + ###### + # -D # + ###### + if (defined $path{$_}) { + if (defined $md5sums{$_}) { + if ($count == 0) { + print " $_ $path{$_} $md5sums{$_}" if $count == 0; + print "$_ $path{$_} $md5sums{$_}" if $count == 1; + print "\n"; + } + elsif (m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, && + $count == 1) { + print " $_ $path{$_} $md5sums{$_}" if $count == 0; + print "$_ $path{$_} $md5sums{$_}" if $count == 1; + print "\n"; + } + } + elsif ($path{$_} ne "newconffile") { + if ($count == 0) { + print " $_ $path{$_} OK" if $count == 0; + print "$_ $path{$_} OK" if $count == 1; + print "\n"; + } + elsif (m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, && + $count == 1) { + print " $_ $path{$_} OK" if $count == 0; + print "$_ $path{$_} OK" if $count == 1; + print "\n"; + } + } + else { + if ($count == 0) { + print " $_ $path{$_}\n" if $count == 0; + print "$_ $path{$_}\n" if $count == 1; + print "\n"; + } + elsif (m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, && + $count == 1) { + print " $_ $path{$_} OK" if $count == 0; + print "$_ $path{$_} OK" if $count == 1; + print "\n"; + } + } + } + elsif ($count == 1) { + if (m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, && !-d) { + file_now(\%commands); + print "$_\n"; + } + } + } + # humm? treated specially, hopefully. + ###################### + # BASE-FILES PACKAGE # + ###################### + elsif ($argument eq "base-files") { + my $line = $_; + if ($line =~ m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, || + defined $path{$line}) { + md5_print(\%path,\%md5sums,$line,$count); + } + } + } # another while + close(LIST); + %md5sums = (); + %path = (); + @path = (); + @md5 = (); + $count++; + if ($count == 1) { + open (MD5SUM,"$md5sums") if $md5sums; + } + } # loop through -c or not + } # do the md5sum files even exist? + } + #@@ another important change, print --md5sum and -l together + if (-e $file && $commands->{"d"} && (!defined $md5sums && + !defined $md5sums_conf) || -e $file && + (!$commands->{"md5sum"} && $commands->{"d"})) { + file_now(\%commands) if !$commands->{"f"}; + #if (-e $file && $commands->{"d"}) { + open (LIST,"$file"); + while () { + chomp; + if (m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/, && !-d) { + print "$_\n"; + } + } + } + else { + #if (!defined $md5sums || !defined $md5sums_conf) { + if (!-e $file) { + print "package $argument is not installed\n"; + } + } + } # if !--n + else { + # Let's check first if this package actually exists, files are checked + # earlier. + if (defined $argument) { + if (!defined $db{"$argument"}) { + print "package $argument is not installed\n"; + exit; + } + } + nfile(\%commands); + } + } # if defined $argument + + untie %db; + + + if (defined $file_now && !($commands->{"z"} || + $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"})) { + if ($commands{"x"} || $commands{"ftp"} || $commands{"source"} || + $commands{"source_only"} || $commands{"remove"} || + $commands{"r"} || $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + + +} # end sub file + +# this manages situation involving -qlcx & -qglx +sub file_now { + + my ($commands) = @_; + my %commands = %$commands; + + #if (!$commands->{"g"} && !defined $file_now) { + if (!$commands->{"g"}) { + if ($arg_count < $#ARGV) { + push(@arg_holder,$argument); + # humm + #@PACKAGES = "DEFINEDONE"; + #@PACKAGES = "$ARGV[$#ARGV]"; + $arg_count++; + } + else { + @PACKAGES = @arg_holder; + push(@PACKAGES,$argument); + } + } + else { + if ($arg_count < $#stuff) { + push(@arg_holder,$argument); + #$arg_count++; + } + else { + @PACKAGES = @arg_holder; + push(@PACKAGES,$argument); + } + } + +} # end file_now + +# In order to run a md5sum test on configuration files directly recognized +# by dpkg, a file with package_name-conf.md5sums is created, in addition to +# any existing package_name.md5sums file. +sub make_conf { + + my ($commands) = @_; + my %commands = %$commands; + + my $md5sums_conf; + if (!$commands->{"n"}) { + dbi(\%commands); + } + # humm, just a trap + else { + ndb(\%commands); + } + + if ($argument !~ /_/ ) { + # I guess we can stop here here is there are no configuration + # files + if (defined $db{$argument}) { + require SWIM::Info; + SWIM::Info->import(qw(conf)); + my $orig_argument = $argument; + $argument = $db{$argument}; + my ($conf, @conf, %conf); + my ($m5, $dir, $thing); + if (conf(\%commands) ne 0) { + $conf = conf(\%commands); + @conf = split(/\n/, $conf); + open(PACKCONF,">$parent$base/info/$orig_argument-conf.md5sums"); + foreach (@conf) { + $_ =~ m,( \/)(.*$),; + ($dir, $m5) = split(/ /, $2, 2); + $thing = "$m5 $dir\n"; + print PACKCONF $thing; + } + close(PACKCONF); + $md5sums_conf = + "$parent$base/info/$orig_argument-conf.md5sums"; + return $md5sums_conf; + } + else { + return; + } + } + } + untie %db; + +} # end sub make_conf + + +# prints out the results from the md5sum test for -l & -l --df +sub md5_print { + + my ($path, $md5sums, $line, $count) = @_; + + if (defined $path->{$line}) { + if (defined $md5sums->{$line}) { + print " $line $path->{$line} $md5sums->{$line}" if $count == 0; + print "$line $path->{$line} $md5sums->{$line}" if $count == 1; + print "\n"; + } + elsif ($path->{$line} ne "newconffile") { + print " $line $path->{$line} OK" if $count == 0; + print "$line $path->{$line} OK" if $count == 1; + print "\n"; + } + else { + print " $line $path->{$line}\n" if $count == 0; + print "$line $path->{$line}\n" if $count == 1; + } + } + elsif ($count == 1) { + print "$line\n"; + } + +} # end md5_print + + +# -n The list of files/dirs belonging to a package. No md5sum here. +sub nfile { + + my ($commands) = @_; + my %commands = %$commands; + my $ramdisk = ram_on(\%commands); + + # Here's a case where gnu grep is faster than using open. + if ($ramdisk eq "yes") { + my $what = "yes"; + process_nfile($what,\%commands); + } # if ramdisk + + elsif ($ramdisk eq 1) { + my $what = "no"; + process_nfile($what,\%commands); + } + +} # end sub nfile + +# -n figure out --df, -d & -l using the contents db +sub process_nfile { + + my ($what,$commands) = @_; + my %commands = %$commands; + my $contentsdb = finddb(\%commands); + my ($arch,$dist) = which_archdist(\%commands); + my ($Contents,$subject); + + + # the + solution + nsb(\%commands); + $subject = (split(/\s/,$nsb{$argument}))[1]; + $argument =~ s,\+,\\\\+,g if $argument =~ m,\+,; + untie %nsb; + + if ($what eq "no") { + if (-e "$contentsdb/ncontentsindex$arch$dist.deb.gz") { + $Contents = "zgrep -E $argument\ $contentsdb/ncontentsindex$arch$dist.deb.gz|"; + } + else { + print "swim: stopping, cannot perform this operation without contents\n"; + exit; + } + } + elsif ($what eq "yes") { + if (-e "$contentsdb/dramdisk/ncontentsindex$arch$dist.deb.gz") { + $Contents = "zgrep -E $argument\ $contentsdb/dramdisk/ncontentsindex$arch$dist.deb.gz|"; + } + else { + print "swim: stopping, cannot perform this operation without contents\n"; + exit; + } + } + + + my($dirfile,$package,@dirfile,@comma,%all,%again); + open(CONTENTSDB, "$Contents"); + while () { + # changed for >= 0.2.9 - will have to watch for these + # guys net/sendfile, x11/xscreensaver, x11/xscreensaver, + # graphics/ucbmpeg, admin/cfengine .. there is a space before them + #if (/^FILE\s*LOCATION$/) { + #while () { + if (!$commands->{"df"}) { + # this isn't acurate for groups of packages ,,, so will use the + # subject section instead of \b and $ + $argument =~ s,\\\\+,\\\+,g if $argument =~ m,\+,; + if (m,$subject/$argument,) { + ###################### + # DOESN'T END WITH / # + ###################### + if ($_ !~ m,.*/\s+\w*,) { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + $dirfile = "/$dirfile"; + ###### + # -L # + ###### + if (!$commands->{"d"} && $commands->{"l"}) { + print "$dirfile\n"; + } + ###### + # -D # + ###### + elsif ($commands->{"d"}) { + if ($dirfile =~ m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/,) { + print "$dirfile\n"; + } + } + } + } + } + ######## + # --DF # + ######## + elsif ($commands->{"df"} && $commands->{"l"} && !$commands->{"d"}) { + $argument =~ s,\\\\+,\\\+,g if $argument =~ m,\+,; + if (m,$subject/$argument,) { + #if (m,\b$argument\b,) { + + ###################### + # ENDS WITH / # + ###################### + if (m,.*/\s+\w*,) { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); $dirfile =~ s,/$,,; + } + ###################### + # DOESN'T END WITH / # + ###################### + else { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); + } + ########################### + # PROCESS INTO FILES/DIRS # + ########################### + my ($count,$holder); + for ($count = 0; $count <= $#dirfile; $count++) { + if ($count == 0) { + $holder = "/$dirfile[$count]"; + my $again = "$dirfile[$count]"; + my $all = "/."; + $again{$again}++; + $all{$all}++; + if ($all{$all} == 1) { + print "/.\n"; + } + if ($again{$again} == 1) { + print "/$dirfile[$count]\n"; + } + } + else { + $holder = $holder . "/$dirfile[$count]"; + my $again = "$holder"; + $again{$again}++; + if ($again{$again} == 1) { + print "$holder\n"; + } + } + } # end for + } + } + ################### + # -D & --DF &| -L # + ################### + elsif (($commands->{"d"} && $commands->{"df"}) || + $commands->{"d"} && $commands->{"df"} && $commands->{"l"}) { + $argument =~ s,\\\\+,\\\+,g if $argument =~ m,\+,; + if (m,$subject/$argument,) { + #if (m,\b$argument$,) { + + ###################### + # DOESN'T END WITH / # + ###################### + if ($_ !~ m,.*/\s+\w*,) { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + $dirfile = "/$dirfile"; + ###### + # -D # + ###### + if ($dirfile =~ m,/usr/doc/|/usr/share/doc/|/man[\d]/|/usr/info/|/usr/share/info/,) { + print "$dirfile\n"; + } + } + } + } + #} + #} + } # while + close(CONTENTSDB); + +} + + +1; diff --git a/lib/Findex.pm b/lib/Findex.pm new file mode 100644 index 0000000..3cf8a98 --- /dev/null +++ b/lib/Findex.pm @@ -0,0 +1,358 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Findex; +use strict; +use SWIM::Global; +use SWIM::Conf qw($my_number); +use SWIM::DB_Library qw(:Xyz ib nib nsb); +use SWIM::Info; +use SWIM::Deps; +use SWIM::Dir; +use vars qw(@ISA @EXPORT_OK); +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(findexer qindexer); + + +# findexer(\%commands) and qindexer used for -a -n -f + +# query filelist for file name.. -qfl -qal, but not -qfl(d)c ... actually +# yes... -qlfd under certain conditions, but not with -c. And -T and +# singular capabilities. +sub findexer { + + my ($commands) = @_; + my %commands = %$commands; + my @alot; + require SWIM::File; + SWIM::File->import(qw(file)); + + + if (!$commands->{"n"}) { + ib(\%commands); + } + else { + my $return = nib(\%commands); + if (!defined $return && $commands->{"a"}) { + untie %ib; + nsb(\%commands); + $ib{"/."} = $nsb{"/."}; + } + } + + if (defined $argument) { + if ($commands->{"dir"}) { + dir(\%commands); + } + elsif ($commands->{"f"}) { + fir(\%commands); + } + if ($ib{"$argument"}){ + my $package = $ib{"$argument"}; + @alot = split(/\s/, $package); + @PACKAGES = @alot; + if ($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @alot = @PACKAGES; + if ($commands->{"total"} || $commands->{"t"}) { + if ($commands->{"T"}) { + foreach (@alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + # nice to print package names before file listings + if (!$commands->{"i"} || !$commands->{"d"} || !$commands->{"c"}) { + print "$argument\n"; + } + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + } + } # if -T + elsif (which_character(\%commands)) { + foreach (@alot) { + my %store_commands = %commands; + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (the_character(\%commands) ne "ok") { + print "$argument\n"; + } + if (defined s_character(\%commands)) {} + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + %commands = %store_commands; + undef %store_commands; + } + } + # no -Ts. + foreach (@alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (defined $argument) { + print "\n" if $commands->{"l"}; + print "$argument\n"; + } + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + if ($commands->{"d"} && !$commands->{"T"} && !which_character(\%commands)) { + print "\n" if !$commands->{"l"}; + } + } # end not's + } # if -t + + + elsif ($#ARGV > $my_number) { + my $total = $#ARGV + 1; + print "use --total or -t to see all $total packages\n"; + exit; + } + elsif ($#alot > $my_number) { + my $total = $#alot + 1; + print "use --total or -t to see all $total packages\n"; + } + + else { + if ($commands->{"T"}) { + foreach (@alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + print "$argument\n"; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + } + } # end -T + elsif (which_character(\%commands)) { + foreach (@alot) { + my %store_commands = %commands; + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (the_character($argument) ne "ok") { + print "$argument\n"; + } + if (defined s_character(\%commands)) {} + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + %commands = %store_commands; + undef %store_commands; + } + } # which_character + foreach (@alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (defined $argument) { + print "$argument\n"; + } + file(\%commands); + if ($commands->{"d"} && !$commands->{"T"} && !which_character(\%commands)) { + print "\n"; + } + } # end not's + } # else + } + else { + $argument =~ m,.*\/(.*$),; + if (defined $1) { + my $file = $1; + if (!$commands->{"n"} && -e "/usr/sbin/update-alternatives") { + my $it = "update-alternatives --display $1|"; + open (IT,"$it") or exit; + if ( =~ /No alternatives/) { + print "file $file is not owned by any package\n"; + } + else { + my @LINES = ; + print "For $argument ->\n"; + $LINES[0] =~ m,(/.*$),; $argument = $1; + print "@LINES\n"; findexer(\%commands); + } + } + else { + print "file $file is not owned by any package\n"; + } + } + } + } + untie %ib; + + if (!($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"})) { + if ($commands->{"x"} || $commands->{"ftp"} || $commands->{"source"} || + $commands->{"source_only"} || $commands->{"remove"} || + $commands->{"r"} || $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + +} # end sub findexer + + +# query description of file name..-i (-qfi) +sub qindexer { + + my ($commands) = @_; + my %commands = %$commands; + require SWIM::Ag; + SWIM::Ag->import(qw(description)); + + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + + my @alot; + + if (!$commands->{"n"}) { + ib(\%commands); + } + else { + my $return = nib(\%commands); + if (!defined $return && $commands->{"a"}) { + untie %ib; + nsb(\%commands); + $ib{"/."} = $nsb{"/."}; + } + } + + if (defined $argument) { + dir(\%commands); + fir(\%commands); + + # this will be moved above for safex(\%commands) + if ($ib{"$argument"}){ + my $package = $ib{"$argument"}; + @alot = split(/\s/, $package); + @PACKAGES = @alot; + if ($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @alot = @PACKAGES; + if ($commands->{"total"} || $commands->{"t"}) { + foreach (@alot) { + $argument = $_; + description(\%commands); + print "\n"; + } + } + elsif ($#ARGV > 0) { + my $total = $#ARGV + 1; + print "use --total or -t to see all $total packages\n"; + exit; + } + elsif ($#alot > 0) { + my $total = $#alot + 1; + print "use --total or -t to see all $total packages\n"; + } + else { + $argument = $package; + description(\%commands); + } + } + else { + $argument =~ m,.*\/(.*$),; + if (defined $1) { + my $file = $1; + if (!$commands->{"n"} && -e "/usr/sbin/update-alternatives") { + my $it = "update-alternatives --display $1|"; + open (IT,"$it") or exit; + if ( =~ /No alternatives/) { + print "file $file is not owned by any package\n"; + } + else { + my @LINES = ; + print "For $argument ->\n"; + $LINES[0] =~ m,(/.*$),; $argument = $1; + print "@LINES\n"; qindexer(\%commands); + } + } + else { + print "file $file is not owned by any package\n"; + } + } + } + } + untie %ib; + + + +} # end sub qindexer + + +1; diff --git a/lib/Format.pm b/lib/Format.pm new file mode 100644 index 0000000..e870fda --- /dev/null +++ b/lib/Format.pm @@ -0,0 +1,62 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Format; +use vars qw(@ISA @EXPORT); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(*PRETTY *ALLGROUPS *SUBJECT *CENTER *SDS $col1 $col2 $ag1 + $ag2 $ag3 $number $subsite $subdate $subsize $subrelease + $center $number $sdsite $sdsdate $sdsize $sdsrelease); + + +# A nice format to make things look prettier, hopefully. +format PRETTY = +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$col1, $col2 +. + +# A format for --allgroups, shouldn't run out of room. +format ALLGROUPS = +@<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<< +$ag1, $ag2, $ag3 +. + +# center for DF|APT call +format SUBJECT = +@|| @||| @||| @||||||||||| @|||||| +$number, $subsite, $subdate, $subsize, $subrelease + +. + + +format CENTER = + @||||||||||||||||||||||| + $center +. + + +format SDS = +@>> @||||||||||||||||||||| @||||||||||||||||||||||||||| @|||||||| @||||| +$number, $sdsite, $sdsdate, $sdsize, $sdsrelease +. + + + +1; diff --git a/lib/Global.pm b/lib/Global.pm new file mode 100644 index 0000000..858bb84 --- /dev/null +++ b/lib/Global.pm @@ -0,0 +1,62 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Global; +#use strict; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(%db $ping %ndb %ib $zing %gb $ging %sb $sing %nsb %commands + $argument $save @stuff @PACKAGES @arg_holder $file_now + $arg_count $aptor_count $aptor_group $swim_version); +%EXPORT_TAGS = ( + Info => [ qw($argument %db) ] + ); + +=pod + +Globals used by all program, which are not related to SWIM::Conf globals. +Most will probably be placed in SWIM::DB_Library. + +=cut +# Nothing to be done here. +# these could be put into SWIM::DB_Library +my (%db,$ping); # package.deb +my %ndb; # npackage.deb +my (%ib, $zing, %it); # fileindex.deb +my (%gb, $ging); # groupindex.deb +my (%sb, $sing); # statusindex.deb +my %nsb; # nstatusindex.deb +my %commands; # standard for Getopt::Long, but should usually + # be passed from ::*, although it can be global to a module +my $argument; # standard for package name +my $save; #for pager + +# Globals related to -xyz +my @stuff; # for -g & x +my @PACKAGES; # a replacement for @ARGV +my @arg_holder; # helps in tricky situations -> -qxl|d +my $file_now; # defined flag for -qlcx & -qglx for file() +$arg_count = 0; # helps in tricky situations +my $aptor_group; # helps when -z is called for groups + +# Swim's version +$swim_version = "0.3.6"; + +1; diff --git a/lib/Groups.pm b/lib/Groups.pm new file mode 100644 index 0000000..8a88728 --- /dev/null +++ b/lib/Groups.pm @@ -0,0 +1,73 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Groups; +use strict; +use SWIM::DB_Library qw(:Groups); +use SWIM::Format; +use SWIM::Global qw(%gb); +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(allgroups); + + +# show all the groups present on this system and exit +sub allgroups { + + my ($commands) = @_; + my %commands = %$commands; + + if (!($commands->{"q"} || $commands->{"query"}) && $commands->{"allgroups"}) { + print "swim: --allgroups may only be used during queries\n"; + exit; + } + if ($commands->{"q"} && $commands->{"allgroups"}) { + $~ = "ALLGROUPS"; + + if (!$commands->{"n"}) { + gb(\%commands); + } + else { + ngb(\%commands); + } + + my @complete = sort keys %gb; + my $three = 0; + while ($three <= $#complete) { + if (defined $complete[$three]) { + $ag1 = $complete[$three]; + } + if (defined $complete[$three + 1]) { + $ag2 = $complete[$three + 1]; + } + if (defined $complete[$three + 2]) { + $ag3 = $complete[$three + 2]; + } + write STDOUT; + $ag1 = ""; + $ag2 = ""; + $ag3 = ""; + $three = $three + 3; + } + exit; + } +} + + +1; diff --git a/lib/Indexer.pm b/lib/Indexer.pm new file mode 100644 index 0000000..d8916a9 --- /dev/null +++ b/lib/Indexer.pm @@ -0,0 +1,509 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Indexer; +use strict; +use SWIM::Global; +use SWIM::Conf qw($my_number); +use SWIM::DB_Library qw(:Xyz ib nib nsb); +use SWIM::Info; +use SWIM::Pn_print; +use SWIM::Deps; +use SWIM::Dir; +use vars qw(@ISA @EXPORT_OK); +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(indexer); + + +# The next few subs are provided to shorten indexer +# for -d or -l, but not -c when -T +sub T_indexer { + + my ($alot,$commands) = @_; + my %commands = %$commands; + + foreach (@$alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + # looks o.k. + print "$argument\n"; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + if ($commands->{"d"} && !$commands->{"c"}) { + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + print "\n"; + } +} # end sub T_indexer + + +sub which_character_indexer { + + my ($alot,$commands) = @_; + my %commands = %$commands; + + foreach (@$alot) { + my %store_commands = %commands; + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (the_character(\%commands) ne "ok") { + print "$argument\n"; + } + if (defined s_character(\%commands)) {} + shlibs(\%commands) if $commands->{"shlibs"}; + if ($commands->{"d"} && !$commands->{"c"}) { + require SWIM::File; + SWIM::File->import(qw(file)); + file(\%commands); + } + print "\n"; + %commands = %store_commands; + undef %store_commands; + } + +} # end sub which_character_indexer + +sub noT_indexer { + + + my ($alot,$commands) = @_; + my %commands = %$commands; + require SWIM::File; + SWIM::File->import(qw(file)); + + foreach (@$alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (defined $argument) { + # should be o.k., almost everything has documentation + print "$argument\n"; + } + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + if ($commands->{"d"} && !$commands->{"T"} && !which_character(\%commands)) { + print "\n"; + } + } + +} # end sub noT_indexer + +# different enough from noT_indexer, used when -c,-d,-l aren't called. +sub nonoT_indexer { + + my ($alot,$commands) = @_; + my %commands = %$commands; + + foreach (@$alot) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + # package name will print out even if there is no script + # definitely useful here + singular(\%commands); + if ($commands->{"scripts"}) { + print "\n"; + } + shlibs(\%commands) if $commands->{"shlibs"}; + } + + +} # end sub nonoT_indexer + + +# when -c is called with or without -l or -d. This sub got rather huge. +sub c_indexer { + + my ($alot,$commands) = @_; + my %commands = %$commands; + my $arg_save; + require SWIM::File; + SWIM::File->import(qw(file)); + + foreach (@$alot) { + $argument = $_; + if (conf(\%commands) ne 0) { + if ($commands->{"T"}) { + # covers first argument, but not the rest. + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + print "$argument\n"; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + print conf(\%commands) if !$commands->{"md5sum"}; + file(\%commands); + #file(\%commands) if $commands->{"md5sum"}; + if (($commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"}))) { + print "\n"; + } + $arg_save = $argument; + } # end "T" + + elsif (which_character(\%commands)) { + my %store_commands = %commands; + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (the_character(\%commands) ne "ok") { + print "$argument\n"; + } + if (defined s_character(\%commands)) {} + shlibs(\%commands) if $commands->{"shlibs"}; + print conf(\%commands) if !$commands->{"md5sum"}; + file(\%commands); + #file(\%commands) if $commands->{"md5sum"}; + if (($commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"}))) { + print "\n"; + } + %commands = %store_commands; + undef %store_commands; + $arg_save = $argument; + } + + # no Ts. + else { + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + print "$argument\n"; + shlibs(\%commands) if $commands->{"shlibs"}; + print conf(\%commands) if !$commands->{"md5sum"}; + file(\%commands); + print "\n"; + } + $arg_save = $argument; + } # end if (conf(\%commands) + + # this spot here can determine whether or not -c overrides l&d + # in packages which don't have conf files. it's nicer to view + # everything. watch this..these are packages which don't have + # conf files + if ($commands->{"d"} || $commands->{"l"}) { + if (defined $arg_save) { + if ($argument ne $arg_save) { + #if (!defined $arg_save) { + if (conf(\%commands) ne 0) { + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + } + + # no conf files + elsif (conf(\%commands) eq 0) { + if ($commands->{"T"}) { + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + print "$argument\n"; + character(\%commands); + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands) if $commands->{"md5sum"}; + print "\n"; + } # end "T" + + elsif (which_character(\%commands)) { + my %store_commands = %commands; + $argument = $_; + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + if (the_character(\%commands) ne "ok") { + print "$argument\n"; + } + if (defined s_character(\%commands)) {} + shlibs(\%commands) if $commands->{"shlibs"}; + %commands = %store_commands; + undef %store_commands; + file(\%commands); + print "\n"; + } + + # no Ts. + else { + if ($commands->{"scripts"} || $commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands->{"menu"} || $commands->{"m"}; + copyright(\%commands) if $commands->{"copyright"}; + changelog(\%commands) if $commands->{"changelog"}; + singular(\%commands); + if ($commands->{"scripts"}) { + print "\n"; + } + shlibs(\%commands) if $commands->{"shlibs"}; + file(\%commands); + print "\n"; + } + } + } + } + } # end if ($commands->{"d"} || + } # end foreach + +} # end sub c_indexer + + +# handles -qf by itself or with -l(-d)&-c or -d by itself, and -qa by itself +# or with -c with -d and/or -l ...essentially not -i. is the +# argument And ofcourse -T or singular capabilities. +sub indexer { + + my ($commands) = @_; + my %commands = %$commands; + my @alot; + + + if (!$commands->{"n"}) { + ib(\%commands); + } + else { + my $return = nib(\%commands); + if (!defined $return && $commands->{"a"}) { + untie %ib; + nsb(\%commands); + $ib{"/."} = $nsb{"/."}; + } + } + + if (defined $argument) { + dir(\%commands); + fir(\%commands); + if ($ib{"$argument"}){ + my $package = $ib{"$argument"}; + $package =~ s/\s/\n/g; + @alot = split(/\s/, $package); + if (defined @alot) { + @PACKAGES = @alot; + } + if ($commands->{"z"} || $commands->{"ftp"}|| + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + + + @alot = @PACKAGES; + if ($commands->{"total"} || $commands->{"t"}) { + # The whole reason for the complicated if/elsif/else routines + # below is to allow simultaneous printing of -c & -d|-l. Other + # options can just be included within. + + ########### + # -D & -t # + ########### + if ($commands->{"d"} && !$commands->{"c"}) { + if ($commands->{"T"}) { + T_indexer(\@alot,\%commands); + } + elsif (which_character(\%commands)) { + which_character_indexer(\@alot,\%commands); + } + # no -Ts. + noT_indexer(\@alot,\%commands); + } + + ####################### + # -t BUT NOT -C,-D,-L # + ####################### + elsif (!$commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"})) { + if ($commands->{"T"}) { + T_indexer(\@alot,\%commands); + } + elsif (which_character(\%commands)) { + which_character_indexer(\@alot,\%commands); + } + # humm smail is missing mysteriously, like it never became part + # of /.., basically, fastswim isn't placing it in long.debian. + # no -Ts. + else { + nonoT_indexer(\@alot,\%commands); + } + } + + ##################### + # -t -C &| -D || -L # + ##################### + # conf stuf. Will only show stuff related to -a or -f with conf. + elsif (($commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"})) || + ($commands->{"c"} && ($commands->{"d"} || $commands->{"l"}))) { + c_indexer(\@alot,\%commands); + } # end elsif + } + + ######################### + # > NUMBER FOR -t # + ########################## + elsif ($#ARGV > $my_number) { + my $total = $#ARGV + 1; + print "use --total or -t to see all $total packages\n"; + exit; + } + elsif ($#alot > $my_number) { + my $total = $#alot + 1; + print "use --total or -t to see all $total packages\n"; + } + + # without -t + else { + + ###### + # -D # + ###### + if ($commands->{"d"} && !$commands->{"c"}) { + if ($commands->{"T"}) { + T_indexer(\@alot,\%commands); + } + elsif (which_character(\%commands)) { + which_character_indexer(\@alot,\%commands); + } + # the noties + noT_indexer(\@alot,\%commands); + } + + ################ + # NOT -C,-D,-L # + ################ + elsif (!$commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"})) { + if ($commands->{"T"}) { + T_indexer(\@alot,\%commands); + } + elsif (which_character(\%commands)) { + which_character_indexer(\@alot,\%commands); + } + else { + nonoT_indexer(\@alot,\%commands); + } + } + + + ################## + # -C &| -D || -L # + ################## + # conf stuf. Will only show stuff related to -a or -f with conf. + elsif (($commands->{"c"} && (!$commands->{"d"} || !$commands->{"l"})) || + ($commands->{"c"} && ($commands->{"d"} || $commands->{"l"}))) { + c_indexer(\@alot,\%commands); + } + + } # without -t + } + else { + $argument =~ m,.*\/(.*$),; + if (defined $1) { + my $file = $1; + if (!$commands->{"n"} && -e "/usr/sbin/update-alternatives") { + my $it = "update-alternatives --display $1|"; + open (IT,"$it") or exit; + if ( =~ /No alternatives/) { + print "file $file is not owned by any package\n"; + } + else { + my @LINES = ; + print "For $argument ->\n"; + $LINES[0] =~ m,(/.*$),; $argument = $1; + print "@LINES\n"; indexer(\%commands); + } + } + else { + print "file $file is not owned by any package\n"; + } + } + } + } + untie %ib; + + if (defined @alot) { + @PACKAGES = @alot; + } + if (!($commands->{"z"} || $commands->{"ftp"} || + $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"})) { + if ($commands->{"x"} || $commands->{"ftp"} || $commands->{"source"} || + $commands->{"source_only"} || $commands->{"remove"} || + $commands->{"r"} || $commands->{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + +} # end sub indexer + + +1; diff --git a/lib/Info.pm b/lib/Info.pm new file mode 100644 index 0000000..ca4fadb --- /dev/null +++ b/lib/Info.pm @@ -0,0 +1,586 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Info; +use strict; +use SWIM::Conf qw(:Info); +use SWIM::Global qw(:Info); +use SWIM::DB_Library qw(:Xyz); +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(scripts copyright changelog menu conf shlibs); + +# scripts() copyright() changelog() menu() conf() shlibs() +# the text stuff taken out of info for the installed system, though the +# not-installed system in checked for, just in case. + +# This shows all the scripts identified with a package(s). In certain +# cases it is valuable to print a script without the name of the package, +# so if --scripts, -a, or -t isn't called, the pure script will be +# presented. +sub scripts { + + my ($commands) = @_; + my %commands = %$commands; + + my ($file, $preinst, $postinst, $prerm, + $postrm, $orig_argument); + + + if ($commands->{"n"}) { + print "swim: no scripts for not-installed, consider --diff\n"; exit; + } + + dbi(\%commands); + + if ($argument =~ /_/) { + $orig_argument = $argument; + my $check = $db{"$argument"}; + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {}; + } + untie %db; + + + # here we will print out whatever we find including the file name. + if ($commands->{"scripts"} && !($commands->{"preinst"} || + $commands->{"postinst"} || $commands->{"prerm"} || + $commands->{"postrm"})) { + if (defined "$parent$base/info/$argument.preinst") { + $preinst = "$parent$base/info/$argument.preinst"; + } + if (defined "$parent$base/info/$argument.postinst") { + $postinst = "$parent$base/info/$argument.postinst"; + } + if (defined "$parent$base/info/$argument.prerm") { + $prerm = "$parent$base/info/$argument.prerm"; + } + if (defined "$parent$base/info/$argument.postrm") { + $postrm = "$parent$base/info/$argument.postrm"; + } + + if (-e $preinst) { + print "#####$argument.preinst#####\n\n"; + open (LIST,"$preinst"); + while () { + print $_; + } + } + if (-e $postinst) { + print "#####$argument.postinst#####\n\n"; + open (LIST,"$postinst"); + while () { + print $_; + } + } + if (-e $prerm) { + open (LIST,"$prerm"); + print "#####$argument.prerm#####\n\n"; + while () { + print $_; + } + } + if (-e $postrm) { + open (LIST,"$postrm"); + print "#####$argument.postrm#####\n\n"; + while () { + print $_; + } + } + } # if scripts + + + # from here on we just print out the particular script(s) called + # literally with no filename, unless -a or -t is called. This is one + # situation in which -t has a use apart from the global default. A + + # title is printed out for singular scripts in this case. + + if ($commands->{"preinst"}) { + if (defined "$parent$base/info/$argument.preinst") { + $preinst = "$parent$base/info/$argument.preinst"; + } + if (-e $preinst) { + if ($commands->{"a"} || $commands->{"t"}) { + print "#####$argument.preinst#####\n\n"; + open (LIST,"$preinst"); + while () { + print $_; + } + } + else { + open (LIST,"$preinst"); + while () { + print $_; + } + } + } + } + + if ($commands->{"postinst"}) { + if (defined "$parent$base/info/$argument.postinst") { + $postinst = "$parent$base/info/$argument.postinst"; + } + if (-e $postinst) { + if ($commands->{"a"} || $commands->{"t"}) { + print "#####$argument.postinst#####\n\n"; + open (LIST,"$postinst"); + while () { + print $_; + } + } + else { + open (LIST,"$postinst"); + while () { + print $_; + } + } + } + } + + if ($commands->{"prerm"}) { + if (defined "$parent$base/info/$argument.prerm") { + $prerm = "$parent$base/info/$argument.prerm"; + } + if (-e $prerm) { + if ($commands->{"a"} || $commands->{"t"}) { + print "#####$argument.prerm#####\n\n"; + open (LIST,"$prerm"); + while () { + print $_; + } + } + else { + open (LIST,"$prerm"); + while () { + print $_; + } + } + } + } + + if ($commands->{"postrm"}) { + if (defined "$parent$base/info/$argument.postrm") { + $postrm = "$parent$base/info/$argument.postrm"; + } + if (-e $postrm) { + if ($commands->{"a"} || $commands->{"t"}) { + print "#####$argument.postrm#####\n\n"; + open (LIST,"$postrm"); + while () { + print $_; + } + } + else { + open (LIST,"$postrm"); + while () { + print $_; + } + } + } + } + + if (!$commands->{"i"}) { + if (defined $orig_argument) { + $argument = $orig_argument; + } + } + +} # end sub scripts + +# show the scripts for /usr/lib/menu +sub menu { + + my ($commands) = @_; + my %commands = %$commands; + + my $filelist; + my $orig_argument = $argument; + my %parent; + + if ($commands->{"n"}) { + print "swim: no menu for not-installed, consider --diff\n"; exit; + } + + dbi(\%commands); + + + if ($argument =~ /_/) { + $orig_argument = $argument; + my $check = $db{"$argument"}; + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {}; + } + untie %db; + + if (defined $argument) { + if (-e "$parent$base/info/$argument.list") { + $filelist = "$parent$base/info/$argument.list"; + } + if (defined $filelist) { + # basically, re-find file/package passed to previous sub + open(FINDMENU,"$filelist"); + while () { + chomp; + if (m,^\/usr\/lib\/menu\/(.*[\w-\+\.]),) { + if (!-d) { + print "#####menu for $orig_argument($1)#####\n"; + open(MENU,"$_"); + while () { + print; + } + print "\n"; + } + } + } + close(FINDMENU); + close(MENU); + } + } # defined + + if (!$commands->{"i"}) { + $argument = $orig_argument; + } + +} # end sub menu + + +# Show changelog, default zcat. This will show all the changelogs in +# the directory /usr/doc/package_name/, there are cases where there is +# a debian.changelog and one provided by the individual(s) working on the +# software, as well as a variety of other cases. +sub changelog { + + my ($commands) = @_; + my %commands = %$commands; + + my $file; + my $orig_argument = $argument; + + if ($commands->{"n"}) { + print "swim: no changelog for not-installed, consider --diff\n"; exit; + } + + dbi(\%commands); + + if ($argument =~ /_/) { + $orig_argument = $argument; + my $check = $db{"$argument"}; + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {}; + } + untie %db; + + + # Using swim -qadt | grep -i change it looks like all the files which + # have change in their name are changelogs when in /usr/doc/$argument, + # sometimes there are more above, but these are the most significant. + my @fsstnd; + if (-e "$parent/usr/doc/$argument" && + -d "$parent/usr/doc/$argument") { + my $directory = "$parent/usr/doc/$argument"; + opendir(CHANGE, "$directory") || die "I thought it existed"; + my @change = sort grep(/change/i, readdir(CHANGE)); + closedir(CHANGE); + foreach (@change) { + if (m,\.gz$,i) { + push(@fsstnd,$_); + print "#####$_ for $argument#####\n\n"; + open(ZCAT,"|$zcat") || die "swim: this option requires zcat"; + open(CHANGELOG, "$directory/$_"); + while () { + print ZCAT $_; + } + close(ZCAT); + close(CHANGELOG); + print "\n"; + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + push(@fsstnd,$_); + print "#####$_ for $argument#####\n\n"; + open(CHANGELOG, "$directory/$_"); + while () { + print "$_"; + } + close(CHANGELOG); + print "\n"; + } + } + } + + if (-e "$parent/usr/share/doc/$argument" && + -d "$parent/usr/share/doc/$argument") { + my $directory = "$parent/usr/share/doc/$argument"; + opendir(CHANGE, "$directory") || die "I thought it existed"; + my @change = sort grep(/change/i, readdir(CHANGE)); + closedir(CHANGE); + foreach (@change) { + if (m,\.gz$,i) { + my $cf = grep(m,^$_$,,@fsstnd); + if ($cf == 0 ) { + print "#####$_ for $argument#####\n\n"; + open(ZCAT,"|$zcat") || die "swim: this option requires zcat"; + open(CHANGELOG, "$directory/$_"); + while () { + print ZCAT $_; + } + close(ZCAT); + close(CHANGELOG); + print "\n"; + } + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + my $cf = grep(m,^$_$,,@fsstnd); + if ($cf == 0 ) { + print "#####$_ for $argument#####\n\n"; + open(CHANGELOG, "$directory/$_"); + while () { + print "$_"; + } + close(CHANGELOG); + print "\n"; + } + } + } + } + + + if (!$commands->{"i"}) { + $argument = $orig_argument; + } + +} # end sub changelog + +# Show copyright, default zcat. This will show all the copyrights in +# the directory /usr/doc/package_name/. Rather than passing the +# greped argument to changelog(), this subroutine was created instead which +# keeps things sensible. +sub copyright { + + my $file; + my $orig_argument = $argument; + + my ($commands) = @_; + my %commands = %$commands; + + + if ($commands->{"n"}) { + print "swim: no copyright for not-installed, consider --diff\n"; exit; + } + + dbi(\%commands); + + + if ($argument =~ /_/) { + $orig_argument = $argument; + my $check = $db{"$argument"}; + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {}; + } + untie %db; + + + # Using swim -qadt | grep -i copy it looks like all the files which + # have copy in their name are generally copyrights when in + # /usr/doc/$argument, sometimes there are more above, but these are + # the most significant. + my @fsstnd; + if (-e "$parent/usr/doc/$argument" && + -d "$parent/usr/doc/$argument") { + my $directory = "$parent/usr/doc/$argument"; + opendir(CHANGE, "$directory") || die "I thought it existed"; + my @change = sort grep(/copy|license/i, readdir(CHANGE)); + closedir(CHANGE); + foreach (@change) { + if (defined $_) { + if (m,\.gz$,i) { + push(@fsstnd,$_); + print "#####$_ for $orig_argument#####\n\n"; + open(ZCAT,"|$zcat") || die "swim: this option requires zcat"; + open(COPYRIGHT, "$directory/$_"); + while () { + print ZCAT $_; + } + # Sometimes these next two mysteriously open, and don't close + # even when no previous gz file was found, causing error output, + # but doesn't effect what's trying to be accomplished. Doesn't + # happen with changelog(). + close(ZCAT); + close(COPYRIGHT); + print "\n"; + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + push(@fsstnd,$_); + print "#####$_ for $orig_argument#####\n\n"; + open(COPYRIGHT, "$directory/$_"); + while () { + print "$_"; + } + close(COPYRIGHT); + print "\n"; + } + } # if defined + } + } + + if (-e "$parent/usr/share/doc/$argument" && + -d "$parent/usr/share/doc/$argument") { + my $directory = "$parent/usr/share/doc/$argument"; + opendir(CHANGE, "$directory") || die "I thought it existed"; + my @change = sort grep(/copy|license/i, readdir(CHANGE)); + closedir(CHANGE); + foreach (@change) { + if (defined $_) { + if (m,\.gz$,i) { + my $cf = grep(m,^$_$,,@fsstnd); + if ($cf == 0 ) { + print "#####$_ for $orig_argument#####\n\n"; + open(ZCAT,"|$zcat") || die "swim: this option requires zcat"; + open(COPYRIGHT, "$directory/$_"); + while () { + print ZCAT $_; + } + # Sometimes these next two mysteriously open, and don't close + # even when no previous gz file was found, causing error output, + # but doesn't effect what's trying to be accomplished. Doesn't + # happen with changelog(). + close(ZCAT); + close(COPYRIGHT); + print "\n"; + } + } + elsif ($_ !~ m,html$|htm$|ps$|dvi$|sgml$|gs$,) { + my $cf = grep(m,^$_$,,@fsstnd); + if ($cf == 0 ) { + print "#####$_ for $orig_argument#####\n\n"; + open(COPYRIGHT, "$directory/$_"); + while () { + print "$_"; + } + close(COPYRIGHT); + print "\n"; + } + } + } # if defined + } + } + + if (!$commands->{"i"}) { + $argument = $orig_argument; + } + +} # end copyright + +# process the database for the configuration files +sub conf { + + my ($commands) = @_; + my %commands = %$commands; + + # added for -xyz, but not necessary + if (defined $argument) { + if ($argument !~ /_/) { + if (defined $db{$argument}) { + $argument = $db{$argument}; + } + } + } + if (!$commands->{"n"}) { + dbi(\%commands); + } + else {} + if (defined $argument) { + my $conf = $argument . "CONF"; + if (defined $db{$conf}) { + return $db{$conf}; + } + else { return 0; } + } + untie %db; +} # end sub conf + +# shared libraries provided by the package +sub shlibs { + + my ($commands) = @_; + my %commands = %$commands; + + my $shlibs; + my $orig_argument; + + if ($commands->{"n"}) { + print "catswim: no shlibs for not-installed, consider --diff\n"; exit; + } + + + dbi(\%commands); + + if (defined $argument) { + if ($argument =~ /_/) { + $orig_argument = $argument; + my $check; + if (defined $db{"$argument"}) { + $check = $db{"$argument"}; + } + $argument =~ m,(^.*)_(.*$),; + if (defined $check) { + $argument = $1; + } + else {} + } + else { + $orig_argument = $argument; + } + } + untie %db; + + if (defined $argument) { + if (-e "$parent$base/info/$argument.shlibs") { + $shlibs = "$parent$base/info/$argument.shlibs"; + } + } + + if (defined $shlibs) { + print "Shlibs:\n"; + open(SHLIBS,"$shlibs"); + while () { + if ($_ !~ m,^\n$,) { + print; + } + } + } + + $argument = $orig_argument; + +} # end sub shlibs + + +1; diff --git a/lib/Library.pm b/lib/Library.pm new file mode 100644 index 0000000..017d02a --- /dev/null +++ b/lib/Library.pm @@ -0,0 +1,144 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Library; +use strict; +use SWIM::Conf; +use SWIM::Global; +use vars qw(@ISA @EXPORT); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(which_archdist finddb root compress_contents); + + +# functions which do not use DB_File which_archdist() finddb() root() + +# which archictecture and distribution does this database involve +sub which_archdist { + + my ($commands) = @_; + + my ($arch,$dist); + #if ($commands->{"initndb"} || $commands->{"rebuildndb"}) { + if ($commands->{"arch"}) { + $arch = "-" . $commands->{"arch"}; + } + else { + $arch = "-$architecture"; + } + + if ($commands->{"dists"}) { + $dist = "-" . $commands->{"dists"}; + } + else { + $dist = "-$distribution"; + } + return ($arch,$dist); + # } + +} # end sub which_archdist + + +# finding any database +sub finddb { + + my ($commands) = @_; + + my $fileplace; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $fileplace = "$parent$library"; + return $fileplace; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $fileplace = "$parent$base"; + return $fileplace; + } + +} # end sub finddb + +# This gives the option to be able to used -d & -l, but not -f, by only +# copying Contents over to contentsindex*.deb.gz. This the fast way. +sub compress_contents { + + my ($Contents,$commands) = @_; + my %commands = %$commands; + my $contentsdb = finddb(\%commands); + my($arch,$dist) = which_archdist(\%commands); + my $contentsindex = "$contentsdb/ncontentsindex$arch$dist.deb"; + my ($contentsindexgz, $mtime); + if (-e "$contentsdb/ncontentsindex$arch$dist.deb.gz") { + $contentsindexgz = "$contentsdb/ncontentsindex$arch$dist.deb.gz"; + $mtime = (stat("$contentsindexgz"))[9]; + } + else { + $contentsindexgz = "$contentsdb/ncontentsindex$arch$dist.deb.gz"; + } + + my $ex; + my $Contents_mtime = (stat("$Contents"))[9]; + my $BContents = $Contents; + $Contents = -B $Contents || $Contents =~ m,\.(gz|Z)$, ? + "$gzip -dc $Contents|" : "cat $Contents|"; + if (defined $mtime) { + if ($mtime == $Contents_mtime) { + print "Same Contents files, won't compress\n"; + exit if !$commands->{"ndb"}; + $ex = "stop"; + } + else { + unlink($contentsindexgz); + } + } + if (!defined $ex) { + print "Copying new Contents\n"; + #system $copy, $BContents, $contentsindexgz; + + # changed for >= 0.2.9 + # changed again >= 0.3.4 + open(CONTENTS, "$Contents") or die "where is it?\n"; + open(CONTENTSDB,">$contentsindex"); + while () { + ##if (/^FILE\s*LOCATION$/) { + ##while () { + s,^(\./)+,,; # filter for Debians altered dir structure + print CONTENTSDB $_; + ##} + ##} + } + print "Compressing Contents\n"; + # added -f just in case + system "$gzip", "-f", "-9", "$contentsindex"; + utime(time,$Contents_mtime,$contentsindexgz); + } + +} # end sub compress_contents + +# for / files +sub root { + + if ($argument eq "/") { + $argument = "/."; + } +} # end sub root + + +1; diff --git a/lib/MD.pm b/lib/MD.pm new file mode 100644 index 0000000..95d2484 --- /dev/null +++ b/lib/MD.pm @@ -0,0 +1,268 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::MD; +use strict; +use SWIM::Conf qw(:Path $splt); +use SWIM::DB_Library qw(:Md); +use SWIM::Library; +use SWIM::Global; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(process_md); + +# process_md used by both SWIM::DB_Init and SWIM::NDB_Init + +=pod + +Because many files and directories exist more than once, and it would be +kind of cool to go up to a directory /usr/bin or /usr/bin/ and do a +swim -qf and see all the packages that populate that directory... +multi-dimensional is the way to go. + +=cut + +sub process_md { + + print "File Database is being made\n"; + + my ($commands) = @_; + my %commands = %$commands; + my @ppackage; + my %md; + my @md; + my @mi; + my $thingy; + my @name; + my $count = 0; + my $count1 = 1; + + my($place) = finddb(\%commands); + + # Let's determine what architecture and distribution this person is + # interested in. + my ($arch, $dist, $not); + if ($commands->{"initndb"} || $commands->{"rebuildndb"}) { + ($arch,$dist) = which_archdist(\%commands); + $not = "n"; + } + else { + $arch = ""; + $dist = ""; + $not = ""; + } + my $fileindex = $not . "fileindex"; + + + # Now we process the files made from the massive array, and create + # fileindex.deb or nfileindex.deb + # Let's just use split, and will allow for customized line adj. + # 25000 is the default + if ($commands->{"split_data"}) { + my $split = $commands->{"split_data"}; + system("$splt -l $split $tmp/big.debian $tmp/DEBIAN"); + } + else { + # Seems like a good default + system("$splt -l 25000 $tmp/big.debian $tmp/DEBIAN"); + } + @ppackage = <$tmp/DEBIAN*>; + # It's unlikely this file will ever get too massive. + push(@ppackage, "$tmp/long.debian"); + print " Create the database\n"; + foreach $thingy (@ppackage) { + open(PARTS, "$thingy"); + while () { + my @c; + @md = split(/ -> /,$_); + if (defined($md[1])) { + chomp $md[0]; + chomp $md[1]; + @c = split(/\s/, $md[1]); + } + push(@mi,$md[0]); + push(@mi,$md[1]); + } # while + print " $thingy\n"; + print " wait a few seconds\n"; + my $zing; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $zing = tie %md, 'DB_File',"$parent$library/$fileindex$arch$dist.deb" + or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $zing = tie %md, 'DB_File',"$parent$base/$fileindex$arch$dist.deb" + or die "DB_File: $!"; + } + while ($count <= $#mi) { + $zing->put($mi[$count], $mi[$count1]); + $count = $count + 2; + $count1 = $count1 + 2; + } + undef $zing; + untie %md; + undef %md; + @mi = (); + @md = (); + $count = 0; + $count1 = 1; + close(PARTS); + } # end foreach + + # now we get to take into account deinstall:ok:config-files + # situations for an installed system. + if ($commands->{"initdb"} || $commands->{"rebuilddb"}) { + sb(\%$commands); ib(\%commands); my $yich; + foreach (values %sb) { + my $zit; my ($nit,$yit) = (split(/\s/,$_))[0,3]; + if ($yit eq "deinstall:ok:config-files" || + $yit eq "purge:ok:config-files") { + ($zit = $nit) =~ s,\+,\\\+,; + if ($ib{"/."} !~ m,$zit,) { + if (!defined $yich) { + $yich = $nit; + } + else { + $yich = $yich . " $nit"; + } + } + } + } + $ib{"/."} = $ib{"/."} . " $yich"; + } + + # after much experimentation it turns out that a flat text file + # is much faster for this particular application. This also + # creates the hash database reference for -db or -i. + my $searchindex = $not . "searchindex"; + open(FLATFILE, ">$place/$searchindex$arch$dist.deb"); + print "Create the powersearch flat database\n"; + foreach $thingy (@ppackage) { + if ($thingy ne "$tmp/long.debian") { + open(PARTS, "$thingy"); + while () { + @md = split(/ -> /,$_); + if (defined($md[1])) { + chomp $md[0]; + } + push(@mi,$md[0]); + } # while + } + print " $thingy\n"; + print " wait a few seconds\n"; + while ($count <= $#mi) { + print FLATFILE "$mi[$count]\n"; + $count++; + } + $count = 0; + @mi = (); + @md = (); + close(PARTS); + } # end foreach + close(FLATFILE); + + # This creates the flatfile with the directories for --powersearch + # --dir, which is probably a rare match in most cases. This doesn't + # create a hash reference database for --db and -i because the only + # package which could benifit from this is base-files, but it has + # configuaration files, on the other hand RedHat has at least one + # package without directories or files, but this is Debian. + my $dirindex = $not . "dirindex"; + open(FLATFILE, ">$place/$dirindex$arch$dist.deb"); + print "Create the powersearch flat directory database\n"; + open(PARTS, "$ppackage[$#ppackage]"); + while () { + @md = split(/ -> /,$_); + if (defined($md[1])) { + chomp $md[0]; + } + push(@mi,$md[0]); + } # while + print " $ppackage[$#ppackage]\n"; + while ($count <= $#mi) { + print FLATFILE "$mi[$count]\n"; + $count++; + } + $count = 0; + @mi = (); + @md = (); + close(PARTS); + close(FLATFILE); + + # compare nstatusindex*.deb to /. from nfileindex*.deb to find out if + # any of the packages in Packages weren't represented in the Contents + # file. This is different than the earlier report which shows packages + # which weren't in Packages but were in Contents. This list is kept, + # and used again in a future --ndb run to make the matches, if they + # exist. + if ($commands->{"initndb"} || $commands->{"rebuildndb"}) { + nsb(\%$commands); + nzing(\%commands); + my @fileindex = split(/\s/,$ib{"/."}); + my @statusindex = split(/\s/,$nsb{"/."}); + if ($#fileindex < $#statusindex) { + my $place = finddb(\%commands); + open(DIFF, ">$place/.packagesdiff$arch$dist.deb") + or warn "couldn't create diff file\n"; + my %uniques; + @uniques{@fileindex} = (); + foreach (@statusindex) { + # no sense putting non-US or experimental in here unless this + # is what is wanted. Only need to check for group non-us/* + if (!$commands->{"nue"}) { + my $name = (split(/_/,$_))[0]; + if (defined $nsb{$name}) { + next if (split(/\s/,$nsb{$name}))[1] =~ m,non-us,; + } + if ($dist eq "experimental") { + next; + } + } + elsif ($dist eq "experimental") { + if (!$commands->{"nue"}) { + my $name = (split(/_/,$_))[0]; + if (defined $nsb{$name}) { + next if (split(/\s/,$nsb{$name}))[1] =~ m,non-us,; + } + } + } + print DIFF "$_\n" unless exists $uniques{$_}; + } + $zing->del("/."); + $zing->put("/.",$nsb{"/."}); + } + } # end if + +# Will unlink transfer.deb, big.debian, long.debian. + unlink(<$tmp/DEBIAN*>); + unlink("$tmp/transfer.deb"); + unlink("$tmp/big.debian"); + unlink("$tmp/long.debian"); + + + #!!! + print " over and out\n"; + print scalar(localtime), "\n"; + +} # end sub process_md + + +1; diff --git a/lib/NDB.pm b/lib/NDB.pm new file mode 100644 index 0000000..e028917 --- /dev/null +++ b/lib/NDB.pm @@ -0,0 +1,1834 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + +package SWIM::NDB; +use strict; +use SWIM::NDB_File; +use SWIM::Library; +use SWIM::DB_Library qw(:NDb); +use SWIM::Format; +use SWIM::Compare; +use SWIM::Global; +use SWIM::Conf qw(:Path $default_directory @user_defined_section + $distribution $architecture); +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(update_packages_ndb rebuildflatndb); + +=pod + +This is one of the most powerful functions of swim because besides +rebuilding the not-installed databases averting a long wait, it creates +a report which can compare changes within one distribution, or this +function can be tricked into comparing the differences between two +distributions. This also quickly updates the DF databases or +not-installed databases when a new package(s) are installed or downloaded. + +=cut + +sub update_packages_ndb { + +=pod + +This function differs from SWIM::DB::db because rather then checking +the status file, it compares the Packages file(s) to the status +database created by swim. + +For normal upadating (not ndb ran automatically) SWIM::NDB_Init is used to +figure out what Packages databases to use for comparison. --ndb run +automatically will also be dealt with. + +=cut + + my ($commands,$contents) = @_; my %commands = %$commands; + + my($arch,$dist); + + # which architecture and distribution? + $commands->{"arch"} ? ($architecture = $commands->{"arch"}) + : ($architecture = $architecture); + + if ($commands->{"dists"}) { + $distribution = $commands->{"dists"}; + ($arch,$dist) = which_archdist(\%commands); + } + else { + $distribution = $distribution; + ($arch,$dist) = which_archdist(\%commands); + } + + # which section is wanted? + my ($main,$contrib,$non_free,$non_us); + $main = "main" if $commands->{"main"}; + $contrib = "contrib" if $commands->{"contrib"}; + $non_free = "non-free" if $commands->{"non-free"}; + # hopefully US is always capitalized -- watch this + $non_us = "non-US" if $commands->{"non-us"}; + if (!defined $main && !defined $contrib && !defined $non_free && + !defined $non_us) { + foreach (@user_defined_section) { + if ($_ eq "main") { + $main = "main"; + } + elsif ($_ eq "contrib") { + $contrib = "contrib"; + } + elsif ($_ eq "non-free") { + $non_free = "non-free"; + } + elsif ($_ eq "non-US") { + $non_us = "non-US"; + } + } + } + + # remove the version check file ..not the Release code + my $place = finddb(\%commands); + if ($commands->{"v"}) { + unlink("$place/.version_compare"); + } + + # Use dir() and fir() in NDB_Init to find path to Packages or + # Package.gz to make things easy, only one or more compressed files, + # or one or more non-compressed files may be used together in a set. + #print "Data is being gathered\n"; + my $begin = scalar(localtime); + print "checking for new, changed, and removed packages\n"; + my @check_arg = split(/\s/,$argument); + my $ac = 0; my $gz; + foreach (@check_arg) { + if ($ac == 0) { + if (-B || m,\.(gz|Z)$,) { + $argument = "gzip -dc $argument|"; + $gz = "yes"; + } + else { + $argument = "cat $argument|"; + } + } + else { + if (-B || m,\.(gz|Z)$,) { + if (!defined $gz) { + print "swim: targets must be one set of compressed or uncompressed file(s)\n"; + exit; + } + } + else { + if (defined $gz) { + print "swim: targets must be one set of compressed or uncompressed file(s)\n"; + exit; + } + } + } + $ac++; + } + + + #ndb(\%commands); nsb(\%commands); + + # now we can find the differences + +=pod + +Basically, if a package is new its information can be placed into the +specified databases. If a package already exists and the version has +changed, then this package will be updated, and specific information like +group and status will be compared. The version change will also be +compared..is it older, newer, debian-revision change? Packages which are +gone will have their information removed from the specified databases. + +# REPORT # + +A report will be kept, this allows changes within a distribution to be +recorded, or alternatively two different distributions can be compared by +tricking swim into thinking that the same distribution is being looked at. + +The format is something like a passwd file, except that it is divided +by ! (exclamations) - fortunately no packages have this - though sometimes +files do (very rare), exclamations in the Description field will be +coverted to a pound #. Control fields are stripped of their Field:. + +(this all on one line) + +GONE or CHANGED or NEW or SAME! +packagename!Description! +current_version!old_version! +current_group!old_group! +current_status!old_status! # Both for installed and not-installed (r<>=) +current_arch!old_arch! +current_dist!old_dist! +current_priority!old_priority! +present_maintainer!old_maintainer! +current_essential!old_essential! +current_source!old_source! # Weird if it changes +current_IS!old_IS! # Installed_Size +current_size!old_size! + +As you can see this format provides lots of information with 25 fields, +even more information than is needed, and the report can be read into a +hash of hashes quite easily, other ways can be used, too. Fields without +a value will just be empty (!!). The report will be available with the +--report option and will be dated, since it will be made new for each +dist-dist comparison. It's not necessary to use a Contents database, so +these reports can be generated very fast. But, it would be interesting to +see file differences in two distinct Distributions..Suse versus Debian, +this may come in the future .. although the author has already written +such a program (which doesn't use databases). + +Important: +Existing databases are used and updated, so for research purposes copies +of the databases in the default directory should be placed in an +alternative directory and --dbpath and/or --root used. + +=cut + + $| = 1; my @NEW; + # uses $ping for npackages-arch-dists.deb - %db + nping(\%commands) if !$commands->{"status_only"}; + # uses $zing for nfileindex-arch-dists.deb - %ib + nzing(\%commands) if $commands->{"Contents"}; + nging(\%commands); # uses $ging for ngroupindex-arch-dists.deb - %gb + nsing(\%commands); # uses $sing for nstatusindex-arch-dists.deb - %nsb + sb(\%commands); # uses %sb vs %nsb for nsing + + # no sense going through this if we just want to update n* status + if (!$commands->{"status_only"}) { + + + # First we have to sort out repeaters, it's annoying to have + # to have another loop, but repeats (not Debian Policy) are known + # to occur, and can wreck havoc in the databases. This loop can + # be skipped to check for changes when a ni has become in. + + # grab the ruler + my (%Package_count,%not_me,$packler,%not_me2,%warch,%arc); + open(PACKAGE, "$argument"); + while () { + if (/^Package:/i) { + $packler = substr($_,9); chomp $packler; + $Package_count{$packler}++; + } + elsif (/^Version:/) { + # decide who shall rule with the greatest version, + # order matters in the way the Packages are processed. + my $version = substr($_,9); chomp $version; + $not_me{$packler} = $version if $Package_count{$packler} == 1; + if ($Package_count{$packler} > 1) { + my $answer = comparison($not_me{$packler},$version); + if ($answer eq "<" || $answer eq "r<" || $answer eq "") { + delete $not_me{$packler}; delete $Package_count{$packler}; + $not_me{$packler} = $version; $Package_count{$packler} = 1; + delete $not_me2{$packler}; $not_me2{$packler} = $version; + } + else { + $not_me2{$packler} = $not_me{$packler}; + delete $Package_count{$packler}; $Package_count{$packler} = 1; + } + } + } # elsif version + elsif (/^Architecture:/) { + my $which_architecture = substr($_,14); + chomp $which_architecture; + if (!defined $warch{$packler}) { + $warch{$packler} = $which_architecture; + } + else { + $warch{$packler} = $warch{$packler} . " $which_architecture"; + } + # The assumption here is that there will never be two of the + # same architecture along with different ones, rather in cases + # where there are other archs, each will be unique, and where + # there are two or more of the same arch, a genuine repeat has + # occurred, this should cover the experimental dist. + if (defined $not_me2{$packler}) { + $arch =~ /-(.*)/; my $archi = $1; + #print "$packler\n"; + foreach (split(/\s/,$warch{$packler})) { + #print "$_\n"; + if ($_ eq $archi) { + $arc{"$archi$packler"}++; + #print "$archi$packler\n"; + } + } + if (defined $arc{"$archi$packler"}) { + if ($arc{"$archi$packler"} == 1) { + delete $not_me2{$packler}; + } + } + } + } # elsif arch + } + close(PACKAGE); + undef %warch; undef %Package_count; undef %not_me; + + my @hu = keys %not_me2; + print STDERR "REPEATS:" if $#hu != -1; + for (keys %not_me2) { + print STDERR " $_"; #print " $_ $not_me2{$_}"; + } + print STDERR "\n" if $#hu != -1; + + + my (@old_report,@new_report,$packagename,@New_packages, + @CHANGED,@CHANGED_REV,%CR,%two_timers); + my $packagesgz = $argument; + my %equalizer; + + # this will have a similiar setup to SWIM::NDB_Init but with the + # option not to check all fields. new and old status will be + # figured out, too. Even though almost everything could be done in + # one loop, we will keep it simple for now to stablize everything + # and maybe in the future integrate this all into one loop. We will + # grab all the report info from this loop, Gone packages can have + # their report info grabbed separately below. + open (DIFFERENCE, "$argument"); + while () { + # Package name + if (/^Package:/i) { + $packagename = (split(/: /,$_))[1]; chomp $packagename; + push(@New_packages,$packagename); + } + elsif (/^Version:/) { + my $new_version = substr($_,9); chomp $new_version; + my $packagen = (split(/_/,$packagename))[0]; + if (defined $not_me2{$packagen}) { + if ($not_me2{$packagen} ne $new_version) { + pop(@New_packages); undef $new_version; undef $packagename; + next; + } + else { + $equalizer{$packagename}++; + # two with the same version + if ($equalizer{$packagename} > 1) { + pop(@New_packages); undef $new_version; undef $packagename; + next; + } + } + } + if (defined $nsb{$packagename}) { + # just an example + if ($commands->{"report"}) { + my $old_priority = (split(/\s/,$nsb{$packagename}))[2]; + push(@old_report,$old_priority); + } + } + # humm, never seen this package before + # NEW # + if (! defined $nsb{$packagename}) { + print STDERR "NEW $packagename\n"; + push(@NEW,$packagename); + } + # guess I've seen it before! But has its version changed? + # CHANGED # + else { + my $old_version = + (split(/_/,((split(/\s/,$nsb{$packagename}))[0])))[1]; + my $operand; + if ($new_version ne $old_version) { + $operand = comparison($new_version,$old_version); + compare_versions($operand,$new_version,$old_version, + $packagename,\%commands) if $commands->{"v"}; + if ($operand eq "r>" || $operand eq "r<") { + push(@CHANGED_REV,$packagename); + $CR{$packagename} = "yes"; + print STDERR "CHANGED-REVISION $packagename\n"; + } + else { + push(@CHANGED,$packagename); + print STDERR "CHANGED $packagename\n"; + } + #print "$packagename $new_version $operand $old_version\n"; + } + #$operand = "=" if !defined $operand; + } + } + } + close(DIFFERENCE); + + # GONE # + + # for some reason the value for "/." gets corrupted sometimes after + # going through the @GONE loop .. so we will just carry it down, and + # this seems to work fine. As though that wasn't enough, sometimes + # the same monster exists in both non-us and main, so we will have + # to make provisions for this situation, otherwise the packages + # relationship to changes will be incorrectly recognized. This + # means -qan will provide a strange listing with two packages with + # the same name and then will be altered after + # --ndb. This causes all kinds of complications because nstatus is + # indexed with the name not the name_version, but /. can include + # both. So for these two timers or more, we will watch for them, + # and always use the newest version or the lack of it from both to + # determine whether the package(s) is gone, new, changed, and + # rewrite the entry for the two timer to be the newest, actually + # they should be handled in the initial creation. What this all + # means is that the databases as well as querying capabilities will + # be designed to handle multiple versions of the same package. + # + # Actually, the best solution is to provide no provisions for + # packages which exist with more than one version, just + # use the newest version of the package getting rid of all + # references to the packages for both --initndb & --ndb. This + # situation can also occur when swim fails to notice that two dists + # are unique (i.e. personal vs Debian) - a problem soon to be + # resolved. + + my (@Old_packages,%OP); + my @OLD_packages = split(" ",$nsb{"/."}); + foreach (@OLD_packages) { + my $hinge = (split(/_/,$_))[0]; + push(@Old_packages,$hinge); + $OP{$hinge}++; + #print "$hinge\n" if $OP{$hinge} > 1; + } + + my %tracker; + grep($tracker{$_}++,@New_packages); + my @GONE = grep(!$tracker{$_},@Old_packages); + my @sgone = @GONE; + foreach (@GONE) { + print STDERR "GONE $_\n"; + } + + my $new=$#NEW + 1; my $cr=$#CHANGED_REV + 1; my $ch=$#CHANGED + 1; + my $gon= $#GONE + 1; + if ($commands->{"check"}) { + print "\n TOTAL\n -----\n"; + print "NEW $new\n"; print "GONE $gon\n"; + print "CHANGED $ch\n"; print "CHANGED REVISION $cr\n"; exit; + } + print "\n TOTAL\n -----\n"; + print "NEW $new\n"; print "GONE $gon\n"; + print "CHANGED $ch\n"; print "CHANGED REVISION $cr\n"; + + + my %BS; # Before State for .packagesdiff* + my @BS = (@GONE,@NEW,@CHANGED,@CHANGED_REV) if $commands->{"Contents"}; + foreach (@BS) { + $BS{$_} = "ok"; + } + @GONE = (@GONE,@CHANGED,@CHANGED_REV); + ##undef @GONE; + @NEW = (@NEW,@CHANGED,@CHANGED_REV); + my @KGONE = @GONE if $commands->{"Contents"}; + #untie %db; + #undef %db; + #untie %nsb; + #undef %nsb; + + # Remember to remove ndirindex..gz and nsearchindex..gz and r> r< do + # not have to be completely updated in ncontentsindex*.deb, but + # packagename_version will need to be removed + + + # Time for some fun stuff + # There are four states: GONE - all information about this package + # needs to be removed from the databases. NEW - all information about + # this package needs to be put in the databases. CHANGED - a + # combination of the two previous, information could be cross + # referenced and checked for changes, but it's probably no saving of + # time, so first remove information from the same package of a + # different version, then add the information about the package of the + # new version (older or newer) CHANGED REVISION doesn't have to be run + # through the nfile database (debian-revision). + + ############# + # # + # GONE # + # # + ############# + # GONE. (reverse applies to NEW) + # For npackage-arch-dists.deb - Delete description + # (packagename_version), packagenameREP, packagenamePRO, + # packagenameDEP, packagenamePRE, packagenameREC, + # packagenameSUG, packagenameCON, packagenameCONF. delete package -> + # version. + # + # for ncontentsindex-arch-dists.deb - + # Find all files and directories associated with the package. Delete + # these files (keys). Find all directories where the file + # exists..delete package name from value, delete whole key if it is the + # only package name. + # + # for ngroupindex - delete package name (value) from Section + # it belonged to..humm, find section package belongs to in + # nstatusuindex-arch-dists.deb, and delete whole Section key if only one. + # + # for nstatusindex-arch-dists.deb - + # delete package -> version group. + # + # for flat files dirindex and searchindex - + # the removal of files and/or directories can be put on hold, and + # done with an option at a later time, since fileindex.deb remembers + # current state, at a later time the old state of the flat files can be + # compared to the new state of fileindex, and these files can be + # rewritten. This is all o.k. because these extra files or directories + # will return undef in search() if the packages don't exist. + + # calling noram to turn off the ramdisk, don't want this on + noram(\%commands); + + # might as well check to see it ncontentsindex-arch-dists-old.deb.gz + # exits, if it doesn't and --Contents is called will give a + # warning and quit, if it does time to remove ndirindex-arch-dists.gz + # and nsearchindex-arch-dists.gz + my ($ncontents,%packagediff); + $ncontents = "no"; + if ($commands->{"Contents"}) { + $ncontents = ncontents_exist(\%commands); + if ($ncontents eq "no") { + print "swim: database implied for --Contents does not exist\n"; + exit; + } + my $contentsdb = finddb(\%commands); + if (-e "$contentsdb/.packagesdiff$arch$dist.deb") { + open(PACKAGEDIFF,"$contentsdb/.packagesdiff$arch$dist.deb"); + while () { + chomp; $packagediff{(split(m,_,,$_))[0]} = $_; + } + close(PACKAGEDIFF); + } + } + + my $x = 1; + foreach (@GONE) { + print "G|C|CR $x\r"; + $x++; + #next if $_ eq "/." || $_ eq "/.."; + #first delete keys from package.deb + # If I kept this the name_version would be remembered. + $ping->del($_); + my $orig_argument = $_; + #my $packname_version = (split(/\s/,$nsb{$orig_argument}))[0]; + # apache-common in .diff + #print "1 $orig_argument\n" if !defined $packname_version; + #print "2 $packname_version\n" if !defined $orig_argument; + untie $sing; + $argument = "$_"; + nver(\%commands); + $ping->del($argument); + my $conf = $argument . "REP"; + $ping->del($conf); + $conf = $argument . "PRO"; + $ping->del($conf); + $conf = $argument . "DEP"; + $ping->del($conf); + $conf = $argument . "PRE"; + $ping->del($conf); + $conf = $argument . "REC"; + $ping->del($conf); + $conf = $argument . "SUG"; + $ping->del($conf); + $conf = $argument . "CON"; + $ping->del($conf); + $conf = $argument . "MD"; + $ping->del($conf); + $conf = $argument . "FN"; + $ping->del($conf); + untie $ping; + + # remove from the group, and if only one remove the group. + # Let's first find out which group this monster belongs to. + if (defined $nsb{$orig_argument}) { + (my $oa = $orig_argument) =~ s,\+,\\\+,g; + my($section) = (split(/\s/,$nsb{$orig_argument}))[1]; + if (defined $gb{$section}) { + my $status = ($gb{$section} =~ s,$oa ,,); + if ($status eq "") { + $status = ($gb{$section} =~ s, $oa,,); + if ($status eq "") { + $gb{$section} =~ s,$oa,,; + } + } + if ($gb{$section} eq "") { + $ging->del($section); + } + } + } + + } # end foreach OLD + + + # Time to use ncontentsindex-arch-dists.deb.gz and hunt down all + # directories and files, the trick would be doing this in one loop which + # would speed things up. We better umount dramdisk if it is mounted + # and delete ndirindex-arch-dists.deb.gz and nsearchindex-arch-dists.deb.gz + # Moreover, this operation shouldn't be performed unless --Contents + # was called, and only if ncontentsindex-arch-dists.deb exists - in this + # case it will just skip on, otherwise the other databases will get + # corrupted. + # The new ncontents-arch-dists.deb.gz can be copied over the argument + # to --Contents or its location in DF. + # we will do the checks and removals here .. better be --Contents. + + print "\n" if $#GONE != -1; + $x = 1; + foreach (@GONE) { + my $orig_argument = $_; + my $packname_version = (split(/\s/,$nsb{$orig_argument}))[0]; + $packname_version =~ s,\+,\\\+,g; + ################################ + # NFILEINDEX-ARCH-DISTS.DEB.GZ # + ################################ + if ($commands->{"Contents"}) { + if ($commands->{"Contents"} !~ /^FDB/) { + if (!defined $packagediff{$orig_argument}) { + my $subject = (split(/\s/,$nsb{$orig_argument}))[1]; + my (@file) = + remove_add_nfile($orig_argument,$ncontents,$subject,\%commands); + my $file = "$orig_argument.list"; + print "#$x VIRTUAL G|C|CR $file \r"; + $x++; + foreach (@file) { + if (defined $ib{$_}) { + my $status = ($ib{$_} =~ s,$packname_version ,,); + if ($status eq "") { + $status = ($ib{$_} =~ s, $packname_version,,); + if ($status eq "") { + $ib{$_} =~ s,$packname_version,,; + } + } + if ($ib{$_} eq "") { + $zing->del($_); + } + } # if defined + } # foreach + } + } + } + # Now ditch the package->version group in nstatusindex-arch-dist.deb + # And redo /. + $sing->del($orig_argument); + untie $sing; + } + + # constantly deleting /. didn't work too well, so will do a one time + # thing. I found out that this value needs to be put in twice before + # it sticks which would indicate that "/." already exists and + # doesn't want to be removed (now you can delete it the first time), + # basically something weird is going on because /.. is being + # created at the very top of this module, and + # it is being mistaken for /. When --Contents is ran GONE and + # CHANGED in @GONE are being chomped somewhere in a way that they still + # exist in @GONE but aren't ""..in fact /[\w\.\+-] matches. + + if ($#GONE != -1) { + @GONE = @KGONE if $commands->{"Contents"}; + foreach (@GONE) { + if (defined $OP{$_}) { + delete $OP{$_}; + } + } + my @Orig_packages = sort keys %OP; my $rs; + #print "AFTER GONE $#Orig_packages\n"; + foreach (@Orig_packages) { + if ($_ ne "/." && $_ ne "/..") { + my $pv = (split(/\s/,$nsb{$_}))[0]; + !defined $rs ? ($rs = $pv) : ($rs = $rs . " $pv"); + } + } + $sing->del("/."); $sing->del("/."); # no thing + $sing->put("/.","$rs"); $sing->put("/.","$rs"); + } + + # the new ncontentsindex-arch-dists.deb.gz needs to be set-up now. + if ($ncontents ne "no") { + if ($commands->{"Contents"} !~ /^FDB/) { + print "\n"; + defined $contents ? + compress_contents($contents,\%commands) : + compress_contents(find_contents(\%commands),\%commands); + } + } + + + ############# + # # + # NEW # + # # + ############# + + + my ($ok,$goon1,$goon,$filename,@FILENAME,$distro); + my (%exacts,@package,$essential,$version,$maintainer,$things, + $priority,%group,$group,$section); + my ($pre_depends,$depends,$replaces,$provides,$recommends, + $suggests, $conflicts, @REPLACE); + my (@ldescription,@description,$installed_size,$source,$size,$status); + my $scount = 0; my $count = 0; + undef %equalizer; + + my $format_deb = "$tmp/format.deb"; + my @NEW_AND_REV = (@NEW,@CHANGED_REV); + foreach (@NEW_AND_REV) { + $exacts{$_} = "yes"; + } + + $x = 1; + open(PRETTY, ">$format_deb"); + open(PACKAGE, "$packagesgz"); + while () { + # Package name + if (/^Package:/i) { + @package = split(/: /,$_); + chomp $package[1]; + if (defined $exacts{$package[1]}) { + print "N|C|CR $x\r"; + $x++; $goon1 = "yes"; + } + else { + $goon1 = "no"; + undef @package; + next; + } + } + elsif ($goon1 eq "no") { + next; + } + elsif (/^Version:/) { + $version = $_; + chomp $version; + my $vion = substr($version,9); + my $pv = $package[1] . "_" . $vion; + if ($scount == 0) { + $things = $pv; + } + else { + $things = $things . " $pv"; + } + $scount++; + } + elsif (/^Priority:/) { + $priority = $_; + } + elsif (/^Section:/) { + $section = $_; + # make the hash for the groupindex.deb + $group = substr($section,9); + chomp $group; + if (!defined $group{$group}) { + $group{$group} = $package[1]; + } + else { + $group{$group} = "$group{$group} $package[1]"; + } + } + elsif (/^Essential/) { + ($essential) = (split(/: /,$_))[1]; + } + elsif (/^Maintainer:/) { + $maintainer = $_; + } + # This stuff will be available with seperate query flags or -T + elsif (/^Pre-Depends:/) { + $pre_depends = $_; + if (defined($pre_depends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "PRE"; + push(@REPLACE, "$nv"); + push(@REPLACE, $pre_depends); + } + } + elsif (/^Depends:/) { + $depends = $_; + if (defined($depends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "DEP"; + push(@REPLACE, "$nv"); + push(@REPLACE, $depends); + } + } + elsif (/^Recommends:/) { + $recommends = $_; + if (defined($recommends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "REC"; + push(@REPLACE, "$nv"); + push(@REPLACE, $recommends); + } + } + elsif (/^Suggests:/) { + $suggests = $_; + if (defined($suggests)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "SUG"; + push(@REPLACE, "$nv"); + push(@REPLACE, $suggests); + } + } + elsif (/^Conflicts:/) { + $conflicts = $_; + if (defined($conflicts)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "CON"; + push(@REPLACE, "$nv"); + push(@REPLACE, $conflicts); + } + } + elsif (/^Provides:/) { + $provides = $_; + if (defined($provides)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "PRO"; + push(@REPLACE, "$nv"); + push(@REPLACE, $provides); + } + } + elsif (/^Replaces:/) { + $replaces = $_; + if (defined($replaces)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "REP"; + push(@REPLACE, "$nv"); + push(@REPLACE, $replaces); + } + } + + # These next two determine whether to skip or keep the data. + # It can't be assumed that the right database is being used. + # Filename has the name of the distribution. + ############## + # ARCH CHECK # + ############## + elsif (/^Architecture:/) { + my $which_architecture = substr($_,14); + chomp $which_architecture; + $arch =~ /-(.*)/; my $archi = $1; + ### REPEATERS ### + my $vion = substr($version,9); + if (defined $not_me2{$package[1]}) { + if ($not_me2{$package[1]} ne $vion) { + #print "Pack $package[1]\n"; + $which_architecture = "FUNNY"; + } + else { + $equalizer{$package[1]}++; + # to with the same version + if ($equalizer{$package[1]} > 1) { + $which_architecture = "FUNNY"; + #print "no need to do it again\n"; + } + } + } + if ($which_architecture ne $archi) { + if ($which_architecture ne "all") { + # erasure time + ########## + # GROUPS # + ########## + # This keeps the groupindex proper + undef $ok; + (my $moggy = $package[1]) =~ s/\+/\\+/g; + my $check = ($group{$group} =~ m,(^.*)\s$moggy$,); + if ($check ne "") { + #print "DIST $disti $1\n"; + $group{$group} = $1; + } + else { + delete $group{$group}; + } + ########### + # REPLACE # + ########### + # this keeps deps correct + if (defined $pre_depends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $pre_depends; + } + if (defined $depends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $depends; + } + if (defined $recommends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $recommends; + } + if (defined $suggests) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $suggests; + } + if (defined $conflicts) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $conflicts; + } + if (defined $provides) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $provides + } + if (defined $replaces) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $replaces; + } + + ########## + # STATUS # + ########## + my $vion = substr($version,9); + $vion =~ s/\+/\\+/g; + my $pv = $moggy . "_" . $vion; + my $scheck = ($things =~ m,(^.*)\s$pv$,); + if ($scheck ne "") { + $things = $1; + } + else { + $things = ""; + } + # some of these things don't need to be undefed because + # they will be reset, because of the next. + undef $priority if defined $priority; + undef $section if defined $section; + undef $group if defined $group; + undef $essential if defined $essential; + undef $maintainer if defined $maintainer; + $goon = "yes"; + next; + } + else { + undef $goon; + } + } # wrong architecture + else { + undef $goon; + } + } + + ######################### + # DIST CHECK & FILENAME # + ######################### + elsif (/^Filename:/ && !defined $goon) { + chomp; + $filename = $_; + my @fields = split(/\//,$filename); + $distro = $fields[1]; + my $archo; + if (defined $fields[3]) { + my $archos = $fields[3]; + #$archos =~ /^.*-(\w*)$/; + $archos =~ /^binary-([-\w]*)$/; + $archo = $1; + } + else { + # experimental looks like project/experimental/packagename_ver + # so the architecture will be what is specified. Right now, + # the only architectures in experimental is i386 and all. + # This makes sense because all is the goal of Debian. + $arch =~ /-(.*)/; my $archi = $1; + $archo = $archi; + } + $dist =~ /-(.*)/; my $disti = $1; + $arch =~ /-(.*)/; my $archi = $1; + my($mainf, $contribf, $non_freef, $non_usf, $experimentalf); + if (defined $fields[3]) { + if (defined $main) { + $mainf = "yes" if $fields[2] eq $main; + } + if (defined $contrib) { + $contribf = "yes" if $fields[2] eq $contrib; + } + if (defined $non_free) { + $non_freef = "yes" if $fields[2] eq $non_free; + } + if (defined $non_us) { + $non_usf = "yes" if $fields[2] eq $non_us; + } + } + # the distribution experimental has no sections. + elsif ($fields[0] eq "Filename: project") { + $experimentalf = "yes" if $fields[1] eq "experimental"; + } + #print "$filename && $distro && $archo && $fields[0]\n"; + #print "$disti -> $distro && $archi -> $archo\n"; + # project is experimental + # will determine whether this is right distribution and whether + # main, non-free, contrib, or non-us (not set up for traditional + # packages file) have been requested. options override the + # default + if ($disti eq $distro && $archi eq $archo && defined $mainf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $contribf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $non_freef) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $non_usf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo + && defined $experimentalf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + else { + # erasure time + ########## + # GROUPS # + ########## + # This keeps the groupindex proper + undef $ok; + # if (defined $package[1]) { + # $ppackage = $package[1]; + # } + (my $moggy = $package[1]) =~ s/\+/\\+/g; + ##print "$distro $group == ", $group{$group}, " == $package[1]"; + #print "$group -", $group{$group}, "\n"; + my $check = ($group{$group} =~ m,(^.*)\s$moggy$,); + if ($check ne "") { + #print "DIST $disti $1\n"; + $group{$group} = $1; + } + else { + #print "JUST ONE", $group{$group}, "\n"; + delete $group{$group}; + } + ########### + # REPLACE # + ########### + # this keeps deps correct + if (defined $pre_depends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $pre_depends; + } + if (defined $depends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $depends; + } + if (defined $recommends) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $recommends; + } + if (defined $suggests) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $suggests; + } + if (defined $conflicts) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $conflicts; + } + if (defined $provides) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $provides + } + if (defined $replaces) { + undef @REPLACE; + #pop(@REPLACE); pop(@REPLACE); + undef $replaces; + } + + ########## + # STATUS # + ########## + my $vion = substr($version,9); + $vion =~ s/\+/\\+/g; + my $pv = $moggy . "_" . $vion; + my $scheck = ($things =~ m,(^.*)\s$pv$,); + if ($scheck ne "") { + $things = $1; + } + else { + $things = ""; + } + # some of these things don't need to be undefed because + # they will be reset, because of the next. + undef $priority if defined $priority; + undef $section if defined $section ; + undef $group if defined $group; + undef $essential if defined $essential; + undef $maintainer if defined $maintainer; + next; + } # wrong distribution + } + + ############ + # ######## # + # # MAIN # # + # ######## # + ############ + # From here on we can start putting stuff in the databases + elsif (defined $ok) { + # first the package relationships + if (defined @REPLACE) { + my %relationship = @REPLACE; + foreach (keys %relationship) { + $ping->put($_,$relationship{$_}); + } + undef @REPLACE; + } + # second the groups + if (defined %group) { + if (!defined $gb{$group}) { + $ging->put($group,$package[1]); + } + else { + my $change_group = "$gb{$group} $package[1]"; + $ging->del($group); + $ging->put($group,"$change_group"); + } + undef %group; + } + # third Filename + if (defined @FILENAME) { + my %filename = @FILENAME; + foreach (keys %filename) { + $ping->put($_,$filename{$_}); + } + undef @FILENAME; + } + if (/^Size:/) { + $size = $_; + chomp; + } + # fourth the MD5 + elsif (/^MD5sum/) { + chomp; + my $md5sum = substr($_,8); + chomp $md5sum; + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "MD"; + $ping->put($nv,$md5sum); + } + + # To be combined with first fields. There are no packages + # missing this field, unlike a status file. + # defined either at architecture or filename. + elsif (m,Description:|^\s\w*|^\s\.\w*|^installed-size:|^revision:,){ + # this solved an annoying problem + if (/^\n$/) { + next; + } + chomp $version; + $version =~ m,Version:\s(.*),; my $ending = $1; + my $many_lines = $_; + if ($_ !~ /^installed-size:|^revision:/) { + $count++; + if ($count == 1) { + if (defined $package[1]) { + push(@description,"$package[1]_$ending"); + } + } + if (defined($many_lines)) { + push(@ldescription,$many_lines); + } + } # end if ($_ !~ /^\n$/ + elsif ($_ =~ /^installed-size|^revision:/) { + $count = 0; + # let's put each description into one scalar + my ($c, $cool); + if ($#ldescription != 0) { + for ($c = $#ldescription; $c >= 0; $c--) { + if ($c > 0) { + $cool = $ldescription[$c-1] .= $ldescription[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $ldescription[0]; + } + if (defined $cool) { + push(@description,$cool); + } + @ldescription = (); + } # end else + } # end elsif Description + + ####################################### + # installed-size: followed by source: # + ####################################### + # if installed-size is at the end of Description, than source may + # follow. revision has been found once in the experimental + # distribution, but nothing was following it, this will have to be + # watched because the order isn't known, and installed-size and source + # will probably come into picture at some time. + if (/^installed-size:/ || /^revision:/) { + $installed_size = $_; + my $next = ; + # source follows + if ($next =~ /^source:/) { + $source = $next; + chomp $source; + chomp ($version, $section); + $col1 = "Package: $package[1]"; + + # status time + my $yep = exist_sb(\%commands); + if (defined $yep) { + my($different,$same); + my $pname = $package[1]; + if (defined $sb{$pname}) { + my ($vname,$gname,$priorname,$statusname) = + split(/\s/,"$sb{$pname}",4); + $statusname =~ s/:/ /g; + # a way to test + #$version = "Version: 1:5.0-2"; + my $pver = substr($version,9); + my $cname = $pname . "_" . $pver; + if ($vname eq $cname) { + $status = "Status: $statusname\n"; + $same = "yes"; undef($different); + } + else { + # here's where we get to do some comparisons + # we will have to compare sections. 1). may have changed + # 2). may be an unfair comparison free vs non-free, on the + # other-hand this should be in the person's awareness + # making the check. 1) will provide the answer to both. + $vname =~ m,^.*_(.*)$,; + my $ever = $1; + # print "$pname: $pver && $ever\n"; + # $pver = new $ever = installed + my $oper = comparison($pver,$ever); + compare_versions($oper,$pver,$ever,$pname,\%commands) + if $commands->{"v"}; + $status = + "Status: " . $oper . " $statusname ($ever)\n"; + $different = "yes"; undef($same); + } + } + else { + $status = "Status: not-installed\n"; + } + $col2 = $status; + untie %sb; + } + else { + $col2 = "Status: not-installed\n"; + } + write PRETTY; + $col1 = $version; + $version =~ m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # ran. + my $name = $package[1]; my $name_ver = "$package[1]_$1"; + $ping->put($name,$name_ver); + #$package[1] = "$package[1]_$1"; + my $priory = substr($priority,10); chomp $priory; + my $thimk = "$name_ver $group $priory"; + $sing->put($name,$thimk); + if(defined($essential)) { + $col2 = "Essential: $essential"; + $essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + $col1 = $section; + $col2 = $priority; + write PRETTY; + #my $cool = $installed_size . $maintainer; + my $einstalled_size = substr($installed_size,16); + chomp $einstalled_size; + $col1 = "Installed-Size: $einstalled_size"; + if (defined $source) { + my $esource = substr($source,8); + $col2 = "Source: $esource"; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + $col1 = $size; + $col2 = "Architecture: $architecture\n"; + write PRETTY; + if ($distro ne "experimental") { + $filename =~ m,^Filename: dists\/(\w*)\/.*$,; + print PRETTY "Distribution: $1\n"; + print PRETTY $maintainer + } + else { + my $exp_dist = "experimental"; + print PRETTY "Distribution: $exp_dist\n"; + print PRETTY $maintainer + } + } # if $next =~ source + + + ############################################## + # installed-size: or revision: by themselves # + ############################################## + # source doesn't follow + elsif ($next =~ /^\n$/) { + chomp($version, $section); + $col1 = "Package: $package[1]"; + + # revision magic + if (/revision:/) { + $filename =~ m,.*/(.*)\.deb$,; + my $rr = $1 . "MD"; + my $rver = substr($version,9); + my $prr = $package[1] . "_" . "$rver" . "MD REVISION"; + $ping->put($rr,$prr); + } + + # status time + my $yep = exist_sb(\%commands); + if (defined $yep) { + my($different,$same); + my $pname = $package[1]; + if (defined $sb{$pname}) { + my ($vname,$gname,$priorname,$statusname) = + split(/\s/,"$sb{$pname}",4); + $statusname =~ s/:/ /g; + # a way to test + #$version = "Version: 1:5.0-2"; + my $pver = substr($version,9); + my $cname = $pname . "_" . $pver; + if ($vname eq $cname) { + $status = "Status: $statusname\n"; + $same = "yes"; undef($different); + } + else { + # here's where we get to do some comparisons + # we will have to compare sections. 1). may have changed + # 2). may be an unfair comparison free vs non-free, on the + # other-hand this should be in the person's awareness + # making the check. 1) will provide the answer to both. + $vname =~ m,^.*_(.*)$,; + my $ever = $1; + # print "$pname: $pver && $ever\n"; + # $pver = new $ever = installed + my $oper = comparison($pver,$ever); + compare_versions($oper,$pver,$ever,$pname,\%commands) + if $commands->{"v"}; + $status = + "Status: " . $oper . " $statusname ($ever)\n"; + $different = "yes"; undef($same); + } + } + else { + $status = "Status: not-installed\n"; + } + $col2 = $status; + untie %sb; + } # if defined $yep + else { + $col2 = "Status: not-installed\n"; + } + write PRETTY; + $col1 = $version; + $version =~ m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # ran. + my $name = $package[1]; my $name_ver = "$package[1]_$1"; + $ping->put($name,$name_ver); + #$package[1] = "$package[1]_$1"; + my $priory = substr($priority,10); chomp $priory; + my $thimk = "$name_ver $group $priory"; + $sing->put($name,$thimk); + if(defined($essential)) { + $col2 = "Essential: $essential"; + $essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + $col1 = $section; + $col2 = $priority; + write PRETTY; + #my $cool = $installed_size . $maintainer; + my $einstalled_size = substr($installed_size,16); + chomp $einstalled_size; + $col1 = "Installed-Size: $einstalled_size"; + if (defined $source) { + my $esource = substr($source,8); + $col2 = "Source: $esource"; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + $col1 = $size; + $col2 = "Architecture: $architecture\n"; + write PRETTY; + if ($distro ne "experimental") { + $filename =~ m,^Filename: dists\/(\w*)\/.*$,; + print PRETTY "Distribution: $1\n"; + print PRETTY $maintainer + } + else { + my $exp_dist = "experimental"; + print PRETTY "Distribution: $exp_dist\n"; + print PRETTY $maintainer + } + } # if $next =~ source + } # elsif installed-size + } # right arch and dist + } # end while PACKAGE + + close(PRETTY); + close(PACKAGE); + + # put /. in nstatus + if (defined $things) { + if ($things =~ /^\s.*/) { + $things =~ s/^\s//; + } + $things = $nsb{"/."} . " $things"; + $sing->del("/."); + $sing->put("/.",$things); + } + + # Let's put together the description with the rest of its fields. + my(@form,@formly,@complete); + open(FIELDS,"$format_deb"); + while () { + push(@form,$_); + } + close(FIELDS); + foreach (@form) { + push(@formly,$_); + my ($cool); + $count++; + if ($count == 7) { + my ($c, $cool); + if ($#formly != 0) { + for ($c = $#formly; $c >= 0; $c--) { + if ($c > 0) { + $cool = $formly[$c-1] .= $formly[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $formly[0]; + } + push(@complete,$cool); + @formly = (); + $count = 0; + } + } + + my $name_version; + foreach (@description) { + if ($count == 1) { + # -i + my $lingo = shift(@complete); + $lingo = $lingo . $_; + $ping->put($name_version,$lingo); + $lingo = (); + $count = 1; + } + else { + # packagename_version + $name_version = $_; + $count = 0; + } + $count++; + untie $ping; + } + undef $ping; + unlink($format_deb); + + ########################################### + # NEW FILE/DIR NFILEINDEX-ARCH-DISTS.DEB # + ########################################### + # add the files/dirs + if ($commands->{"Contents"}) { + if ($commands->{"Contents"} !~ /^FDB/) { + my $package_name; + + # we have come this far so we get to do the three steps. + # + # a). remove GONE (not CHANGED) from %packagediff + # b). if find in @NEW it is CHANGED so remove from %packagediff + # c). throw whats left into @NEW because files/dirs probably exist + # now. + # Any files returning 0 bytes will be dealt with below, first by + # creating a new .packagesdiff-arch-dist.deb, and second by being + # recorded in %ib. If the old .packagesdiff is + # still 0 (it isn't GONE) it will be placed in .packagesdiff again. + # No double dipping allowing in %ib if an old fellow exists from .pd. + # so $zing->del("/."); $zing->put("/.",$nsb{"/."}); + # Everything is in %nsb now, anyways. No .contentsdiff-arch-dist.deb + # is created for --ndb + + if ($#NEW != -1) { + + foreach (@sgone) { + delete $packagediff{$_}; + } + foreach (@NEW) { + delete $packagediff{$_}; + } + foreach (keys %packagediff) { + push(@NEW,$_); + } + + print "\n" if $#NEW != -1; + ndb(\%commands); $x = 1; + unlink("$tmp/nsearchindex.deb") if -e "$tmp/nsearchindex.deb"; + foreach $package_name (@NEW) { + # And a good place to set-up /. properly for CR as well as + # anything found in $packagediff if files aren't found, yet. + if (!defined $packagediff{$package_name}) { + my $subject = (split(/\s/,$nsb{$package_name}))[1]; + my (@file) = + remove_add_nfile($package_name,$ncontents,$subject,\%commands); + my $file = "$package_name.list"; + print "#$x"; print " VIRTUAL N|C|CR $file \r"; + $x++; + + if ($#file != -1) { + foreach (@file) { + #open(LIST,"$file"); + #while () { + #chomp; + + # This all looks nice, except for one thing we need to know + # whether an element pertains to one or more packages. Knowing + # something isn't a directory doesn't cut it, this differs + # greatly from SWIM::DB::db. That's why we create one big file + # here, and stick everything in the search db's after nfile* is + # updated. + if (!defined $ib{$_}) { + open(SEARCHINDEX,">>$tmp/nsearchindex.deb"); + print SEARCHINDEX "$_\n"; + close(SEARCHINDEX); + } # !defined + + # If the directory already exists we can just append + # to the end of the value + if (defined $ib{$_}) { + my $cvalue = $ib{$_} . " $db{$package_name}"; + #my $status = $zing->del($_); + $zing->put($_,$cvalue); + } # if defined + else { + $zing->put($_,$db{$package_name}); + } + } + #close(LIST); + #unlink("$file") if -e $file; + } # if file is 0 size + else { + # no sense putting non-US or experimental in here unless this + # is what is wanted. Only need to check for group non-us/* + # This is suppose to work, but not always. + if (!$commands->{"nue"}) { + if (defined $nsb{$package_name}) { + next if (split(/\s/,$nsb{$package_name}))[1] =~ m,non-us,; + } + if ($dist eq "experimental") { + next; + } + } + elsif ($dist eq "experimental") { + if (!$commands->{"nue"}) { + if (defined $nsb{$package_name}) { + next if (split(/\s/,$nsb{$package_name}))[1] =~ m,non-us,; + } + } + } + open(PACKAGEDIFF,">>$place/.packagesdiff$arch$dist.deb.bk") + or warn "Couldn't create packagediff\n"; + print PACKAGEDIFF "$db{$package_name}\n" + if $db{$package_name} ne ""; + close(PACKAGEDIFF); + #unlink("$file") if -e $file; + } + } + } # end foreach NEW + + ############################################ + # CHECKING CONTENTS FOR UNCHANGED PACKAGES # + ############################################ + my @PDbk; + if (-e "$place/.packagesdiff$arch$dist.deb") { + open(PD, "$place/.packagesdiff$arch$dist.deb"); + while () { + my $package_name = (split(/_/,$_))[0]; + if (!defined $BS{$package_name}) { + push(@PDbk,$_); + } + } + close(PD); + } + !-e "$place/.packagesdiff$arch$dist.deb" or + unlink("$place/.packagesdiff$arch$dist.deb"); + rename("$place/.packagesdiff$arch$dist.deb.bk", + "$place/.packagesdiff$arch$dist.deb"); + if (defined @PDbk) { + print "\n"; $x = 1; + # now we get to add a few more seconds checking to see if packages + # which haven't changed can now be found in Contents, so + # .packagesdiff* and nfile* can be proper. It's good to remember not + # changed as not CR or G. A little accounting would be nice. + foreach (@PDbk) { + my $o_name = $_; + my $package_name = (split(/_/,$_))[0]; + my $subject = (split(/\s/,$nsb{$package_name}))[1]; + my (@file) = + remove_add_nfile($package_name,$ncontents,$subject,\%commands); + my $file = "$package_name.list"; + print "#$x"; print " NO-C $file \r"; + $x++; + if ($#file != -1) { + foreach (@file) { + + # This all looks nice, except for one thing we need to know + # whether an element pertains to one or more packages. Knowing + # something isn't a directory doesn't cut it, this differs + # greatly from SWIM::DB::db. That's why we create one big file + # here, and stick everything in the search db's after nfile* is + # updated. + if (!defined $ib{$_}) { + open(SEARCHINDEX,">>$tmp/nsearchindex.deb"); + print SEARCHINDEX "$_\n"; + close(SEARCHINDEX); + } # !defined + + # If the directory already exists we can just append + # to the end of the value + if (defined $ib{$_}) { + my $cvalue = $ib{$_} . " $db{$package_name}"; + #my $status = $zing->del($_); + $zing->put($_,$cvalue); + } # if defined + else { + $zing->put($_,$db{$package_name}); + } + } + } # if file is not 0 size + else { + # no sense putting non-US or experimental in here unless this + # is what is wanted. Only need to check for group non-us/* + # This is suppose to work, but not always. + if (!$commands->{"nue"}) { + my $name = (split(/_/,$o_name))[0]; + if (defined $nsb{$name}) { + next if (split(/\s/,$nsb{$name}))[1] =~ m,non-us,; + } + if ($dist eq "experimental") { + next; + } + } + elsif ($dist eq "experimental") { + if (!$commands->{"nue"}) { + my $name = (split(/_/,$o_name))[0]; + if (defined $nsb{$name}) { + next if (split(/\s/,$nsb{$name}))[1] =~ m,^non-us/.*$,; + } + } + } + open(PD, ">>$place/.packagesdiff$arch$dist.deb"); + print PD "$o_name" if $o_name ne ""; + close(PD); + } + } + } + $zing->del("/."); $zing->put("/.",$nsb{"/."}); + + # now nsearch* and ndir* can be updated search() style + ############################## + # APPENDING SEARCH DATABASES # + ############################## + print "\nAppending search databases\n"; + open(SEARCH,"$tmp/nsearchindex.deb"); + open(SEARCHINDEX,">>$place/nsearchindex$arch$dist.deb"); + open(DIRINDEX,">>$place/ndirindex$arch$dist.deb"); + while () { + chomp; + if (defined $ib{$_}) { + my @dir = split(/\s/,$ib{$_}); + $#dir == 0 ? print SEARCHINDEX "$_\n" : print DIRINDEX "$_\n"; + } + } + untie %db; untie $zing; + } # prevents loop being entered in $#NEW is -1 + # and --check isn't called. + } + } + + + ############ + # N STATUS # + ############ + } # status_only + if (!$commands->{"check"}) { + my $yep = exist_sb(\%commands); + if (defined $yep) { + # now we update the status for N|G|CR|C packages. We will use + # statusindex.deb since all the figuring has already been done here, + # at first I was thinking of going through status, but this is + # unecessary, although it would alow n* to be updated before --db is + # used. Next, edit the status field in the description in npac* + # This checks everything in sb, it would be nice just to do an + # individual change or --db, but the issue of which n* should be used + # arises. + nping(\%commands); # because undefed before loop and ndb is used + print "Updating status\n"; my $x = 0; + foreach (keys %nsb) { + if (defined $sb{$_}) { + my ($veri,$stati) = (split(/\s/,$sb{$_}))[0,3]; $stati =~ s,:, ,g; + $veri = (split(/_/,$veri))[1]; my $vern; + if (defined $nsb{$_}) { + $vern = (split(/_/,((split(/\s/,$nsb{$_}))[0])))[1]; + $x++; + } + else { next; } + my $operand = comparison($vern,$veri); + compare_versions($operand,$vern,$veri,$_,\%commands) if + $commands->{"v"} && $operand ne ""; + if (defined $db{$db{$_}}) { + if ($db{$db{$_}} !~ m,Package:.+Status: $operand $stati \($veri\)| + Package:.+Status: $stati,x) { + $operand ne "" ? + ($db{$db{$_}} =~ s,Status:.*,Status: $operand $stati \($veri\),) : + ($db{$db{$_}} =~ s,Status:.*,Status: $stati,); + } + } + } # if found in statusindex + elsif (defined $db{$_}) { + if ($db{$db{$_}} =~ m,Package:.+Status:\s.*[^not-]+installed| + Package:.+Status:\s.*unpacked| + Package:.+Status:\s.*half-configured| + Package:.+Status:\s.*config-files,x) { + $db{$db{$_}} =~ s,Status:.*,Status: not-installed,; + } + } + } # foreach + print STDERR "$x installed packages found in n*\n" if defined $x; + } + } + + + unlink("$tmp/nsearchindex.deb") if -e "$tmp/nsearchindex.deb"; + print "\n" if $#NEW != -1; + print "$begin to ", scalar(localtime), "\n"; + +} # end sub update_packages_ndb + +# Generally, it's unecessary to rebuild the flat databases unless major +# changes have occurred to a person's installation, and the database has +# become very repetitive, or a file has changed into a directory. This +# function has also been tried by tieing the flat file to an array, but +# there doesn't seem to be that much of a speed advantage unless ib() +# happens to be in memory, but more experimentation will be tried in the +# future. Unfortunately for ni..keys %ib is not giving the proper amt. of +# elements unless used with DB_File compiled with libdb2. +sub rebuildflatndb { + + my($commands) = @_; + my %commands = %$commands; + nzing(\%commands); + + print scalar(localtime), "\n"; + + my ($arch,$dist) = which_archdist(\%commands); + my ($file,$dir); + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + !($commands->{"dbpath"} && $commands->{"root"})) { + if (-e "$parent$library/nsearchindex$arch$dist.deb") { + $dir = "$parent$library/ndirindex$arch$dist.deb"; + $file = "$parent$library/nsearchindex$arch$dist.deb"; + unlink($file); + unlink("$file.gz") if -e "$file.gz"; + unlink($dir); + unlink("$dir.gz") if -e "$dir.gz"; + } + else { + print "swim: operation only implemented for installed system\n"; + exit; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/nsearchindex$arch$dist.deb") { + $file = "$parent$base/nsearchindex$arch$dist.deb"; + $dir = "$parent$base/ndirindex$arch$dist.deb"; + unlink($file); + unlink("$file.gz") if -e "$file.gz"; + unlink($dir); + unlink("$dir.gz") if -e "$dir.gz"; + } + else { + print "swim: operation only implemented for installed system\n"; + exit; + } + } + + # HERE'S where it all happens + # We need to reconstruct long.debian & DEBIAN*, but can't take into account + # weirdisms with the database - NEW packages which aren't NEW. + open(DIR,">$dir"); + open(FILE,">$file"); + foreach (keys %ib) { + if (defined $ib{$_}) { + my $filedir = $_; + my $package = $ib{$_}; + my @the_amount = split(/\s/, $package); + if ($#the_amount > 0) { + print DIR "$filedir\n"; + } + elsif ($#the_amount == 0) { + print FILE "$filedir\n"; + } + } + } + #untie %ib; + print scalar(localtime), "\n"; + +} # end sub rebuildflatndb + + +1; diff --git a/lib/NDB_File.pm b/lib/NDB_File.pm new file mode 100644 index 0000000..a7c4349 --- /dev/null +++ b/lib/NDB_File.pm @@ -0,0 +1,251 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + +package SWIM::NDB_File; +use strict; +use SWIM::DB_Library qw(ram_on); # nzing nsb +use SWIM::Library; +use SWIM::Global qw($argument); # %ib $zing %nsb +use SWIM::Conf qw($pwd $tmp); +use SWIM::Dir; +use SWIM::Ramdisk; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(noram ncontents_exist find_contents remove_add_nfile); + +# This program handles updating nfileindex-arch-dists.deb + +# This checks if the ramdisk is on, we will want to turn it off, if it is. +sub noram { + + my ($commands) = @_; + my %commands = %$commands; + my $ramdisk = ram_on(\%commands); + + if ($ramdisk eq "yes") { + my $what = "yes"; + $commands{"ramdiskoff"} = 1; + ramdisk(\%commands); + } # if ramdisk + +} # end sub nfile + +# This will set-up the argument for ncontents if it can be found. +sub ncontents_exist { + + my ($commands) = @_; + my %commands = %$commands; + my $contentsdb = finddb(\%commands); + my ($arch,$dist) = which_archdist(\%commands); + + + if (-e "$contentsdb/ncontentsindex$arch$dist.deb.gz") { + if (-e "$contentsdb/ndirindex$arch$dist.deb.gz") { + unlink("$contentsdb/ndirindex$arch$dist.deb.gz"); + } + if (-e "$contentsdb/nsearchindex$arch$dist.deb.gz") { + unlink("$contentsdb/nsearchindex$arch$dist.deb.gz"); + } + return " $contentsdb/ncontentsindex$arch$dist.deb.gz|"; + } + else { + return "no"; + } + +} # end sub ncontents_exist + +# Find where the new Contents is on the on the command line vs the old +# Contents database (when the FDB argument isn't used). +sub find_contents { + + my ($commands) = @_; + my %commands = %$commands; + + ############ + # CONTENTS # + ############ + # Figure out where Contents is + if ($commands->{"Contents"}) { + my ($Contents,$FDB); + for ($commands->{"Contents"}) { + + ############### + # SITUATION 0 # + ############### + # this doesn't work to well for anything less simple than ../../ + if (m,^\.\./|^\.\.$,) { + if ($_ !~ m,/[\w-+]+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : (x$tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($Contents = "$tpwd/$_") : ($Contents = "$tpwd/"); + } + dir(\%commands); + fir(\%commands); + } + + ############### + # SITUATION I # + ############### + elsif ( m,\/,) { + $Contents = $_; + if ($Contents =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $Contents =~ m,^\.([^\.].*$),; + $Contents = "$pwd$1"; + } + else { + $Contents =~ m,^\.([^\.].*$),; + $Contents = "$1"; + } + } + dir(\%commands); + fir(\%commands); + } + + ################ + # SITUATION II # + ################ + elsif ($pwd =~ m,^\/$,) { + $Contents = "/$_"; + dir(\%commands); + fir(\%commands); + } + + ################# + # SITUATION III # + ################# + else { + $Contents = "$pwd/$_"; + if ($Contents =~ m,\.$,) { + $Contents =~ m,(.*)\.$,; + $Contents = $1; + } + dir(\%commands); + fir(\%commands); + } + } + + return $Contents; + + } # if Contents + +} # end sub find_contents + +# figure out --df and remove from nfileindex-arch-dists.deb +sub remove_add_nfile { + + my ($argument,$Contents,$subject,$commands) = @_; + my %commands = %$commands; + #my $contentsdb = finddb(\%commands); + #my ($arch,$dist) = which_archdist(\%commands); + ##nzing(\%commands); + + # the + solution + $argument =~ s,\+,\\\\+,g if $argument =~ m,\+,; + $Contents = "zgrep -E $argument\ $Contents"; + + my($dirfile,$package,@dirfile,%all,%again, + @package_match,@more_things,@file); + open(CONTENTSDB, "$Contents"); + while () { + # changed for >= 0.2.9 + #if (/^FILE\s*LOCATION$/) { + #while () { + ######## + # --DF # + ######## + $argument =~ s,\\\\+,\\\+,g if $argument =~ m,\+,; + if (m,$subject/$argument,) { + #if (m,\b$argument\b,) { + + ###################### + # ENDS WITH / # + ###################### + if (m,.*/\s+\w*,) { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); $dirfile =~ s,/$,,; + } + ###################### + # DOESN'T END WITH / # + ###################### + else { + ($dirfile,$package) = split(/\s+/,$_,2); + if ($package !~ m,^[a-z0-9-]*/.*$|^[a-z0-9-]*/.*/.*$,) { + my @more_things = split(/\s+/,$package); + $package = $more_things[$#more_things]; + (my $backpackage = $package) =~ s,\+,\\+,g; + my @dirfile = split(/\s+$backpackage/,$_); + $dirfile = $dirfile[0]; + } + @dirfile = split(/\//,$dirfile); + } + ########################### + # PROCESS INTO FILES/DIRS # + ########################### + my ($count,$holder); + for ($count = 0; $count <= $#dirfile; $count++) { + if ($count == 0) { + $holder = "/$dirfile[$count]"; + my $again = "$dirfile[$count]"; + $again{$again}++; + #my $all = "/."; + #$all{$all}++; + #if ($all{$all} == 1) { + #print FILELIST "/.\n"; + #} + if ($again{$again} == 1) { + push(@file,"/$dirfile[$count]"); + #print FILELIST "/$dirfile[$count]\n"; + } + } + else { + $holder = $holder . "/$dirfile[$count]"; + my $again = "$holder"; + $again{$again}++; + if ($again{$again} == 1) { + push(@file,"$holder"); + #print FILELIST "$holder\n"; + } + } + } # end for + } + undef @package_match; + #} + #} + } # while + close(CONTENTSDB); + undef @more_things; undef @dirfile; undef %again; undef %all; + return @file; + + +} # end sub remove_nfile + +1; diff --git a/lib/NDB_Init.pm b/lib/NDB_Init.pm new file mode 100644 index 0000000..c60d438 --- /dev/null +++ b/lib/NDB_Init.pm @@ -0,0 +1,2366 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::NDB_Init; +use strict; +use DB_File; +use SWIM::Library; +use SWIM::Format; +use SWIM::Conf qw(:Path $default_directory $apt_cache @user_defined_section + $distribution $pwd $sort $gzip $architecture $slowswim + $longswim $apt_sources $alt); +use SWIM::Global qw(%sb $argument); +use SWIM::Dir; +use SWIM::Compare; +use SWIM::MD; +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(initndb); + + +# initndb() not_installed() exist_sb() sb() compress_contests() nmd() +# --initndb --rebuildndb - exist_sb and sb are in DB_Library as well. + +# this checks for the @ARG for a not-installed database make and then runs +# not_installed() +sub initndb { + + my($commands) = @_; + my %commands = %$commands; + + my $one_more_arg = 0; + my $save_argument; + my($arch,$dist) = which_archdist(\%commands); + $dist =~ m,^-(.*)$,; my $dis = $1; my %what; + $arch =~ m,^-(.*)$,; my $arc = $1; my @what; + my $df = $default_directory; my $contents; + my $dd = $default_directory; + if ($#ARGV != -1) { + $ARGV[0] eq "APT" ? ($default_directory = $apt_sources) + : ($default_directory = $default_directory); + } + + # This provides the full path of dir/file. ../ not implemented yet. + # So, the queries can occur within each situation. + if ($#ARGV != -1) { + + + ###################### + # APT & DF SITUATION # + ###################### + # this part can also apply to apt + if ($ARGV[0] eq "DF" || $ARGV[0] eq "APT") { + if ($ARGV[0] eq "APT" && !defined $apt_cache) { + print "swim: this target requires apt\n"; + exit; + } + $df = $apt_sources if $ARGV[0] eq "APT"; + shift(@ARGV); + + # which section is wanted? + my ($main,$contrib,$non_free,$non_us,$experimental, + $omain,$ocontrib,$onon_free,$onon_us,$oexperimental); + $omain = "main" if $commands->{"main"}; + $ocontrib = "contrib" if $commands->{"contrib"}; + $onon_free = "non-free" if $commands->{"non-free"}; + $onon_us = "non-US" if $commands->{"non-us"}; + #$oexperimental = "experimental" + # if $commands->{"dists"} eq "experimental"; + + # Are we using a traditional debian archive structure from an + # alternative distribution..or is it debian? + if ($commands->{"alt"}) { + $alt = $commands->{"alt"}; + } + + if (!defined $main && !defined $contrib && + !defined $non_free && !defined $non_us) { + foreach (@user_defined_section) { + if ($_ eq "main") { + $main = "main"; + } + elsif ($_ eq "contrib") { + $contrib = "contrib"; + } + elsif ($_ eq "non-free") { + $non_free = "non-free"; + } + elsif ($_ eq "non-US") { + $non_us = "non-US"; + } + } + if (defined $commands->{"dists"}) { + if ($commands->{"dists"} eq "experimental") { + $experimental = "experimental"; + } + } + elsif ($distribution eq "experimental") { + $experimental = "experimental"; + } + } + + ################ + # USER DEFINED # + ################ + # use user defined values for sections..if any of these aren't + # true, options override the default values + if (!defined $omain && !defined $ocontrib && + !defined $onon_free && !defined $onon_us) { + if (defined $main) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_main_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_main_" . + "binary$arch" ."_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"MAIN"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"MAIN"} }) { + if (defined $what{"MAIN"}[$scount]) { + my $dsite = (split(/!/,$what{"MAIN"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"MAIN"}[$scount] = + $what{"MAIN"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $contrib) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_contrib_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_contrib_" . + "binary$arch" . "_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"CONTRIB"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"CONTRIB"} }) { + if (defined $what{"CONTRIB"}[$scount]) { + my $dsite = (split(/!/,$what{"CONTRIB"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"CONTRIB"}[$scount] = + $what{"CONTRIB"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $non_free) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_non-free_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_non-free_" . + "binary$arch" . "_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"NON-FREE"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + #print "$date $dsite $size\n"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"NON-FREE"} }) { + if (defined $what{"NON-FREE"}[$scount]) { + my $dsite = (split(/!/,$what{"NON-FREE"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"NON-FREE"}[$scount] = + $what{"NON-FREE"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $non_us) { + my $count = 1; + # on package1 hope $alt is correct? + my $package1 = $alt . "_" . "non-US" . "_" . "$dis" . + "_" . "binary$arch" . "_Packages"; + my $package2 = $alt . "_dists_" . "$dis" . "_non-US_" . + "binary$arch" . "_Packages"; + opendir(DF,"$df/"); + foreach (sort grep(/$package1|$package2/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"NON-US"}[$count] = + "$date!$mtime!$size!$dsite!$df/$_!none"; + $count++; + } + closedir(DF); + } + if (defined $experimental) { + my $count = 1; + my $package = $alt ."_project_experimental_Packages"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"EXPERIMENTAL"}[$count] = + "$date!$mtime!$size!$dsite!$df/$_!none"; + $count++; + } + closedir(DF); + } + } + ################ + # COMMAND LINE # + ################ + else { + if (defined $omain) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_main_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_main_" . + "binary$arch" . "_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"MAIN"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"MAIN"} }) { + if (defined $what{"MAIN"}[$scount]) { + my $dsite = (split(/!/,$what{"MAIN"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"MAIN"}[$scount] = + $what{"MAIN"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $ocontrib) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_contrib_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_contrib_" . + "binary$arch" . "_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"CONTRIB"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"CONTRIB"} }) { + if (defined $what{"CONTRIB"}[$scount]) { + my $dsite = (split(/!/,$what{"CONTRIB"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"CONTRIB"}[$scount] = + $what{"CONTRIB"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $onon_free) { + my $count = 1; + my $package = $alt . "_dists_" . "$dis" . "_non-free_" . + "binary$arch" . "_Packages"; + my $release = $alt . "_dists_" . "$dis" . "_non-free_" . + "binary$arch" . "_Release"; + opendir(DF,"$df/"); + foreach (sort grep(/$package/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"NON-FREE"}[$count] = "$date!$mtime!$size!$dsite!$df/$_"; + #print "$date $dsite $size\n"; + $count++; + } + closedir(DF); + $count = 1; + opendir(DF,"$default_directory"); + foreach (sort grep(/$release/, readdir(DF))) { + my $releasite = (split(/_/,$_))[0]; + open(RELEASE,"$default_directory/$_"); + while () { + if (m,^Version:,) { + m,^Version:\s+(.*),; my $Version = $1; + my $scount; + foreach $scount (0 .. $#{ $what{"NON-FREE"} }) { + if (defined $what{"NON-FREE"}[$scount]) { + my $dsite = (split(/!/,$what{"NON-FREE"}[$scount]))[3]; + if ($dsite eq $releasite) { + $what{"NON-FREE"}[$scount] = + $what{"NON-FREE"}[$scount] ."!$Version"; + } + } + } + } + } + close(RELEASE); + $count++; + } + closedir(DF); + } + if (defined $onon_us) { + my $count = 1; + my $package1 = $alt . "non-US" . "_" . "$dis" . "_" . + "binary$arch" . "_Packages"; + my $package2 = $alt . "_dists_" . "$dis" . "_non-US_" . + "binary$arch" . "_Packages"; + opendir(DF,"$df/"); + foreach (sort grep(/$package1|$package2/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what{"NON-US"}[$count] = + "$date!$mtime!$size!$dsite!$df/$_!none"; + #print "$date $dsite $size\n"; + $count++; + } + closedir(DF); + } + } + + #################### + # PACKAGE PRINTOUT # + #################### + # check to see that all Packages have a Release file, there is + # no date check on Release files because it is assumed that they + # will be kept current. Versions apt >= 3.2 download *Release. + # "none" if no Release is found, avoids unecessary errors, here. + # If all the Release versions are the same check against a file + # to find if there is a change, otherwise check against + # themselves. + my ($section,$site,$scount,%CHECK); + if (defined %what) { + foreach $section (keys %what) { + foreach $scount (0 .. $#{ $what{$section} }) { + if (defined $what{$section}[$scount]) { + my @CHECK = split(/!/,$what{$section}[$scount]); + if ($#CHECK != 5) { + print STDERR "swim: Missing Release files.\n"; + print STDERR "swim: This can occur when there is no Release file found at the site.\n"; + $what{$section}[$scount] = $what{$section}[$scount] ."!none"; + } + elsif ($CHECK[$#CHECK] ne "none") { + $CHECK{$CHECK[$#CHECK]} = ""; + } + } + } + } + } + my @AMT = keys %CHECK; + + # Time to store Release version number, if it is the same - no + # need to, if it has changed, time to make an important warning. + # Obviously this can occur for stable or unstable. + my $place = finddb(\%commands); my (@CHANGE,$CHANGE); + if (-e "$place/.release$arch$dist") { + open(VERSION,"$place/.release$arch$dist") or exit; + if ($#AMT == 0) { + @CHANGE = ; chomp $CHANGE[0]; + if ($CHANGE[0] ne $AMT[0]) { + $CHANGE = $CHANGE[0]; + } + } + } + else { + open(VERSION,">$place/.release$arch$dist") or exit; + if (!defined ) { + if ($#AMT == 0) { + print VERSION $AMT[0]; + } + } + } + + if (!$commands->{"cron"}) { + + # print out the stuff for analysis + $~ = "SUBJECT"; + $subsite = "Site"; $subdate = "Date"; $subsize = "Size (bytes)"; + $number = "###"; $subrelease = "Release"; + my $ex; + defined %what ? + write STDOUT : + ($ex = 0); + if (defined $ex) { + #if ($commands->{"dists"} || $commands->{"arch"}) { + print "swim: no Packages exist for $dis $arc\n"; + exit; + } + # Some changed + if ($#AMT > 0) { + $~ = "CENTER"; + $section = "WARNING: RELEASE CHANGE"; + $center = $section; + write STDOUT; + print "\n"; + } + # All changed + if (defined $CHANGE) { + $~ = "CENTER"; + $section = "WARNING: $AMT[0] to $CHANGE"; + $center = $section; + write STDOUT; + print "\n"; + } + foreach $section (keys %what) { + $~ = "CENTER"; + #print "CENTER $section\n"; + $center = $section; + write STDOUT; + foreach $scount (0 .. $#{ $what{$section} }) { + if (defined $what{$section}[$scount]) { + $~ = "SDS"; + my ($date,$size,$site,$release) = + (split(/!/,$what{$section}[$scount],))[0,2,3,5]; + $number = $scount; $sdsite = $site; + $sdsdate = $date; $sdsize = $size; + $sdsrelease = $release; + write STDOUT; + } + } + print "\n"; + } + + ####################### + # PACKAGE INTERACTIVE # + ####################### + # Let the person decide on one, or none for each section. + $~ = "STDIN"; + my ($OK,%GOON); + my $scal_count = 1; + my $end = (split(/\//, scalar(%what)))[0]; + + AGAIN: while (!defined $OK) { + foreach $section (keys %what) { + if (!defined $GOON{$section}) { + print "swim: for $section, which ### do you want?: "; + my $use_num = ; chomp $use_num; + if ($use_num ne "" && $use_num =~ /\b\d+\b/) { + if (defined $what{$section}[$use_num]) { + push(@ARGV,(split(/!/,$what{$section}[$use_num]))[4]); + $GOON{$section} = $section; + if ($scal_count == $end) { + $OK = "yes"; + } + } + else { + if ($scal_count < $end) { + print "swim: do you want to go on to the next section? (yes or no): "; + } + else { + print "swim: do you want this section? (yes or no): "; + $OK = "yes"; + } + my $again = ; #chomp $again; + while ($again eq "\n" || !($again eq "yes\n" + || $again eq "no\n")) { + print "swim: please enter yes or no: "; + $again = ; + } + $GOON{$section} = $section if $again ne "no\n"; + $scal_count++ if $again eq "yes\n"; + $end++ if $again eq "yes\n"; + next AGAIN if $again eq "no\n"; + } + } + else { + if ($scal_count < $end) { + print "swim: do you want to go on to the next section? (yes or no): "; + } + else { + print "swim: do you want this section? (yes or no): "; + $OK = "yes"; + } + my $again = ; #chomp $again; + while ($again eq "\n" || !($again eq "yes\n" + || $again eq "no\n")) { + print "swim: please enter yes or no: "; + $again = ; + } + $GOON{$section} = $section if $again ne "no\n"; + $scal_count++ if $again eq "yes\n"; + $end++ if $again eq "yes\n"; + next AGAIN if $again eq "no\n"; + } + } + $scal_count++; + } # for section + } + + exit if $#ARGV == -1; + + ################################ + # APT || DF CONTENTS SITUATION # + ################################ + if ($commands->{"Contents"}) { + if ($commands->{"Contents"} eq "FDBDF" || + $commands->{"Contents"} eq "DF") { + $df = $dd; + } + + my $count = 1; + $contents = "_" . "$dis" . "_" . "Contents$arch"; + opendir(DF,"$df/"); + foreach (sort grep(/$contents/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what[$count] = "$date!$mtime!$size!$dsite!$df/$_!none"; + $count++; + } + closedir(DF); + + ##################### + # CONTENTS PRINTOUT # + ##################### + + # print out the stuff for analysis + $~ = "SUBJECT"; + $subsite = "Site"; $subdate = "Date"; $subsize = "Size (bytes)"; + $number = "###"; + defined @what ? + write STDOUT : + ($ex = 0); + if (defined $ex) { + print "swim: no Contents exist for $dis $arc\n"; + # there is a reason to stop ofcourse! + exit; + } + $~ = "CENTER"; + #print "CENTER $section\n"; + $center = "CONTENTS"; + write STDOUT; + + foreach $scount (0 .. $#what) { + if (defined $what[$scount]) { + $~ = "SDS"; + my ($date,$size,$site,$release) = + (split(/!/,$what[$scount],))[0,2,3,5]; + $number = $scount; $sdsite = $site; + $sdsdate = $date; $sdsize = $size; + $sdsrelease = $release; + write STDOUT; + } + } + + ######################## + # CONTENTS INTERACTIVE # + ######################## + undef $OK; undef %GOON; + $~ = "STDIN"; + print "\n"; + AGAIN: while (!defined $OK) { + foreach $scount (1 .. $#what) { + print "swim: for CONTENTS, which ### do you want?: "; + my $use_num = ; chomp $use_num; + if ($use_num ne "" && $use_num =~ /\b\d+\b/) { + if (defined $what[$use_num]) { + ($contents) = (split(/!/,$what[$use_num]))[4]; + $OK = "yes"; + last; + } + else { + print "swim: do not use CONTENTS? (yes or no): "; + my $again = ; + while ($again eq "\n" || !($again eq "yes\n" + || $again eq "no\n")) { + print "swim: please enter yes or no: "; + $again = ; + } + next AGAIN if $again eq "no\n"; + $OK = "yes" if $again eq "yes\n"; last if $again eq "yes\n"; + } + } + else { + print "swim: do not use CONTENTS? (yes or no): "; + my $again = ; + while ($again eq "\n" || !($again eq "yes\n" + || $again eq "no\n")) { + print "swim: please enter yes or no: "; + $again = ; + } + next AGAIN if $again eq "no\n"; + $OK = "yes" if $again eq "yes\n"; last if $again eq "yes\n"; + } + } + } + } # if Contents + + } # if not cron + + ######## + # CRON # + ######## + # if no user interaction is wanted, this will figure out which + # Packages for each section and Contents database is the newest + # and use them. If the Release has changed --cron will not + # continue. This uses APT and/or DF. + else { + if ($#AMT > 0 || defined $CHANGE) { + print "swim: RELEASE CHANGE\n"; + exit; + } + + ############ + # PACKAGES # + ############ + my ($section,$site,$scount,%TIME); + if (defined %what) { + foreach $section (keys %what) { + foreach $scount (0 .. $#{ $what{$section} }) { + if (defined $what{$section}[$scount]) { + my $time = (split(/!/,$what{$section}[$scount]))[1]; + $TIME{$section}{"$section!$scount"} = $time; + } + } + } + } + foreach $section (keys %TIME) { + my @comparer; + foreach $site (keys %{ $TIME{$section} }) { + push(@comparer,$TIME{$section}{$site}); + } + @comparer = sort { $b <=> $a } @comparer; + my $newest = shift @comparer; + my %only_one; + foreach $site (keys %{ $TIME{$section} }) { + if ($TIME{$section}{$site} == $newest) { + $only_one{$newest}++; + if ($only_one{$newest} == 1) { + my($sect,$count) = (split(/!/,$site))[0,1]; + push(@ARGV,(split(/!/,$what{$sect}[$count]))[4]); + } + } + } + } + exit if $#ARGV == -1; + + ############ + # CONTENTS # + ############ + if ($commands->{"Contents"}) { + if ($commands->{"Contents"} eq "FDBDF" || + $commands->{"Contents"} eq "DF") { + $df = $dd; + } + + my $count = 1; + $contents = "_" . "$dis" . "_" . "Contents$arch"; + opendir(DF,"$df/"); + foreach (sort grep(/$contents/, readdir(DF))) { + my ($size,$mtime) = (stat("$df/$_"))[7,9]; + my $date = localtime($mtime); + my $dsite = (split(/_/,$_))[0]; + $what[$count] = "$date!$mtime!$size!$dsite!$df/$_!none"; + $count++; + } + closedir(DF); + + + my @time; + foreach (@what) { + if (defined $_) { + push(@time,$_); + } + } + + @what = map { $_->[1] } + sort { $b->[0] <=> $a->[0] } + map { [ (split(/!/,$_))[1], $_ ] } + @time; + + $contents = (split(/!/,$what[0]))[4]; + + } # end Contents + } + + } # end total thing pertaining to APT DF + + + foreach (@ARGV) { + ############### + # SITUATION 0 # + ############### + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/[\w-+]+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + } + else { print "swim: not implemented yet\n"; exit; } + dir(\%commands); + fir(\%commands); + #print "0 $argument\n"; + if ($one_more_arg > 0) { + $argument = qq($save_argument $argument); + } + $one_more_arg++; + $save_argument = $argument; + } + + ############### + # SITUATION I # + ############### + if ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + dir(\%commands); + fir(\%commands); + #print "I $argument\n"; + if ($one_more_arg > 0) { + $argument = qq($save_argument $argument); + } + $one_more_arg++; + $save_argument = $argument; + } + + ################ + # SITUATION II # + ################ + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + dir(\%commands); + fir(\%commands); + #print "II $argument\n"; + if ($one_more_arg > 0) { + $argument = qq($save_argument $argument); + } + $one_more_arg++; + $save_argument = $argument; + } + + ################# + # SITUATION III # + ################# + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + dir(\%commands); + fir(\%commands); + #print "III $argument\n"; + if ($one_more_arg > 0) { + $argument = qq($save_argument $argument); + } + $one_more_arg++; + $save_argument = $argument; + } + } # end foreach + # this is where SWIM::NDB::update_packages_ndb can be, too. + not_installed(\%commands) if $commands->{"initndb"} || + $commands->{"rebuildndb"}; + if ($commands->{"ndb"}) { + require SWIM::NDB; + SWIM::NDB->import(qw(update_packages_ndb)); + update_packages_ndb(\%commands,$contents); + } + } + + # NO ARGUMENTS + else { + print "swim: no Packages file mentioned\n"; + exit; + } + + ############ + # CONTENTS # + ############ + # Figure out where Contents is + if ($commands->{"Contents"}) { + my ($Contents,$FDB); + for ($commands->{"Contents"}) { + if ($commands->{"Contents"} =~ /^FDB/) { + s/FDB//; + $FDB = "yes"; + } + if ($commands->{"Contents"} eq "FDBDF" || + $commands->{"Contents"} eq "DF") { + $Contents = $contents; + } + + ############### + # SITUATION 0 # + ############### + # this doesn't work to well for anything less simple than ../../ + elsif (m,^\.\./|^\.\.$,) { + if ($_ !~ m,/[\w-+]+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($Contents = "$tpwd/$_") : ($Contents = "$tpwd/"); + } + dir(\%commands); + fir(\%commands); + } + + ############### + # SITUATION I # + ############### + elsif ( m,\/,) { + $Contents = $_; + if ($Contents =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $Contents =~ m,^\.([^\.].*$),; + $Contents = "$pwd$1"; + } + else { + $Contents =~ m,^\.([^\.].*$),; + $Contents = "$1"; + } + } + dir(\%commands); + fir(\%commands); + } + + ################ + # SITUATION II # + ################ + elsif ($pwd =~ m,^\/$,) { + $Contents = "/$_"; + dir(\%commands); + fir(\%commands); + } + + ################# + # SITUATION III # + ################# + else { + $Contents = "$pwd/$_"; + if ($Contents =~ m,\.$,) { + $Contents =~ m,(.*)\.$,; + $Contents = $1; + } + dir(\%commands); + fir(\%commands); + } + } + + if (!defined $FDB) { + # To the total db thing. Will have to find Contents. + if ($commands->{"initndb"} || $commands->{"rebuildndb"}) { + nmd($Contents,\%commands); + + # Do the the lowmem approach + system "$slowswim", $tmp, $sort; + + # has to know --arch and --dist + process_md(\%commands) + } + elsif ($commands->{"ndb"}) { + exit; + } + } + elsif (defined $FDB) { + compress_contents($Contents,\%commands); + } + + } # if Contents + +} # end sub initndb + +# This represents one on the most useful features of swim, the ability to +# evauluate a non-installed system by grabbing information from the +# Packages and Contents files. Ofcourse it is a hypothetical system, because +# lots of packages which wouldn't be able to live with one another are +# presented, and a few of swim's features which would normally be useful on a +# real system are disabled. But, this is a great way to explore around and +# discover things. The goal here is to provide information to +# people who don't even have dpkg installed so available won't be used. +# This will include architecture called and all. frozen, stable, and +# unstable distributions will have separate dbs. What will be kept will be +# determined by version. This is set-up so a person can use an indices +# file as well as a specific Packages, and Contents files (obviously, the +# proper Contents file will have to be used). +sub not_installed { + + my ($commands) = @_; + my %commands = %$commands; + + #my whatever that is + my ($arch, $dist); + my @Tdescription; + my @description; + my @ldescription; + my @package; + my %ndb; + my @name; + my $count = 0; + + my $the_status; + + my $status; + my @essential; + my $priority; + my $section; + my $installed_size; # at the very end + my $maintainer; + my $source; # at the very end + my $version; + my $ver; + + my %ngb; + my %group; + my $group; + + # Keeps a package->version database + # to save time over using status + my %nsb; + my @status; + my $things; # /. + my $scount = 0; + + my ($pre_depends, $depends, $replaces, $provides, $recommends, + $suggests, $conflicts, @REPLACE); + + my @conffiles; + my @conf; + my @complete; + my @form; + my @formly; + my $format_deb = "$tmp/format.deb"; + + my ($filename,@FILENAME); + my $size; + my @MD5SUM; + my ($ok,$goon); # arch & dist skippers + my $distro; # the distribution in the Packages + + # when revision: exists this helps md5sumo() since the package is labeled + # differently than the version number everywhere else. + my @revision; + + # Let's determine what architecture and distribution this person is + # interested in. + #if (defined $architecture || defined $distribution) { + # ($arch,$dist) = which_archdist(); + #} + if ($commands->{"arch"}) { + $architecture = $commands->{"arch"}; + } + else { + $architecture = $architecture; + } + + if ($commands->{"dists"}) { + $distribution = $commands->{"dists"}; + ($arch,$dist) = which_archdist(\%commands); + } + else { + $distribution = $distribution; + ($arch,$dist) = which_archdist(\%commands); + } + + + # we only need to clean-up, and decide what to do once. + +# Let's decide whether we should even go on. If it is --initdb, and +# the databases already exist, nothing should be touched, but if it is +# --rebuilddb and they exist, then they are removed and remade from +# scratch. + + # But first, better clean up any files in $tmp in case of an aborted + # database formation + unlink(<$tmp/DEBIAN*>) if -e "$tmp/DEBIANaa"; + unlink("$tmp/transfer.deb") if -e "$tmp/transfer.deb"; + unlink("$tmp/big.debian") if -e "$tmp/big.debian"; + unlink("$tmp/long.debian") if -e "$tmp/long.debian"; + + + # People may not want to use --Contents for a variety of reasons, so + # nfileindex-arch-dist.deb may not exist. If this is the case querying + # will have to be done a little bit differently. + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if ($commands->{"initndb"}) { + if (-e "$parent$library/npackages$arch$dist.deb") { + print "swim: use --rebuildndb\n"; + exit; + } + else { + # if a database happens to be missing + if (-e "$parent$library/npackages$arch$dist.deb") { + unlink("$parent$library/npackages$arch$dist.deb"); + } + if (-e "$parent$library/nfileindex$arch$dist.deb") { + unlink("$parent$library/nfileindex$arch$dist.deb"); + } + if (-e "$parent$library/ngroupindex$arch$dist.deb") { + unlink("$parent$library/ngroupindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb") { + unlink("$parent$library/ncontentsindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb.gz") { + unlink("$parent$library/ncontentsindex$arch$dist.deb.gz"); + } + # might as well delete these to free some room + if (-e "$parent$library/nsearchindex$arch$dist.deb") { + unlink("$parent$library/nsearchindex$arch$dist.deb"); + } + if (-e "$parent$library/nsearchindex$arch$dist.deb.gz") { + unlink("$parent$library/nsearchindex$arch$dist.deb.gz"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb") { + unlink("$parent$library/ndirindex$arch$dist.deb"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb.gz") { + unlink("$parent$library/ndirindex$arch$dist.deb.gz"); + } + + } + } + # this only works if all databases exist. + elsif ($commands->{"rebuildndb"}) { + if (-e "$parent$library/npackages$arch$dist.deb") { + unlink("$parent$library/npackages$arch$dist.deb"); + unlink("$parent$library/nfileindex$arch$dist.deb"); + unlink("$parent$library/ngroupindex$arch$dist.deb"); + unlink("$parent$library/nstatusindex$arch$dist.deb"); + if (-e "$parent$library/ncontentsindex$arch$dist.deb") { + unlink("$parent$library/ncontentsindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb.gz") { + unlink("$parent$library/ncontentsindex$arch$dist.deb.gz"); + } + # might as well delete these to free some room + if (-e "$parent$library/nsearchindex$arch$dist.deb") { + unlink("$parent$library/nsearchindex$arch$dist.deb"); + } + if (-e "$parent$library/nsearchindex$arch$dist.deb.gz") { + unlink("$parent$library/nsearchindex$arch$dist.deb.gz"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb") { + unlink("$parent$library/ndirindex$arch$dist.deb"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb.gz") { + unlink("$parent$library/ndirindex$arch$dist.deb.gz"); + } + } + else { + print "swim: use --initndb to create databases\n"; + exit; + } + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if ($commands->{"initndb"}) { + if (-e "$parent$base/npackages$arch$dist.deb") { + print "swim: use --rebuildndb\n"; + exit; + } + else { + # if a database happens to be missing + if (-e "$parent$base/npackages$arch$dist.deb") { + unlink("$parent$base/npackages$arch$dist.deb"); + } + if (-e "$parent$base/nfileindex$arch$dist.deb") { + unlink("$parent$base/nfileindex$arch$dist.deb"); + } + if (-e "$parent$library/ngroupindex$arch$dist.deb") { + unlink("$parent$base/ngroupindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb") { + unlink("$parent$library/ncontentsindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb.gz") { + unlink("$parent$library/ncontentsindex$arch$dist.deb.gz"); + } + # might as well delete these to free some room + if (-e "$parent$library/nsearchindex$arch$dist.deb") { + unlink("$parent$base/nsearchindex$arch$dist.deb"); + } + if (-e "$parent$library/nsearchindex$arch$dist.deb.gz") { + unlink("$parent$base/nsearchindex$arch$dist.deb.gz"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb") { + unlink("$parent$library/ndirindex$arch$dist.deb"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb.gz") { + unlink("$parent$library/ndirindex$arch$dist.deb.gz"); + } + } + } + # this only works if all databases exist. + elsif ($commands->{"rebuildndb"}) { + if (-e "$parent$base/npackages$arch$dist.deb") { + unlink("$parent$base/npackages$arch$dist.deb"); + unlink("$parent$base/nfileindex$arch$dist.deb"); + unlink("$parent$base/ngroupindex$arch$dist.deb"); + unlink("$parent$base/nstatusindex$arch$dist.deb"); + if (-e "$parent$library/ncontentsindex$arch$dist.deb") { + unlink("$parent$library/ncontentsindex$arch$dist.deb"); + } + if (-e "$parent$library/ncontentsindex$arch$dist.deb.gz") { + unlink("$parent$library/ncontentsindex$arch$dist.deb.gz"); + } + # might as well delete these to free some room + if (-e "$parent$library/nsearchindex$arch$dist.deb") { + unlink("$parent$library/nsearchindex$arch$dist.deb"); + } + if (-e "$parent$library/nsearchindex$arch$dist.deb.gz") { + unlink("$parent$library/nsearchindex$arch$dist.deb.gz"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb") { + unlink("$parent$library/ndirindex$arch$dist.deb"); + } + if (-e "$parent$library/ndirindex$arch$dist.deb.gz") { + unlink("$parent$library/ndirindex$arch$dist.deb.gz"); + } + } + else { + print "swim: use --initndb to create databases\n"; + exit; + } + } + } + + + # which section is wanted? + my ($main,$contrib,$non_free,$non_us); + $main = "main" if $commands->{"main"}; + $contrib = "contrib" if $commands->{"contrib"}; + $non_free = "non-free" if $commands->{"non-free"}; + # hopefully US is always capitalized -- watch this + $non_us = "non-US" if $commands->{"non-us"}; + if (!defined $main && !defined $contrib && !defined $non_free && + !defined $non_us) { + foreach (@user_defined_section) { + if ($_ eq "main") { + $main = "main"; + } + elsif ($_ eq "contrib") { + $contrib = "contrib"; + } + elsif ($_ eq "non-free") { + $non_free = "non-free"; + } + elsif ($_ eq "non-US") { + $non_us = "non-US"; + } + } + } + + + #!!! + print scalar(localtime), "\n"; + + # remove the version check file + my $place = finddb(\%commands); + if ($commands->{"v"}) { + unlink("$place/.version_compare"); + } + + # will use dir() and fir() to find path to Packages or Package.gz + # to make things easy, only one or more compressed files, or + # one or more non-compressed files may be used together in a set. + print "Data is being gathered\n"; + my @check_arg = split(/\s/,$argument); + my $ac = 0; + my $gz; + foreach (@check_arg) { + if ($ac == 0) { + if (-B || m,\.(gz|Z)$,) { + $argument = "gzip -dc $argument|"; + $gz = "yes"; + } + else { + $argument = "cat $argument|"; + } + } + else { + if (-B || m,\.(gz|Z)$,) { + if (!defined $gz) { + print "swim: targets must be one set of compressed or uncompressed file(s)\n"; + exit; + } + } + else { + if (defined $gz) { + print "swim: targets must be one set of compressed or uncompressed file(s)\n"; + exit; + } + } + } + $ac++; + } + + # I decided to not keep more than one instance of a package if + # it happens to have more than one version, this means running + # a check, but if the package exists in another architecture, then + # it isn't a repeat. + my (%Package_count,%not_me,$packler,%not_me2,%warch,%arc); + open(PACKAGE, "$argument"); + while () { + if (/^Package:/i) { + $packler = substr($_,9); chomp $packler; + $Package_count{$packler}++; + } + elsif (/^Version:/) { + # decide who shall rule with the greatest version + my $version = substr($_,9); chomp $version; + $not_me{$packler} = $version if $Package_count{$packler} == 1; + if ($Package_count{$packler} > 1) { + my $answer = comparison($not_me{$packler},$version); + if ($answer eq "<" || $answer eq "r<" || $answer eq "") { + delete $not_me{$packler}; delete $Package_count{$packler}; + $not_me{$packler} = $version; $Package_count{$packler} = 1; + delete $not_me2{$packler}; $not_me2{$packler} = $version; + } + else { + $not_me2{$packler} = $not_me{$packler}; + delete $Package_count{$packler}; $Package_count{$packler} = 1; + } + } + } # elsif version + elsif (/^Architecture:/) { + my $which_architecture = substr($_,14); + chomp $which_architecture; + if (!defined $warch{$packler}) { + $warch{$packler} = $which_architecture; + } + else { + $warch{$packler} = $warch{$packler} . " $which_architecture"; + } + # The assumption here is that there will never be two of the + # same architecture along with different ones, rather in cases + # where there are other archs, each will be unique, and where + # there are two or more of the same arch, a genuine repeat has + # occurred, this should cover the experimental dist. + if (defined $not_me2{$packler}) { + $arch =~ /-(.*)/; my $archi = $1; + #print "$packler\n"; + foreach (split(/\s/,$warch{$packler})) { + #print "$_\n"; + if ($_ eq $archi) { + $arc{"$archi$packler"}++; + #print "$archi$packler\n"; + } + } + if (defined $arc{"$archi$packler"}) { + if ($arc{"$archi$packler"} == 1) { + delete $not_me2{$packler}; + } + } + } + } # elsif arch + } + close(PACKAGE); + undef %warch; undef %Package_count; undef %not_me; + + my @hu = keys %not_me2; + print "REPEATS:" if $#hu != -1; + for (keys %not_me2) { + print " $_"; #print " $_ $not_me2{$_}"; + } + print "\n" if $#hu != -1; + + my %equalizer; $| = 1; my $x = 0; + open(PRETTY, ">$format_deb"); + open(PACKAGE, "$argument"); + while () { + # Package name + if (/^Package:|^PACKAGE:/) { + @package = split(/: /,$_); + chomp $package[1]; + $x = 1 if $x == 6; + print "|\r" if $x == 1 || $x == 4; print "/\r" if $x == 2; + print "-\r" if $x == 3 || $x == 6; print "\\\r" if $x == 5; + $x++; + } + # Some other pertinent fields + # All this stuff can be placed together..since it is generally nice + # to know these things at one glance, in this order. + # Package: Status: (will check database if it exists ver.) + # Version: Essential: (yes or no) + # Section: Priority: + # Installed-Size: Source: (if different from binary) + # Size: Architecture: + # Maintainer: + # Distribution: (stable, unstable, frozen, experimental - depending on + # version. --latest_version will only keep highest ver.) + # Description: + + elsif (/^Version:/) { + $version = $_; + chomp $version; + my $vion = substr($version,9); + my $pv = $package[1] . "_" . $vion; + if ($scount == 0) { + $things = $pv; + } + else { + $things = $things . " $pv"; + } + $scount++; + } + elsif (/^Priority:/) { + $priority = $_; + } + elsif (/^Section:/) { + $section = $_; + # make the hash for the groupindex.deb + $group = substr($section,9); + chomp $group; + if (!defined $group{$group}) { + $group{$group} = $package[1]; + #$nping->put($group,$package[1]); + } + else { + $group{$group} = "$group{$group} $package[1]"; + #$nping->put($group,"$group{$group} $package[1]"); + } + } + elsif (/^Essential:/) { + @essential = split(/: /,$_); + } + elsif (/^Maintainer:/) { + $maintainer = $_; + } + + # This stuff will be available with seperate query flags or -T + elsif (/^Pre-Depends:/) { + $pre_depends = $_; + if (defined($pre_depends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "PRE"; + push(@REPLACE, "$nv"); + push(@REPLACE, $pre_depends); + } + } + elsif (/^Depends:/) { + $depends = $_; + if (defined($depends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "DEP"; + push(@REPLACE, "$nv"); + push(@REPLACE, $depends); + } + } + elsif (/^Recommends:/) { + $recommends = $_; + if (defined($recommends)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "REC"; + push(@REPLACE, "$nv"); + push(@REPLACE, $recommends); + } + } + elsif (/^Suggests:/) { + $suggests = $_; + if (defined($suggests)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "SUG"; + push(@REPLACE, "$nv"); + push(@REPLACE, $suggests); + } + } + elsif (/^Conflicts:/) { + $conflicts = $_; + if (defined($conflicts)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "CON"; + push(@REPLACE, "$nv"); + push(@REPLACE, $conflicts); + } + } + elsif (/^Provides:/) { + $provides = $_; + if (defined($provides)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "PRO"; + push(@REPLACE, "$nv"); + push(@REPLACE, $provides); + } + } + elsif (/^Replaces:/) { + $replaces = $_; + if (defined($replaces)) { + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "REP"; + push(@REPLACE, "$nv"); + push(@REPLACE, $replaces); + } + } + # These next two determine whether to skip or keep the data. + # Filename has the name of the distribution. + ############## + # ARCH CHECK # + ############## + elsif (/^Architecture:/) { + my $which_architecture = substr($_,14); + chomp $which_architecture; + $arch =~ /-(.*)/; my $archi = $1; + ### REPEATERS ### + my $vion = substr($version,9); + if (defined $not_me2{$package[1]}) { + if ($not_me2{$package[1]} ne $vion) { + #print "Pack $package[1]\n"; + $which_architecture = "FUNNY"; + } + else { + $equalizer{$package[1]}++; + # to with the same version + if ($equalizer{$package[1]} > 1) { + $which_architecture = "FUNNY"; + #print "$package[1] no need to do it again\n"; + } + } + } + if ($which_architecture ne $archi) { + if ($which_architecture ne "all") { + # erasure time + ########## + # GROUPS # + ########## + # This keeps the groupindex proper + undef $ok; + (my $moggy = $package[1]) =~ s/\+/\\+/g; + #print "$distro $group == ", $group{$group}, " == $package[1]\n"; + #print "$group -", $group{$group}, "\n"; + my $check = ($group{$group} =~ m,(^.*)\s$moggy$,); + if ($check ne "") { + #print "DIST $disti $1\n"; + $group{$group} = $1; + } + else { + delete $group{$group}; + } + ########### + # REPLACE # + ########### + # this keeps deps correct + if (defined $pre_depends) { + pop(@REPLACE); pop(@REPLACE); + undef $pre_depends; + } + if (defined $depends) { + pop(@REPLACE); pop(@REPLACE); + undef $depends; + } + if (defined $recommends) { + pop(@REPLACE); pop(@REPLACE); + undef $recommends; + } + if (defined $suggests) { + pop(@REPLACE); pop(@REPLACE); + undef $suggests; + } + if (defined $conflicts) { + pop(@REPLACE); pop(@REPLACE); + undef $conflicts; + } + if (defined $provides) { + pop(@REPLACE); pop(@REPLACE); + undef $provides + } + if (defined $replaces) { + pop(@REPLACE); pop(@REPLACE); + undef $replaces; + } + + ########## + # STATUS # + ########## + my $vion = substr($version,9); + $vion =~ s/\+/\\+/g; + my $pv = $moggy . "_" . $vion; + my $scheck = ($things =~ m,(^.*)\s$pv$,); + if ($scheck ne "") { + $things = $1; + } + else { + $things = ""; + } + ##print "$scheck $things\n\n"; + # some of these things don't need to be undefed because + # they will be reset, because of the next. + undef $priority if defined $priority; + undef $section if defined $section; + undef $group if defined $group; + undef @essential if defined @essential; + undef $maintainer if defined $maintainer; + # undef $version if defined $version; + # undef @package if defined @package; + ###print "GONE $package[1]\n"; + #print "$things\n"; + $goon = "yes"; + next; + } + else { + #print "HUMM $which_architecture && $archi $package[1]\n"; + undef $goon; + #$ok = "yes"; + } + } # wrong architecture + else { + undef $goon; + } + } + + ######################### + # DIST CHECK & FILENAME # + ######################### + elsif (/^Filename:/ && !defined $goon) { + chomp; + $filename = $_; + my @fields = split(/\//,$filename); + $distro = $fields[1]; + my $archo; + if (defined $fields[3]) { + my $archos = $fields[3]; + #$archos =~ /^.*-(\w*)$/; + $archos =~ /^binary-([-\w]*)$/; + $archo = $1; + } + else { + # experimental looks like project/experimental/packagename_ver + # so the architecture will be what is specified. Right now, + # the only architectures in experimental is i386 and all. + # This makes sense because all is the goal of Debian. + $arch =~ /-(.*)/; my $archi = $1; + $archo = $archi; + } + $dist =~ /-(.*)/; my $disti = $1; + $arch =~ /-(.*)/; my $archi = $1; + my($mainf, $contribf, $non_freef, $non_usf, $experimentalf); + if (defined $fields[3]) { + if (defined $main) { + $mainf = "yes" if $fields[2] eq $main; + } + if (defined $contrib) { + $contribf = "yes" if $fields[2] eq $contrib; + } + if (defined $non_free) { + $non_freef = "yes" if $fields[2] eq $non_free; + } + if (defined $non_us) { + $non_usf = "yes" if $fields[2] eq $non_us; + } + } + # the distribution experimental has no sections. + elsif ($fields[0] eq "Filename: project") { + $experimentalf = "yes" if $fields[1] eq "experimental"; + } + #print "$filename && $distro && $archo && $fields[0]\n"; + #print "$disti -> $distro && $archi -> $archo\n"; + # project is experimental + # will determine whether this is right distribution and whether + # main, non-free, contrib, or non-us (not set up for traditional + # packages file) have been requested. options override the + # default + if ($disti eq $distro && $archi eq $archo && defined $mainf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $contribf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $non_freef) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo && defined $non_usf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + elsif ($disti eq $distro && $archi eq $archo + && defined $experimentalf) { + my $filen = substr($_,10); + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "FN"; + push(@FILENAME, "$nv"); + push(@FILENAME, $filen); + $ok = "yes"; + } + else { + # erasure time + ########## + # GROUPS # + ########## + # This keeps the groupindex proper + undef $ok; + # if (defined $package[1]) { + # $ppackage = $package[1]; + # } + (my $moggy = $package[1]) =~ s/\+/\\+/g; + ##print "$distro $group == ", $group{$group}, " == $package[1]"; + #print "$group -", $group{$group}, "\n"; + my $check = ($group{$group} =~ m,(^.*)\s$moggy$,); + if ($check ne "") { + #print "DIST $disti $1\n"; + $group{$group} = $1; + } + else { + #print "JUST ONE", $group{$group}, "\n"; + delete $group{$group}; + } + # if (defined $group{$group}) { + # print "$check -> $group: ", $group{$group}, "\n"; + # } + # print "\n"; + ########### + # REPLACE # + ########### + # this keeps deps correct + if (defined $pre_depends) { + pop(@REPLACE); pop(@REPLACE); + undef $pre_depends; + } + if (defined $depends) { + pop(@REPLACE); pop(@REPLACE); + undef $depends; + } + if (defined $recommends) { + pop(@REPLACE); pop(@REPLACE); + undef $recommends; + } + if (defined $suggests) { + pop(@REPLACE); pop(@REPLACE); + undef $suggests; + } + if (defined $conflicts) { + pop(@REPLACE); pop(@REPLACE); + undef $conflicts; + } + if (defined $provides) { + pop(@REPLACE); pop(@REPLACE); + undef $provides + } + if (defined $replaces) { + pop(@REPLACE); pop(@REPLACE); + undef $replaces; + } + + ########## + # STATUS # + ########## + my $vion = substr($version,9); + $vion =~ s/\+/\\+/g; + my $pv = $moggy . "_" . $vion; + my $scheck = ($things =~ m,(^.*)\s$pv$,); + if ($scheck ne "") { + $things = $1; + } + else { + $things = ""; + } + ###print "$scheck $things\n\n"; + # some of these things don't need to be undefed because + # they will be reset, because of the next. + undef $priority if defined $priority; + undef $section if defined $section ; + undef $group if defined $group; + undef @essential if defined @essential; + undef $maintainer if defined $maintainer; + # undef $version if defined $version; + # undef @package if defined @package; + ###print "GONE $package[1]\n"; + #print "$things\n"; + next; + } # wrong distribution + } + + ############ + # ######## # + # # MAIN # # + # ######## # + ############ + elsif (defined $ok) { + ##print "KEEP $package[1]\n"; + if (/^Size:/) { + $size = $_; + chomp; + } + # -qp --md5sum can do this + # this part and the next work together for description. + elsif (/^MD5sum/) { + chomp; + my $md5sum = substr($_,8); + chomp $md5sum; + my $vion = substr($version,9); + my $nv = "$package[1]" . "_" . "$vion" . "MD"; + push(@MD5SUM, "$nv"); + push(@MD5SUM, $md5sum); + } + + # We only need to go on here if it is the right architecture and + # distribution. + # To be combined with first fields. There are no packages + # missing this field, unlike a status file. + # defined either at architecture or filename. + elsif (m,Description:|^\s\w*|^\s\.\w*|^installed-size:|^revision:,){ + # this solved an annoying problem + if (/^\n$/) { + next; + } + #print "$_ && $package[1]\n"; + chomp $version; + $version =~ m,Version:\s(.*),; my $ending = $1; + my $many_lines = $_; + if ($_ !~ /^installed-size:|^revision:/) { + $count++; + if ($count == 1) { + if (defined $package[1]) { + #push(@dpackage,"$package[1]_$ending"); + push(@description,"$package[1]_$ending"); + } + } + if (defined($many_lines)) { + push(@ldescription,$many_lines); + } + } # end if ($_ !~ /^\n$/ + elsif ($_ =~ /^installed-size|^revision:/) { + $count = 0; + # let's put each description into one scalar + my ($c, $cool); + if ($#ldescription != 0) { + for ($c = $#ldescription; $c >= 0; $c--) { + if ($c > 0) { + $cool = $ldescription[$c-1] .= $ldescription[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $ldescription[0]; + } + if (defined $cool) { + push(@description,$cool); + } + @ldescription = (); + } # end else + } # end elsif Description + + ####################################### + # installed-size: followed by source: # + ####################################### + # if installed-size is at the end of Description, than source may + # follow. revision has been found once in the experimental + # distribution, but nothing was following it, this will have to be + # watched because the order isn't known, and installed-size and source + # will probably come into picture at some time. + if (/^installed-size:/ || /^revision:/) { + $installed_size = $_; + my $next = ; + # source follows + if ($next =~ /^source:/) { + $source = $next; + chomp $source; + chomp ($version, $section); + $col1 = "Package: $package[1]"; + + # status time + my $yep = exist_sb(\%commands); + if (defined $yep) { + my($different,$same); + my $pname = $package[1]; + if (defined $sb{$pname}) { + my ($vname,$gname,$priorname,$statusname) = + split(/\s/,"$sb{$pname}",4); + $statusname =~ s/:/ /g; + # a way to test + #$version = "Version: 1:5.0-2"; + my $pver = substr($version,9); + my $cname = $pname . "_" . $pver; + if ($vname eq $cname) { + $status = "Status: $statusname\n"; + $same = "yes"; undef($different); + } + else { + # here's where we get to do some comparisons + # we will have to compare sections. 1). may have changed + # 2). may be an unfair comparison free vs non-free, on the + # other-hand this should be in the person's awareness + # making the check. 1) will provide the answer to both. + $vname =~ m,^.*_(.*)$,; + my $ever = $1; + # print "$pname: $pver && $ever\n"; + # $pver = new $ever = installed + my $oper = comparison($pver,$ever); + compare_versions($oper,$pver,$ever,$pname,\%commands) + if $commands->{"v"}; + $status = + "Status: " . $oper . " $statusname ($ever)\n"; + $different = "yes"; undef($same); + } + } + else { + $status = "Status: not-installed\n"; + } + $col2 = $status; + untie %sb; + } + else { + $col2 = "Status: not-installed\n"; + } + write PRETTY; + $col1 = $version; + $version =~ m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # ran. + push(@name, $package[1]); + push(@status, $package[1]); + $package[1] = "$package[1]_$1"; + push(@name, $package[1]); + my $priory = substr($priority,10); + chomp $priory; + my $thimk = "$package[1] $group $priory"; + push(@status, $thimk); + if(defined($essential[1])) { + $col2 = "Essential: $essential[1]"; + @essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + $col1 = $section; + $col2 = $priority; + write PRETTY; + #my $cool = $installed_size . $maintainer; + my $einstalled_size = substr($installed_size,16); + chomp $einstalled_size; + $col1 = "Installed-Size: $einstalled_size"; + if (defined $source) { + my $esource = substr($source,8); + $col2 = "Source: $esource"; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + $col1 = $size; + $col2 = "Architecture: $architecture\n"; + write PRETTY; + if ($distro ne "experimental") { + $filename =~ m,^Filename: dists\/(\w*)\/.*$,; + print PRETTY "Distribution: $1\n"; + print PRETTY $maintainer + } + else { + my $exp_dist = "experimental"; + print PRETTY "Distribution: $exp_dist\n"; + print PRETTY $maintainer + } + } # if $next =~ source + + + ############################################## + # installed-size: or revision: by themselves # + ############################################## + # source doesn't follow + elsif ($next =~ /^\n$/) { + chomp($version, $section); + $col1 = "Package: $package[1]"; + + # revision magic + if (/revision:/) { + $filename =~ m,.*/(.*)\.deb$,; + my $rr = $1 . "MD"; + my $rver = substr($version,9); + my $prr = $package[1] . "_" . "$rver" . "MD REVISION"; + push(@revision,$rr); push(@revision,$prr); + } + + # status time + my $yep = exist_sb(\%commands); + if (defined $yep) { + my($different,$same); + my $pname = $package[1]; + if (defined $sb{$pname}) { + my ($vname,$gname,$priorname,$statusname) = + split(/\s/,"$sb{$pname}",4); + $statusname =~ s/:/ /g; + # a way to test + #$version = "Version: 1:5.0-2"; + my $pver = substr($version,9); + my $cname = $pname . "_" . $pver; + if ($vname eq $cname) { + $status = "Status: $statusname\n"; + $same = "yes"; undef($different); + } + else { + # here's where we get to do some comparisons + # we will have to compare sections. 1). may have changed + # 2). may be an unfair comparison free vs non-free, on the + # other-hand this should be in the person's awareness + # making the check. 1) will provide the answer to both. + $vname =~ m,^.*_(.*)$,; + my $ever = $1; + # print "$pname: $pver && $ever\n"; + # $pver = new $ever = installed + my $oper = comparison($pver,$ever); + compare_versions($oper,$pver,$ever,$pname,\%commands) + if $commands->{"v"}; + $status = + "Status: " . $oper . " $statusname ($ever)\n"; + $different = "yes"; undef($same); + } + } + else { + $status = "Status: not-installed\n"; + } + $col2 = $status; + untie %sb; + } # if defined $yep + else { + $col2 = "Status: not-installed\n"; + } + write PRETTY; + $col1 = $version; + $version =~ m,Version:\s(.*),; + # This creates a name -> version index in package.deb, + # and the statusindex.deb database which will serve to + # determine if the status has changed when --db or -i is + # ran. + push(@name, $package[1]); + push(@status, $package[1]); + $package[1] = "$package[1]_$1"; + push(@name, $package[1]); + my $priory = substr($priority,10); + chomp $priory; + my $thimk = "$package[1] $group $priory"; + push(@status, $thimk); + if(defined($essential[1])) { + $col2 = "Essential: $essential[1]"; + @essential = (); + } + else { + $col2 = "Essential: no\n"; + } + write PRETTY; + $col1 = $section; + $col2 = $priority; + write PRETTY; + #my $cool = $installed_size . $maintainer; + my $einstalled_size = substr($installed_size,16); + chomp $einstalled_size; + $col1 = "Installed-Size: $einstalled_size"; + if (defined $source) { + my $esource = substr($source,8); + $col2 = "Source: $esource"; + } + else { + $col2 = ""; + } + write PRETTY; + undef $source; + $col1 = $size; + $col2 = "Architecture: $architecture\n"; + write PRETTY; + if ($distro ne "experimental") { + $filename =~ m,^Filename: dists\/(\w*)\/.*$,; + print PRETTY "Distribution: $1\n"; + print PRETTY $maintainer + } + else { + my $exp_dist = "experimental"; + print PRETTY "Distribution: $exp_dist\n"; + print PRETTY $maintainer + } + } # if $next =~ source + } # elsif installed-size + } # right arch and dist + } # end while () + close(PRETTY); + + # Let's put together the description with the rest of its fields. + open(FIELDS,"$format_deb"); + while () { + push(@form,$_); + } + close(FIELDS); + + $count = 0; + + foreach (@form) { + push(@formly,$_); + my ($cool); + $count++; + if ($count == 7) { + my ($c, $cool); + if ($#formly != 0) { + for ($c = $#formly; $c >= 0; $c--) { + if ($c > 0) { + $cool = $formly[$c-1] .= $formly[$c]; + } + } #end for + } # end if ($#ld + else { + $cool = $formly[0]; + } + push(@complete,$cool); + @formly = (); + $count = 0; + } + } + + foreach (@description) { + if ($count == 1) { + my $lingo = shift(@complete); + $lingo = $lingo . $_; + push(@Tdescription, $lingo); + $lingo = (); + $count = 1; + } + else { + push(@Tdescription, $_); + $count = 0; + } + $count++; + + } + + unlink($format_deb); + + #untie $nping; + #undef %ngdb; + + # We'll keep databases local so that md() doesn't get confused with + # database(). + + # Put the groups into the groupindex.deb database. + print "Not-installed Group Database is being made\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %ngb, 'DB_File', "$parent$library/ngroupindex$arch$dist.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %ngb, 'DB_File', "$parent$base/ngroupindex$arch$dist.deb" or die "DB_File: $!"; + } + + # assigning to HUMM solves a strange problem. semi-panic: attempt to dup + # freed string..internal newSVsv() routine was caused to duplicate a + # scalar that had been previously marked as free. + my @HUMM = %group; + %ngb = @HUMM; + untie %ngb; + undef %ngb; + undef %group; + undef @HUMM; + + # Create the important status database. + print "Not-installed Status Database is being made\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %nsb, 'DB_File', "$parent$library/nstatusindex$arch$dist.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %nsb, 'DB_File', "$parent$base/nstatusindex$arch$dist.deb" or die "DB_File: $!"; + } + + push(@status,"/."); + if ($things =~ /^\s.*/) { + $things =~ s/^\s//; + } + push(@status,$things); + %nsb = @status; + + untie %nsb; + undef %nsb; + undef @status; + undef $scount; + + # Put everything into the package.deb database. + print "Not-installed Description Database is being made\n"; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + tie %ndb, 'DB_File', "$parent$library/npackages$arch$dist.deb" or die "DB_File: $!"; + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + tie %ndb, 'DB_File', "$parent$base/npackages$arch$dist.deb" or die "DB_File: $!"; + } + + %ndb = (@name,@Tdescription,@conf,@REPLACE,@FILENAME,@MD5SUM,@revision); + untie %ndb; + undef @Tdescription; + undef @conf; + undef @REPLACE; + undef @FILENAME; + undef @MD5SUM; + undef @revision; + undef %ndb; + + print scalar(localtime), "\n" if !$commands->{"Contents"}; + + +} # ends sub not_installed + + +# This first looks in the immediate directory for statusindex.deb, if it +# isn't found here, it look in the default directory. It then returns +# undef, or initializes the database based on its findings. +sub exist_sb { + + my ($commands) = @_; + my %commands = %$commands; + + my $yep; + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/statusindex.deb") { + $yep = "yes"; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/statusindex.deb") { + $yep = "yes"; + } + } + + if (!defined $yep) { + if (-e "$parent$base/statusindex.deb") { + tie %sb, 'DB_File', "$parent$base/statusindex.deb" + or die "DB_File: $!"; + return "yes"; + } + else { + return; + } + } + elsif (defined $yep) { + sb(\%commands); + return "yes"; + } + +} # end sub exist_sb + + +sub sb { + + my ($commands) = @_; + + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + if (-e "$parent$library/statusindex.deb") { + tie %sb, 'DB_File', "$parent$library/statusindex.deb" + or die "DB_File: $!"; + } + else { + return; + } + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + if (-e "$parent$base/statusindex.deb") { + tie %sb, 'DB_File', "$parent$base/statusindex.deb" + or die "DB_File: $!"; + } + else { + return; + } + } +} # end sub sb + +# This creates the file filedir.deb using using the program longswim. The +# options --main, --contrib, non-free, non-us, or the default value is +# taken into consideration. +sub nmd { + + my ($Contents,$commands) = @_; + my %commands = %$commands; + my ($dbpath, $root); + + my ($main,$contrib,$non_free,$non_us); + $main = "yes" if $commands->{"main"}; + $contrib = "yes" if $commands->{"contrib"}; + $non_free = "yes" if $commands->{"non-free"}; + $non_us = "yes" if $commands->{"non-us"}; + if (!defined $main && !defined $contrib && !defined $non_free && + !defined $non_us) { + foreach (@user_defined_section) { + if ($_ eq "main") { + $main = "yes"; + } + elsif ($_ eq "contrib") { + $contrib = "yes"; + } + elsif ($_ eq "non-free") { + $non_free = "yes"; + } + elsif ($_ eq "non-us") { + $non_us = "yes"; + } + } + } + + $main = "no" if !defined($main); + $contrib = "no" if !defined($contrib); + $non_free = "no" if !defined($non_free); + $non_us = "no" if !defined($non_us); + + my $Contents_mtime = (stat($Contents))[9]; + $Contents = -B $Contents || $Contents =~ m,\.(gz|Z)$, ? + "$gzip -dc $Contents|" : "cat $Contents|"; + my $contentsdb = finddb(\%commands); + my($arch,$dist) = which_archdist(\%commands); + my $contentsindex = "$contentsdb/ncontentsindex$arch$dist.deb"; + my $npackages = "$contentsdb/npackages$arch$dist.deb"; + + print "Gathering the file(s)/dir(s) for the arch-dist section(s)\n"; + + # 0 1 2 3 4 5 6 + system "$longswim", + $Contents, $contentsindex, $main, $contrib, $non_free, $non_us, $tmp, + $npackages, $gzip, $contentsdb, $Contents_mtime; + + # longswim can be tested with something like this: + # /usr/lib/SWIM/longswim.alt "cat /USE/Contents|" \ + # /test/ncontentsindex-i386-unstable.deb yes yes yes yes \ + # /test /USE/npackages-i386-unstable.deb gzip /test 11111111 + +} # end sub nmd + + + + + +1; diff --git a/lib/Pn_print.pm b/lib/Pn_print.pm new file mode 100644 index 0000000..876b8fe --- /dev/null +++ b/lib/Pn_print.pm @@ -0,0 +1,97 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Pn_print; +use strict; +use SWIM::Global qw($argument); +use vars qw(@ISA @EXPORT); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(singular); + + +# There are times when it is good to print out the "package name_version" +# and there are times when it is unecessary. This sub tries to resolve +# these situations, basically it's printme() +sub singular { + + my ($commands) = @_; + my %commands = %$commands; + + # for files, dirs, or groups + if (($commands->{"f"} || $commands->{"dir"} || $commands->{"g"} || + $commands->{"q"}) && + !($commands->{"i"} || $commands->{"l"} || + $commands->{"df"} || $commands->{"d"} || $commands->{"c"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + print "$argument\n"; + } + elsif (($commands->{"f"} || $commands->{"dir"} || $commands->{"g"} || + $commands->{"q"}) && + $commands {"c"} && !($commands->{"i"} || + $commands->{"df"} || $commands->{"d"} || $commands->{"l"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} && + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + print "$argument\n"; + } + elsif (($commands->{"f"} || $commands->{"dir"} || $commands->{"g"} || + $commands->{"q"}) && + $commands {"c"} && $commands->{"d"} && + !($commands->{"i"} || $commands->{"df"} || $commands->{"l"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + print "$argument\n"; + } + elsif (($commands->{"f"} || $commands->{"dir"} || $commands->{"g"} || + $commands->{"q"}) && + $commands {"c"} && ($commands->{"d"} || + $commands->{"l"}) && !($commands->{"i"} || $commands->{"df"} || + $commands->{"scripts"} || $commands->{"preinst"} || $commands->{"postinst"} || + $commands->{"prerm"} || $commands->{"postrm"} || $commands->{"T"} || + $commands->{"pre_depends"} || $commands->{"depends"} || + $commands->{"recommends"} || $commands->{"suggests"} || + $commands->{"provides"} || $commands->{"replaces"} || + $commands->{"conflicts"} || $commands->{"requires"} || + $commands->{"changelog"} || $commands->{"m"} || $commands->{"menu"} || + $commands->{"copyright"})) { + print "$argument\n"; + } + +} # end sub singular + + +1; diff --git a/lib/Qftp.pm b/lib/Qftp.pm new file mode 100644 index 0000000..b8248f7 --- /dev/null +++ b/lib/Qftp.pm @@ -0,0 +1,951 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Qftp; +use strict; +use SWIM::Conf; +use SWIM::Global qw(@PACKAGES $argument %db); +use SWIM::DB_Library qw(:Xyz); +use SWIM::Deb qw(md5sumo); +use vars qw(@ISA @EXPORT); +use Net::FTP; +use SWIM::F; +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(qftp); + + +=pod + +This is the ftp client when --ftp is called with -q, --search/--ps. The +downloaded packages are put in the Default directory (DF) in a directory +mirroring (in a way relative to the design of swim) the dists structure +which is standard with Debian. This is desirable if a person wants to mirror +parts of a remote ftp site above the +default_directory/default_root_directory/; this also makes it easy for a +person to make their own distribution if they want, and apt can be used to +install the packages at a later time by temporarily placing them in +/var/cache/apt/archives using --df2apt. Obviously, this is nicer than using +apt just to download the packages, but the --nz option (apt) is provided +just in case a person is too lazed to do the -T thing, then they can do the +--apt2df thingy to move the packages from /var/cache/apt/archives to the +appropriate place in the DF. Ofcourse, maybe the -T thing was what the +person didn't want to do, or maybe the person wants to do a combination of +both (like something in the -T apt doesn't care about), this would be an +instance where --ftp would be more useful. The configuration file presents +a way to set this up so that the directory particular to the local ftpd can +be integrated into the DF. The DF can be given any unique named +directories, and the permisions of the directories created above can also be +specified. Other options to control the DF will be provided, and -h will be +available for querying the database pertaining to the packages in the DF, +thereby allowing manipulation of the packages in the DF. The database will +be made from Packages databases updated whenever the DF is called. There +will be two types of Packages, one pertaining to the state of the local +system, and the other pertaining to the state of the real distribution. +--file, and --http will also be integrated with DF when they become +available. + +IMPORTANT: Support will only be provided for not-installed databases, use a +not-installed database which reflects the currently installed package you +want to download in binary or source code. This is due to the fact that swim +thinks in terms of distribution states, and your installed system may +represent a combination of these things. The md5sum is currently checked +for packages, but not for source, if the md5sum data exists (not a new +debian-revision, for instance) the package will be checked. Whether or not +the package is OK it will be placed in it's appropriate place if it +downloads correctly. If you get FAILED, examine the package and alert +the +community (download place, what's wrong with the package), then delete the +package. + +=cut +sub qftp { + + my ($arg,$commands) = @_; + my %commands = %$commands; + + + # Although the /dists/... could be found with -i, it's simpler + # just to use name_versionFILENAME instead. People shouldn't + # edit --stdin to combine different distributions when doing --ftp, + # (note: ofcourse apt-cache dumpavail could be used, and + # ncontentsindex could be put together from many dbs) + # since swim can only figure out what distribution is wanted + # from the default value or the one provided on the command line. + # The same is true of using apt. Whatever package is + # provided to --stdin is assumed to be of the specified distribution, + # anyways. + if (!$commands->{"n"}) { + dbi(\%commands); + @PACKAGES = map($db{$_},(@PACKAGES = split(/\s/,$arg))); + } + else { + ndb(\%commands); + @PACKAGES = map($db{$_},(@PACKAGES = split(/\s/,$arg))) + } + + + my @LOCATION; + for (0 .. $#PACKAGES) { + if (!defined $PACKAGES[$_]) { + print "swim: specified package(s) not found in database\n"; + exit; + } + } + if (defined $db{$PACKAGES[0] . "FN"}) { + @LOCATION = map($db{$_ . "FN"},@PACKAGES); + } + else { + print "swim: incorrect database was specified\n"; + exit; + } + + # might as well check for a temporary directory for downloads, if it + # doesn't exist create it. + mkdir("$default_directory/partial",$permission) + if !-d "$default_directory/partial"; + + # Check if there is a sources.list specified + if (-e "$swim_conf/swimz.list") { + undef @FTP; + open(SOURCES,"$swim_conf/swimz.list") + or warn "swim: could not find swimz.list\n"; + while () { + if ($_ !~ m,#.*|^\s+,) { + chomp; push(@FTP,$_); + } + } + if ($#FTP == -1) { + print "swim: no sites specified in swimz.list, quiting\n"; + exit; + } + } + + # let's make unique sites + my (%site,@sites,$site); + foreach $site (@FTP) { + my @parts = split(' ', $site); + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + $site{$1}++; + push(@sites,"$1!$site") if $site{$1} == 1; + } + + + foreach $site (@sites) { + + # will provide all kinds of options for ftp..like firewall + + my $uri; ($site, $uri) = split(/!/,$site); + my $ftp = Net::FTP->new($site, + Debug => $debug, + Timeout => $timeout, + Passive => $passive, + Firewall => $firewall, + Port => $port + ); + + ########### + # CONNECT # + ########### + if (defined $ftp) { + my $connected = $ftp->code(); + if ($connected == 220) { + print "swim: connected to $site\n"; + } + } + else { + print "swim: could not find $site\n"; + next; + } + + + ######### + # LOGIN # + ######### + $ftp->login("anonymous","swim\@the.netpedia.net"); + my $logged = $ftp->code(); + # we are logged, but what is the time difference. + if ($logged == 230 || $logged == 332) { + print "swim: logged in to $site\n"; + $ftp->binary; + } + else { + # 530 "not logged in" will have to test this + $ftp->code(); + print "swim: not logged in to $site\n"; + next; + } + + # find the base to the distribution + my @parts = split(' ', $uri); + $parts[1] =~ m,^ftp:/+( (?: (?!/). ) *)(.*),sx; + my $base = $2; + + # this finds the base, but it only needs to be found once, ofcourse + # a foreach is totally unecessary unless the site has weird symlinks. + my @tryme_again; my $base_count = 0; + foreach (@FTP) { + next if $base_count == 1; + + ############ + # SETUP # + ############ + LOCUS: foreach (@LOCATION) { + m,(.*)/(.*)$,; + my $uptopackage = $1; + my $packagename = $2; my $packagen = $2; + $packagename =~ s,\+,\\\+,g; + my ($source_drd,$drd); + # make directories with permissions if they don't already exist + # and also establish standardized (swimy) debian-non-US and the + # appropriate symlinks + # if a non-US file is requested. + if ($uptopackage !~ /non-US/) { + if (!-d "$default_directory/$default_root_directory/$uptopackage") { + my $place = "$default_directory/$default_root_directory"; + my @DP = split(m,/,,$uptopackage); + my $placement = "/"; + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission); + # will fix this later + # or warn "swim: could not create dists directory\n"; + # Ofcourse there is even a better fix. + } + } + } + #################### + # ################ # + # # NON-US FILES # # + # ################ # + #################### + else { + (my $above_drd = $uptopackage) =~ s,dists,,; + $above_drd =~ s,non-US/,,; + $source_drd = (split(m,/,,$above_drd))[1]; + ($drd = $default_root_directory) =~ s,/debian,,; + if (!-e "$default_directory$drd/debian-non-US$above_drd") { + my $place = "$default_directory"; + my $create = "$drd/debian-non-US$above_drd"; + my @DP = split(m,/,,$create); + my $placement = "/"; + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission) + or warn "swim: could not create debian-non-US directory\n"; + } + if (!-d "$default_directory$drd/debian-non-US/$source_drd/source") { + my $place = "$default_directory"; + my $create = "$drd/debian-non-US/$source_drd/source"; + my @DP = split(m,/,,$create); + my $placement = "/"; + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission) + or warn "swim: could not create debian-non-US directory\n"; + } + } + + $place = "$default_directory$drd/debian-non-US"; + my $disty = (split(m,/,))[1]; $create = "/dists/$disty"; + undef @DP; + @DP = split(m,/,,$create); + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission) + or warn "swim: could not create debian-non-US directory\n"; + } + + # make the symlinks + chdir("$place$placement"); + symlink("../../$disty","non-US"); + symlink("../../$disty/source","source"); + + $place = "$default_directory$drd/debian"; $create = "/dists/$disty"; + undef @DP; + @DP = split(m,/,,$create); + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission) + or warn "swim: could not create debian-non-US directory\n"; + } + chdir("$place$placement"); + + # make more symlinks + symlink + ("../../../debian-non-US/dists/$disty/non-US","non-US"); + } # if non-US dir !-e + } # end non-us + + + ####### + # GET # + ####### + my $file; + ($packagen = $packagename) =~ s,\\\+,\+,g; + my $localfile = + "$default_directory/partial/$packagen"; + my $home = + "$default_directory/$default_root_directory/$_"; + my $size = $ftp->size("$base/$_"); + my $rmtime = $ftp->mdtm("$base/$_"); + my $file_exist = $ftp->code(); + ######################### + # CHECK DEBIAN-REVISION # + ######################### + # the way this is set up, it is assumed that something exists for + # the -(debian-revision). + if ($file_exist == 550) { + print "swim: $packagen does not exist on the server\n"; + print "swim: checking to see if the debian-revision has changed\n"; + $packagename =~ m,^(.*)-[\dA-Za-z\.\+]+\.deb$,; + my $matcher = $1; + $_ =~ m,^(.*)/$matcher[-\da-zA-Z\.\+]+\.deb$,; + my $otherthing = $1; + my $REVISIONCHANGE = $ftp->ls("$base/$uptopackage"); + my $singfile; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher[-\dA-Za-z\.\+]+\.deb)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + } + } + my $checkfile; + defined $file + ? ($checkfile = $otherthing . "/$file") + : ($checkfile = "NOFILE"); + $size = $ftp->size("$base/$checkfile"); + $rmtime = $ftp->mdtm("$base/$checkfile"); + $file_exist = $ftp->code(); + print "swim: could not find $packagen debian-revision\n" + if $file_exist == 550; + push(@tryme_again,$_) if $file_exist == 550; + next if $file_exist == 550; + $localfile =~ s,$matcher[-\dA-Za-z\.\+]*\.deb$,$file,; + $home = + "$default_directory/$default_root_directory/$uptopackage/$file"; + $packagename = $file; $file = $otherthing . "/$file"; + } # END DEBIAN-REVISION + else {$file = $_; } + my ($lsize,$lmtime); + + + ######################## + # SAME PACKAGE LOCALLY # + ######################## + $packagename =~ m,(^[A-Za-z\d\+-\\+]*)_([\\+A-Za-z\d\+\.:]*) + [-]?[\dA-Za-z\.\+]*\.deb$,x; + my $spackage = $1; my $upstream_revision = $2; + $spackage =~ s,\+,\\\+,g; + if (-e $home) { + ($lsize,$lmtime) = (stat($home))[7,9]; + } + # If the upstream-revision has changed and + # a local package with the same name exists, we want to delete it. + else { + opendir(DF,"$default_directory/$default_root_directory/$uptopackage"); + my $grepthing = "^" . $spackage . "_"; + #my $grepthing = $spackage . "_" . $upstream_revision; + foreach (sort grep(/$grepthing/, readdir(DF))) { + m,(.*)_([\dA-Za-z\+\.:]+)[-]?[\dA-Za-z\+\.]*\.deb$,; + my $lupstream_revision = $2; + if ($lupstream_revision eq $upstream_revision) { + print "swim: $_ with different debian-revision exists\n"; + $_ = ""; + + ########## + # SOURCE # + ########## + if ($commands->{"source"} || $commands->{"source_only"}) { + my (@SOURCE,$upstream_change); + my ($matcher,$local_source,$remote_source,$base) = + source_calc($base,$uptopackage,$packagename,$drd,$source_drd); + my $REVISIONCHANGE = $ftp->ls("$base/$remote_source"); + my $singfile; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + if (!defined @SOURCE) { + print "swim: checking for upstream-revsion change\n"; + ($matcher) = (split(/_/,$matcher))[0]; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + $upstream_change = "yes" if defined @SOURCE; + } + foreach (@SOURCE) { + m,.*/(.*)$,; $packagename = $1; + $lmtime = (stat("$local_source/$packagename"))[9]; + -e "$local_source/$packagename" + ? ($lmtime = (stat("$local_source/$packagename"))[9]) + : ($lmtime = -1); + $size = $ftp->size("$_"); + $rmtime = $ftp->mdtm("$_"); + $file_exist = $ftp->code(); + if ($lmtime != $rmtime) { + if (!$commands->{"diff"}) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && + $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + else { + if (m,diff\.gz,) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && + $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + } + utime(time,$rmtime,"$local_source/$packagename"); + $_ = ""; + } + else { + print "swim: $packagename already exists\n" + } + } + } # source + next LOCUS; + } + elsif ($lupstream_revision ne $upstream_revision) { + if (!$commands->{"source_only"}) { + print "swim: replacing $_ with a different upstream-revision\n"; + unlink + ("$default_directory/$default_root_directory/$uptopackage/$_"); + } + print "swim: $_ exists with a different upstream-revision\n"; + } + } + closedir(DF); + } + + ################## + # EXISTS LOCALLY # + ################## + # got here but localtime was greater. + if (defined $rmtime && defined $lmtime) { + # ofcourse if the file does exist locally and has the same name + # and version, and this exists, something strange is going on. + if ($lmtime < $rmtime) { + print "swim: downloading $packagen, strange......... +same upstream version exists in the same package locally\n"; + get($ftp,"$base/$file",$localfile); + my $complete = $ftp->code(); + $argument = $localfile; + $commands{"md5sum"} = 1; + md5sumo(\%commands) if $complete == 226; + ($packagen = $packagename) =~ s,\\\+,\+,g; + print "swim: successful retrieval of $packagen\n" + if $complete == 226; + $_ = "" if $complete == 226; + utime(time,$rmtime,$localfile); + } + elsif ($lmtime == $rmtime) { + $_ = ""; + ($packagen = $packagename) =~ s,\\\+,\+,g; + print "swim: $packagen already exists\n"; + ########## + # SOURCE # + ########## + if ($commands->{"source"} || $commands->{"source_only"}) { + my (@SOURCE,$upstream_change); + my ($matcher,$local_source,$remote_source,$base) = + source_calc($base,$uptopackage,$packagename,$drd,$source_drd); + my $REVISIONCHANGE = $ftp->ls("$base/$remote_source"); + my $singfile; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + if (!defined @SOURCE) { + print "swim: checking for upstream-revsion change\n"; + ($matcher) = (split(/_/,$matcher))[0]; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + $upstream_change = "yes" if defined @SOURCE; + } + foreach (@SOURCE) { + m,.*/(.*)$,; $packagename = $1; + -e "$local_source/$packagename" + ? ($lmtime = (stat("$local_source/$packagename"))[9]) + : ($lmtime = -1); + $size = $ftp->size("$_"); + $rmtime = $ftp->mdtm("$_"); + $file_exist = $ftp->code(); + if ($lmtime != $rmtime) { + if (!$commands->{"diff"}) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + else { + if (m,diff\.gz,) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + } + utime(time,$rmtime,"$local_source/$packagename"); + $_ = ""; + } + else { + print "swim: $packagename already exists\n" + } + } + } # source + } + } + ######################################################### + # DOESN'T EXIST LOCALLY OR DIFFERENT UPSTREAM-REVISION # + ######################################################### + else { + ######################## + # BINARY AND/OR SOURCE # + ######################## + if (!$commands->{"source_only"}) { + print "swim: downloading $packagen ($size bytes)\n"; + my $upstream_change; + get($ftp,"$base/$file",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226) { + $argument = $localfile; + $commands{"md5sum"} = 1; md5sumo(\%commands); + ($packagen = $packagename) =~ s,\\\+,\+,g; + print "swim: successful retrieval of $packagen\n"; + rename("$localfile","$home") + or system "$mv", "$localfile", "$home"; + utime(time,$rmtime,"$home"); + } + else { + print "swim: unsuccessful retrieval of $file\n"; + } + $_ = ""; + ########## + # SOURCE # + ########## + if ($commands->{"source"}) { + my (@SOURCE,$upstream_change); + my ($matcher,$local_source,$remote_source,$base) = + source_calc($base,$uptopackage,$packagename,$drd,$source_drd); + my $REVISIONCHANGE = $ftp->ls("$base/$remote_source"); + my $singfile; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + if (!defined @SOURCE) { + print "swim: checking for upstream-revsion change\n"; + ($matcher) = (split(/_/,$matcher))[0]; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + $upstream_change = "yes" if defined @SOURCE; + } + foreach (@SOURCE) { + m,.*/(.*)$,; $packagename = $1; + -e "$local_source/$packagename" + ? ($lmtime = (stat("$local_source/$packagename"))[9]) + : ($lmtime = -1); + $size = $ftp->size("$_"); + $rmtime = $ftp->mdtm("$_"); + $file_exist = $ftp->code(); + if ($lmtime != $rmtime) { + if (!$commands->{"diff"}) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + else { + if (m,diff\.gz,) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + } + utime(time,$rmtime,"$local_source/$packagename"); + $_ = ""; + } + else { + print "swim: $packagename already exists\n" + } + } + } # source + } + ############### + # SOURCE-ONLY # + ############### + else { + my (@SOURCE,$upstream_change); + my ($matcher,$local_source,$remote_source,$base) = + source_calc($base,$uptopackage,$packagename,$drd,$source_drd); + my $REVISIONCHANGE = $ftp->ls("$base/$remote_source"); + my $singfile; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + if (!defined @SOURCE) { + print "swim: checking for upstream-revsion change\n"; + ($matcher) = (split(/_/,$matcher))[0]; + foreach (@{$REVISIONCHANGE}) { + m,^.*/($matcher.*)$, + ? ($singfile = $1) + : ($singfile = $_); + if ($singfile =~ /^$matcher/) { + $file = $singfile; + push(@SOURCE,"$base/$remote_source/$singfile"); + } + } + $upstream_change = "yes" if defined @SOURCE; + } + foreach (@SOURCE) { + m,.*/(.*)$,; $packagename = $1; + -e "$local_source/$packagename" + ? ($lmtime = (stat("$local_source/$packagename"))[9]) + : ($lmtime = -1); + $size = $ftp->size("$_"); + $rmtime = $ftp->mdtm("$_"); + $file_exist = $ftp->code(); + if ($lmtime != $rmtime) { + if (!$commands->{"diff"}) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + else { + if (m,diff\.gz,) { + $localfile = "$default_directory/partial/$packagename"; + !defined $upstream_change + ? print "swim: downloading $packagename ($size bytes)\n" + : print "swim: downloading upstream-revision $packagename ($size bytes)\n"; + get($ftp,"$_",$localfile); + my $complete = $ftp->code(); + $lsize = (stat($localfile))[7]; + if ($lsize == $size && $complete == 226 && $lmtime != $rmtime) { + print "swim: successful retrieval of $packagename\n"; + rename("$localfile","$local_source/$packagename") + or system "$mv","$localfile","$local_source/$packagename"; + } + else { + print "swim: unsuccessful retrieval of $packagename\n"; + } + } + } + utime(time,$rmtime,"$local_source/$packagename"); + $_ = ""; + } + else { + print "swim: $packagename already exists\n" + } + } + } # source-only + } + } + $base_count++; + } # foreach FTP + undef @LOCATION; + @LOCATION = @tryme_again; + $ftp->quit() if !defined @LOCATION; + my $good_bye = $ftp->code(); + print "swim: logged out\n" if $good_bye == 221; + undef @sites if !defined @LOCATION; + + } # foreach sites + untie %db; + +} # end sub qftp + + +# figure out the source stuff, make appropriate directories for sections +# which aren't non-US +sub source_calc { + + my($base,$uptopackage,$packagename,$drd,$source_drd) = @_; + + + # if source is empty in %db we can use the package name, need + # to watch for experimental + my ($remote_source,$local_source,@SOURCE); + # NON-US + if ($uptopackage =~ /non-US/) { + $local_source = + "$default_directory$drd/debian-non-US/$source_drd/source"; + $uptopackage =~ m,(.*)/.*$,; $remote_source = $1; + $remote_source = "$remote_source/source"; + # for safety's sake and because most sites don't have + # /pub/debian/dists/unstable/non-US/source except for a + # site made with swim, convert debian to debian-non-US and + # hope everything is standard. + if ($base !~ /debian-non-US/) { + $base =~ s/debian/debian-non-US/; + } + } + # EVERYTHING ELSE + else { + $uptopackage =~ m,(.*)/(.*)$,; + my $subject = $2; $1 =~ m,(.*)/.*$,; $local_source = $1; + #$remote_source =~ m,(.*)/.*$,; $remote_source = $1; + $remote_source = $local_source; + $local_source = "$remote_source/source/$subject"; + $remote_source = $local_source; + $local_source = + "$default_directory$default_root_directory/$local_source"; + } + + # exciting matcher realities..if it isn't non-US than the + # %db needs to be searched for anything found in Source:, + # if it is defined, then vola, herein this section lays the + # source, otherwise it's probably in the section which pertains + # to the package being queried..we hope. Epochs aren't used + # fortunately they aren't in package_versionFN, but they can + # be in the Source: area so they need to be removed. + $packagename =~ m,(^[A-Za-z\d\+-\\+]*_[\\+A-Za-z\d\+\.:]*) + [-]?[\dA-Za-z\.\+]*\.deb$,x; + + # everything, but revision + my $matcher = $1; + $matcher =~ m,^(.*)_(.*)$,; my $mat = $1; + if (defined $db{$mat}) { + $mat = $db{$mat}; $mat = $db{$mat}; + if ($mat =~ m,Installed-Size:\s\d+\s+Source:\s(.*),){ + $matcher = $1; + ########################################## + # DIFFERENT VERSION AND DIFFERENT SOURCE # + ########################################## + if ($matcher =~ m,[\(\)], ) { + $matcher =~ /:/ + ? $matcher =~ m,^(.*) + \s\([\d]?[:]? + ([A-Za-z0-9\+\.]+) + [-]?[\dA-Za-z\+\.]*\)$,x + : $matcher =~ m,^(.*) + \s\( + ([A-Za-z0-9\+\.]+) + [-]?[\dA-Za-z\+\.]*\)$,x; + + my $mat2 = $1; my $mat2_ver = $2; + $matcher = $mat2 . "_" . $mat2_ver; + if (defined $db{$mat2}) { + $matcher = $mat2 . "_" . $mat2_ver; + # time to change the $remote_source and $local_source + if ($uptopackage !~ /non-US/) { + my $change = $db{$mat2}; + $change = $db{$change ."FN"}; + $change =~ m,(.*)/(.*)$,; + $uptopackage = $1; $uptopackage =~ m,(.*)/(.*)$,; + my $subject = $2; + $1 =~ m,(.*)/.*$,; $local_source = $1; + $local_source = "$local_source/source/$subject"; + $remote_source = $local_source; + $local_source = + "$default_directory$default_root_directory/$local_source"; + } + } + } + ##################################### + # SAME VERSION AND DIFFERENT SOURCE # + ##################################### + else { + if (defined $db{$matcher}) { + # time to change the + # $remote_source and $local_source + if ($uptopackage !~ /non-US/) { + my $change = $db{$matcher}; + $change = $db{$change ."FN"}; + $change =~ m,(.*)/(.*)$,; + $uptopackage = $1; $uptopackage =~ m,(.*)/(.*)$,; + my $subject = $2; + $1 =~ m,(.*)/.*$,; $local_source = $1; + $local_source = "$local_source/source/$subject"; + $remote_source = $local_source; + $local_source = + "$default_directory$default_root_directory/$local_source"; + } + } + } + } # Source: found + } # should be defined + + + # time to make direcorties if $local_source isn't defined + # non-US already made, if source if already made, just the + # subject above needs to be made + if (!-e $local_source) { + my $place; + my @LS = split(m,/,,$local_source); + for (1 .. $#LS - 2) { + $_ == 1 ? ($place = "/$LS[$_]") + : ($place = $place . "/" . $LS[$_]); + } + my $create = "$LS[$#LS -1]/$LS[$#LS]"; + if (-d "$place/$LS[$#LS - 1]") { + mkdir("$place/$create",$permission) + or warn "swim: could not create source directory\n"; + } + else { + my @DP = split(m,/,,$create); + my $placement = "/"; + for (0 .. $#DP) { + $_ == 0 ? ($placement = "/$DP[$_]") + : ($placement = $placement . "/" . $DP[$_]); + mkdir("$place$placement",$permission) + or warn "swim: could not create source directory\n"; + } + } + } + + return($matcher,$local_source,$remote_source,$base); + +} # end source_calc + + + + +1; diff --git a/lib/Ramdisk.pm b/lib/Ramdisk.pm new file mode 100644 index 0000000..f174b3b --- /dev/null +++ b/lib/Ramdisk.pm @@ -0,0 +1,180 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Ramdisk; +use strict; +use SWIM::Conf; +use SWIM::Library; +use vars qw(@ISA @EXPORT); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(ramdisk); + + +=pod + +make access a lot faster for contentsindex.deb.gz, alternatively +searchindex.deb & file/dirindex. Ramdisks don't work well for +everything like the creation of a database. The goal is to +automatically determine the size of the disk based on the files +put into it (which will all be compressed) This also has a residual +effect, so when the ramdisk is umounted stuff still stays in +the memory. + +=cut + +sub ramdisk { + + + my ($commands) = @_; + + # lot's of thing can be put into the ramdisk, ncontentsindex being the + # most important, but flat search files, too. --ramdiskon -n would be + # the most important application. + my $size = 0; + my (@storage,@files); + my $count = 0; + my %commands = %$commands; + my $where = finddb(\%commands); + my ($arch,$dist) = which_archdist(\%commands); + my $not = "n" if defined $arch; + $not = "" if !$commands->{"n"}; + $arch = "" if !$commands->{"n"}; + $dist = "" if !$commands->{"n"}; + my $contentsindex = "contentsindex"; + my $searchindex = "searchindex"; + my $dirindex = "dirindex"; + + if ($commands->{"ramdiskon"}) { + + my $rambo = "$cat /proc/mounts|"; + open(RAM, "$rambo"); + while () { + if (/ram/) { + my($device,$mount) = split(/\s/,$_,2); + if ($mount =~ /dramdisk/) { + print "swim: use --ramdiskoff\n"; + exit; + } + $storage[$count] = $device; + $count++; + } + } + close(RAM); + + if (-e "$where/$not$contentsindex$arch$dist.deb.gz" && + -B "$where/$not$contentsindex$arch$dist.deb.gz") { + $size = (stat("$where/$not$contentsindex$arch$dist.deb.gz"))[7]; + push(@files,"$where/$not$contentsindex$arch$dist.deb.gz"); + } + + if ($commands->{"searchfile"}) { + # stat caused some weirdisms based on the boolean logic + #if (-e "$where/$not$searchindex$arch$dist.deb" && + # -e "$where/$not$dirindex$arch$dist.deb") { + # compress the monsters + if (!-e "$where/$not$dirindex$arch$dist.deb.gz") { + print "swim: please wait while dirindex.deb is compressed\n"; + if (-e "$where/$not$dirindex$arch$dist.deb") { + system "$gzip -c9 $where/$not$dirindex$arch$dist.deb > $where/$not$dirindex$arch$dist.deb.gz"; + } + } + if (!-e "$where/$not$searchindex$arch$dist.deb.gz") { + print "swim: please wait while searchindex.deb is compressed\n"; + if (-e "$where/$not$searchindex$arch$dist.deb") { + system "$gzip -c9 $where/$not$searchindex$arch$dist.deb > $where/$not$searchindex$arch$dist.deb.gz"; + } + } + push(@files,"$where/$not$dirindex$arch$dist.deb.gz"); + push(@files,"$where/$not$searchindex$arch$dist.deb.gz"); + my $size1 = (stat("$where/$not$searchindex$arch$dist.deb.gz"))[7]; + my $size2 = (stat("$where/$not$dirindex$arch$dist.deb.gz"))[7]; + if (defined $size) { + $size = $size + $size1 + $size2; + } + else { + $size = $size1 + $size2; + } + #} + } + + # it will be assumed that ext2 is used, and hopefully there isn't a mount + # of the exact same name..hence dramdisk should be unusual + my $number; + if (defined @storage) { + @storage = sort {$a cmp $b} @storage; + $storage[$#storage] =~ s/\D//g; + $number = $storage[$#storage] + 1; + } + else { + $number = 0; + } + + # the size will be the sizes added together/1024 + (.15 of the total) + if (-e "$where/dramdisk") { + if (!-d "$where/dramdisk") { + print "swim: --ramdiskon requires dir dramdisk, but a file named dramdisk already exists\n"; + exit; + } + } + elsif (!-d "$where/dramdisk") { + mkdir("$where/dramdisk",0666); + } + + my $increase = $size * 0.15; + $size = $increase + $size; + $size = $size/1024; + $size = sprintf("%.f",$size); + if ($size > 0) { + system "$mke2fs", "-m0", "/dev/ram$number", "$size"; + system "$mount", "-t", "ext2", "/dev/ram$number", "$where/dramdisk"; + foreach (@files) { + system "$copy", "$_", "$where/dramdisk"; + } + } + } # if on + else { + + my $rambo = "$cat /proc/mounts|"; + open(RAM, "$rambo"); + while () { + if (/ram/) { + my($device,$mount) = split(/\s/,$_,2); + if ($mount =~ /dramdisk/) { + system "$umount", "$device"; + exit; + } + $storage[$count] = $device; + $count++; + } + } + close(RAM); + + + } # if off + + exit; + +} # end sub ramdisk + + + + + +1; diff --git a/lib/Safex.pm b/lib/Safex.pm new file mode 100644 index 0000000..e0d3ace --- /dev/null +++ b/lib/Safex.pm @@ -0,0 +1,470 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Safex; +use strict; +use Term::ReadLine; +use SWIM::Conf qw($apt_get $dpkg $tmp $HISTORY); +use SWIM::Global qw(@PACKAGES $argument $aptor_group %db); +use SWIM::DB_Library qw(:Xyz); +use SWIM::Library; +use vars qw(@ISA @EXPORT %EXPORT_TAGS); +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(safex); + + +# when x is called +sub safex { + + my ($commands) = @_; + my %commands = %$commands; + + if ($commands->{"x"} || $commands->{"ftp"} || $commands->{"source"} || + $commands->{"source_only"} || $commands->{"remove"} || $commands->{"r"} || + $commands->{"purge"}) { + + + if (!defined @PACKAGES) { + if ($commands->{"search"} || $commands->{"ps"} || $commands->{"research"} + || $commands->{"refinesearch"}) { + @PACKAGES = "NOPACKAGES"; + } + else { + @PACKAGES = @ARGV; + } + } + + #print "PACKAGES @PACKAGES $argument\n"; + + my ($aptor,$arg); + if (defined $argument) { + if ($argument =~ /_/) { + $argument =~ m,(.*)_.*,; + $aptor = $1; + } + else { + if (($argument =~ m,/, && ($commands->{"y"} || $commands->{"z"} || + $commands->{"ftp"} || $commands->{"nz"})) || defined $aptor_group || + $commands->{"ftp"} || $commands->{"purge"} || $commands->{"remove"} || + $commands->{"r"}) { + if ($PACKAGES[$#PACKAGES] =~ /_/) { + $PACKAGES[$#PACKAGES] =~ m,(.*)_.*,; + $aptor = $1; + } + else { + $aptor = $PACKAGES[$#PACKAGES]; + } + } + else { + $aptor = $argument; + } + } + } + else { + if ($commands->{"y"} || $commands->{"z"} || $commands->{"ftp"} || + $commands->{"nz"} || $commands->{"purge"} || $commands->{"remove"} || + $commands->{"r"}) { + if ($PACKAGES[$#PACKAGES] =~ /_/) { + $PACKAGES[$#PACKAGES] =~ m,(.*)_.*,; + $aptor = $1; + } + else { + $aptor = $PACKAGES[$#PACKAGES]; + } + } + } + + if ($PACKAGES[$#PACKAGES] =~ m,/,) { + $PACKAGES[$#PACKAGES] =~ m,.*/(.*)$,; + $arg = $1; + foreach (@PACKAGES) { + $_ =~ m,.*/(.*)$,; + shift @PACKAGES; + push(@PACKAGES,$1); + } + } + else { + if ($PACKAGES[$#PACKAGES] =~ /_/) { + $PACKAGES[$#PACKAGES] =~ m,(.*)_.*,; + $arg = $1; + foreach (0 .. $#PACKAGES) { + if ($PACKAGES[$_] =~ /_/) { + $PACKAGES[$_] =~ m,^(.*)_.*$,; + $PACKAGES[$_] = $1; + } + else { + $PACKAGES[$_] = $PACKAGES[$_]; + } + } + } + else { + $arg = $PACKAGES[$#PACKAGES]; + foreach (0 .. $#PACKAGES) { + if ($PACKAGES[$_] =~ /_/) { + $PACKAGES[$_] =~ m,^(.*)_.*$,; + $PACKAGES[$_] = $1; + } + else { + $PACKAGES[$_] = $PACKAGES[$_]; + } + } + } + } + + $aptor = "DEFINEDONE" if !defined $aptor; + if (($aptor eq $arg) || ($commands->{"search"} || + $commands->{"ps"} || $commands->{"research"} || + $commands->{"refinesearch"} || $aptor eq "/.") && + $PACKAGES[0] ne "NOPACKAGES") { + xyz(\%commands); + } + } + + +} + + +# swim provides a great interface to apt. The trick is to not actually +# run apt-get until all the arguments are stored in an array. This is +# done easily for xy and for for xyz which provides virtual installation +# and querying completion after --db && --ndb updates. Obviously, the +# package virtually installed needs to be the same architecture as the +# machine running, since this is how apt works, but the databases can be +# in any specified directory. This function also provides an interface for +# ftp, as well as dpkg's --remove & --purge. +sub xyz { + + my ($commands) = @_; + my %commands = %$commands; + + if (!$commands->{"ftp"}) { + if (!defined $apt_get) { + print "swim: configure swimrc\n"; + exit; + } + } + + # error correcting + if ($commands->{"ftp"} && ($commands->{"r"} || $commands->{"remove"} || + $commands->{"purge"})) { + print "swim: --ftp cannot be used with "; + print "-r " if defined $commands->{"r"}; + print "--remove " if defined $commands->{"remove"}; + print "--purge " if defined $commands->{"purge"}; + print "\n"; + exit; + } + if (($commands->{"r"} || $commands->{"remove"}) && $commands->{"purge"}) { + print "swim: "; + print "-r " if defined $commands->{"r"}; + print "--remove " if defined $commands->{"remove"}; + print "--purge " if defined $commands->{"purge"}; + print "cannot be used together\n"; + exit; + } + if (($commands->{"y"} || $commands->{"z"} || $commands->{"x"} || + $commands->{"nz"}) && ($commands->{"ftp"} || $commands->{"purge"})) { + print "swim: -"; + print "x" if $commands->{"x"}; + print "y" if $commands->{"y"}; + print "z" if $commands->{"z"}; + print " --nz" if $commands->{"nz"}; + print " cannot be used with "; + print "--purge " if defined $commands->{"purge"}; + print "--ftp " if defined $commands->{"ftp"}; + print "\n"; + exit; + } + if (($commands->{"source"} && $commands->{"source_only"})) { + print "swim: --source and --source_only cannot be used together\n"; + exit; + } + if (($commands->{"source"} || $commands->{"source_only"}) && + !$commands->{"ftp"}) { + print "swim: --"; + print "source" if $commands->{"source"}; + print "source_only" if $commands->{"source_only"}; + print " cannot be used without --ftp\n"; + exit; + } + if (($commands->{"y"} || $commands->{"z"} || $commands->{"nz"}) && + !$commands->{"x"}) { + print "swim: requires -x option\n"; + exit; + } + + if ($commands->{"x"}) { + # There's no sense in doing this if the wrong architecture is called. + if (defined $dpkg) { + system "$dpkg --print-installation-architecture > $tmp/arch.deb"; + open(ARCH, "$tmp/arch.deb") or warn "couldn't find arch\n"; + my @arch = ; chomp $arch[0]; + my($arch,$dist) = which_archdist(\%commands); $arch =~ m,^-(.*),; + if ($1 ne $arch[0]) { + print "swim: apt uses the $arch[0] architecture\n"; + exit; + } + } + } + + + ############### + # SAFETY MODE # + ############### + if ((($commands->{"x"} || ($commands->{"x"} && $commands->{"y"})) || + ($commands->{"x"} && ($commands->{"r"} || $commands->{"remove"}) || + ($commands->{"x"} && $commands->{"y"} && ($commands->{"r"} || + $commands->{"remove"})))) && + !($commands->{"z"} || $commands->{"nz"})) { + my $arg; + my $count = 0; + foreach (@PACKAGES) { + if ($count == 0) { + $arg = "$_"; + } + else { + $arg = $arg . " " . "$_"; + } + $count++; + } + ######### + # STDIN # + ######### + if ($commands->{"stdin"}) { + my $term = Term::ReadLine->new("Simple Shell"); + my @HISTORY = history(\%commands); + $term->addhistory(@HISTORY); + my @history; push(@history,"$arg"); + print "swim: type exit to finish --stdin\n"; + my $termcount = 0; + while ($termcount < 1 ) { + $_ = $term->readline('swim: ',"$arg"); + push (@history,$_); + $termcount++; + } do { $_ = $term->readline('swim: '); + push (@history,$_); + } while $_ ne "exit"; + $arg = $history[$#history - 1]; + if ($arg ne $HISTORY[$#HISTORY]) { + if ($arg =~ m,^[^\w],) { + $arg =~ s,^\s+(\w+),$1,; + } + history_print($arg,\%commands); + } + } + !($commands->{"r"} || $commands{"remove"}) ? + system "$apt_get install -qs $arg" : + system "$apt_get remove -qs $arg"; + } + ##################### + # INSTALLATION MODE # + ##################### + # provides optional --stdin to change packages to be installed + # from the command line + else { + my $arg; + my $count = 0; + foreach (@PACKAGES) { + if ($count == 0) { + $arg = "$_"; + } + else { + $arg = $arg . " " . "$_"; + } + $count++; + } + ######### + # STDIN # + ######### + if ($commands->{"stdin"}) { + my $term = Term::ReadLine->new("Simple Shell"); + my @HISTORY = history(\%commands); + $term->addhistory(@HISTORY); + my @history; push(@history,"$arg"); + print "swim: type exit to finish --stdin\n"; + my $termcount = 0; + while ($termcount < 1 ) { + $_ = $term->readline('swim: ',"$arg"); + push (@history,$_); + $termcount++; + } do { $_ = $term->readline('swim: '); + push (@history,$_); + } while $_ ne "exit"; + $arg = $history[$#history - 1]; + if ("$arg" ne "$HISTORY[$#HISTORY]") { + if ($arg =~ m,^[^\w],) { + $arg =~ s,^\s+(\w+),$1,; + } + history_print($arg,\%commands); + } + } + ####### + # XYZ # + ####### + if (!($commands->{"ftp"} || $commands->{"purge"})) { + if (!$commands->{"y"}) { + if (!$commands->{"nz"}) { + !($commands->{"r"} || $commands{"remove"}) ? + system "$apt_get install $arg" : + system "$apt_get remove $arg"; + } + else { + !($commands->{"r"} || $commands{"remove"}) ? + system "$apt_get -d install $arg" : + system "$apt_get remove $arg"; + } + } + else { + if (!$commands->{"nz"}) { + !($commands->{"r"} || $commands{"remove"}) ? + system "$apt_get install -y $arg" : + system "$apt_get remove -y $arg"; + } + else { + # not that the y does anything + !($commands->{"r"} || $commands{"remove"}) ? + system "$apt_get install -y -d $arg" : + system "$apt_get remove -y $arg"; + } + } + } + ####### + # FTP # + ####### + elsif ($commands->{"ftp"}) { + require SWIM::Qftp; + SWIM::Qftp->import(qw(qftp)); + qftp($arg,\%commands); + } + + ################## + # PURGE & REMOVE # + ################## + elsif ($commands->{"purge"} || $commands->{"remove"} || $commands->{"r"}) { + purge($arg,\%commands); + } + + # this is a good time to return the versions, too, as well as + # including any NEW packages from --db and --ndb. We'll assume $arg + # from qftp will never be too large + if (!$commands->{"n"}) { + dbi(\%commands); + @PACKAGES = map($db{$_},(@PACKAGES = split(/\s/,$arg))); + } + else { + ndb(\%commands); + @PACKAGES = map($db{$_},(@PACKAGES = split(/\s/,$arg))); + } + untie %db; + } + +} # end sub xyz + + +# Remove (keep configuration files) or purge everything for each package. +sub purge { + + my ($arg,$commands) = @_; + + if (!$commands->{"n"}) { + if ($commands->{"purge"}) { + system "$dpkg --purge $arg"; + + } + elsif ($commands->{"remove"} || $commands->{"r"}) { + system "$dpkg -r $arg"; + } + } + else { + print "swim: "; + print "-r " if defined $commands->{"r"}; + print "--remove " if defined $commands->{"remove"}; + print "--purge " if defined $commands->{"purge"}; + print "can only be used with installed packages\n"; + } + + +} # end sub purge + + +# find the history file and return proper output +sub history { + + my($commands) = @_; + my %commands = %$commands; + + my($arch,$dist) = which_archdist(\%commands); + my($place) = finddb(\%commands); + my $swim_history; + if ($commands->{"n"}) { + $swim_history = "$place/.nswim$arch$dist" . "_history"; + } + else { + $swim_history = "$place/.swim" . "_history"; + } + open(HISTORY,"$swim_history") or exit; + my (@HISTORY,$line); + while () { + chomp; + foreach (split(/\s/,$_)) { + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + } + push(@HISTORY,$line); undef $line; + } + + return @HISTORY; + +} # end sub history + +# append history if it has changed +sub history_print { + + my($arg,$commands) = @_; + my %commands = %$commands; + my($arch,$dist) = which_archdist(\%commands); + my($place) = finddb(\%commands); + my $swim_history; + if ($commands->{"n"}) { + $swim_history = "$place/.nswim$arch$dist" . "_history"; + } + else { + $swim_history = "$place/.swim" . "_history"; + } + open(HISTORY,"$swim_history") or exit; + my @HISTORY = ; + close(HISTORY); + if ($#HISTORY < $HISTORY - 1) { + push(@HISTORY,"$arg\n"); + } + else { + shift(@HISTORY); + push(@HISTORY,"$arg\n"); + } + open(HISTORY,">$swim_history") or exit; + print HISTORY @HISTORY; + + +} # end sub history_print + +1; diff --git a/lib/Search.pm b/lib/Search.pm new file mode 100644 index 0000000..aa34ac9 --- /dev/null +++ b/lib/Search.pm @@ -0,0 +1,850 @@ +# Package administration and research tool for Debian +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum + +# 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. + + +package SWIM::Search; +use vars qw(@ISA @EXPORT); +use strict; +use SWIM::Global; +use SWIM::Conf; +use SWIM::DB_Library qw(:Search); +use SWIM::Library; +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(search); + + +# search() and searchdf() = mm --search, --ps --refinesearch --research + +=pod + +This searches for keyword(s) amongst the descriptions, and then +shows the packages which match, a little more sophisticated than +swim -qait | grep , besides you can use perl regexping +notation when you do your search. By default the description is +automatically presented, but a list of package names which match is kept +which can then be queried using -S in the normal fashion, until the +next search. + +=cut + +sub search { + + my ($search_mem,$commands,$num,$argv) = @_; + + $argument = "/."; + my %commands = %$commands; + + my %morethanone; + my $keyword = $commands->{"search"}; + if ($commands->{"search"}) { + $keyword = $commands->{"search"}; + } + elsif ($commands->{"research"}) { + $keyword = $commands->{"research"}; + } + elsif ($commands->{"refinesearch"}) { + $keyword = $commands->{"refinesearch"}; + } + elsif ($commands->{"powersearch"} || $commands->{"ps"}) { + if ($commands->{"powersearch"}) { + $keyword = $commands->{"powersearch"}; + } + if ($commands->{"ps"}) { + $keyword = $commands->{"ps"}; + } + } + my $count = 0; + + my ($search_file, $search_dir); + if (!$commands->{"n"}) { + ib(\%commands); + dbi(\%commands); + if ($commands->{"ps"} || $commands->{"powersearch"}) { + ($search_file,$search_dir) = searchdf(\%commands); + if (-B $search_file && -B $search_dir) { + $search_file = "$gzip -dc $search_file|"; + $search_dir = "$gzip -dc $search_dir|"; + } + } + } + ##### + # N # + ##### + else { + my $return = nib(\%commands); + if (!defined $return) { + untie %ib; + nsb(\%commands); + $ib{"/."} = $nsb{"/."}; + } + ndb(\%commands); + if ($commands->{"ps"} || $commands->{"powersearch"}) { + ($search_file,$search_dir) = searchdf(\%commands); + if (!-e $search_file || !-e $search_dir) { + delete $commands{"ps"} if defined $commands->{"ps"}; + delete $commands{"powersearch"} if defined $commands->{"powersearch"}; + } + if (-B $search_file && -B $search_dir) { + $search_file = "$gzip -dc $search_file|"; + $search_dir = "$gzip -dc $search_dir|"; + } + } + } + + ########## + # # + # SEARCH # + # # + ########## + # Here starts --search & optionally -g + my ($line,@HISTORY); + if ($commands->{"search"}) { + my @stuff; + if ($commands->{"g"}) { + # check for some errors + if ($commands->{"a"} || $commands->{"f"} || $commands->{"dir"}) { + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + # extract the packages related to the group. + if (!$commands->{"n"}) { + gb(\%commands); + } + else { + ngb(\%commands) + } + if ($#ARGV != -1) { + foreach (@ARGV) { + $argument = $_; + if (defined $gb{$argument}) { + @stuff = split(/\s/, $gb{$argument}); + } + else { + print "group $argument does not contain any packages\n"; + } + } + } + else { + print "swim: no arguments given for query\n"; + } + untie %gb; + } # if ($commands->{"g"}) + + # not yet for -g + if ($commands->{"search"} && !$commands->{"g"}) { + if (defined $argument) { + if ($ib{"$argument"}){ + foreach (split(/\s/, $ib{"$argument"})) { + if ($keyword =~ /\/i$/) { + $keyword =~ m,(.*)\/i$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/i) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/m$/) { + $keyword =~ m,(.*)\/m$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/m ) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $keyword =~ m,(.*)\/.[im]$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/im ) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + else { + if (defined $db{$_}) { + if ($db{$_} =~ /$keyword/) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + print "swim: found $count package(s)\n"; + #exit; + } + if (!defined $line) { + $line = ""; + } + else { + $line = "$line\n"; + } + history($line,$search_mem); + } + } + + # ok -g + elsif ($commands->{"search"} && $commands->{"g"}) { + if (defined @stuff) { + #unlink("$search_mem"); + foreach (@stuff) { + $argument = $_; + version(\%commands); + # if we just did a group search we don't want to append it to + # the .search.deb file. + if ($keyword =~ /\/i$/) { + $keyword =~ m,(.*)\/i$,; + if (defined $db{$_}) { + if ($db{$argument} =~ /$1/i) { + print "$db{$argument}\n" if !$commands->{"no"}; + push(@PACKAGES,$argument); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/m$/) { + $keyword =~ m,(.*)\/m$,; + if (defined $db{$_}) { + if ($db{$argument} =~ /$1/m ) { + print "$db{$argument}\n" if !$commands->{"no"}; + push(@PACKAGES,$argument); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $keyword =~ m,(.*)\/.[im]$,; + if (defined $db{$_}) { + if ($db{$argument} =~ /$1/im ) { + print "$db{$argument}\n" if !$commands->{"no"}; + push(@PACKAGES,$argument); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + else { + if (defined $db{$_}) { + if ($db{$argument} =~ /$keyword/) { + print "$db{$argument}\n" if !$commands->{"no"}; + push(@PACKAGES,$argument); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + print "swim: found $count package(s)\n"; + if (!defined $line) { + $line = ""; + } + else { + $line = "$line\n"; + } + history($line,$search_mem); + } + } + exit if !($commands->{"stdin"} || $commands->{"x"} || $commands->{"y"} || + $commands->{"z"} || $commands->{"ftp"}); + } + + ############################# + # # + # RESEARCH || REFINESEARCH # + # # + ############################# + # research time or refining time + if ($commands->{"research"} || $commands{"refinesearch"}) { + if ($commands->{"g"}) { + print "swim: use -g only with a new search\n"; + exit; + } + foreach (@$argv) { + if ($keyword =~ /\/i$/) { + $keyword =~ m,(.*)\/i$,; + if (defined $db{$_}) { + if ($db{$db{$_}} =~ /$1/i) { + print "$db{$db{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/m$/) { + $keyword =~ m,(.*)\/m$,; + if (defined $db{$_}) { + if ($db{$db{$_}} =~ /$1/m ) { + print "$db{$db{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $keyword =~ m,(.*)\/.[im]$,; + if (defined $db{$_}) { + if ($db{$db{$_}} =~ /$1/im ) { + print "$db{$db{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + else { + if (defined $db{$_}) { + if ($db{$db{$_}} =~ /$keyword/) { + print "$db{$db{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + print "swim: found $count package(s)\n"; + if (!defined $line) { + $line = ""; + } + else { + $line = "$line\n"; + } + # refine the search + if ($commands->{"refinesearch"}) { + open(HISTORY, "$search_mem") || exit; + my @HISTORY = reverse ; + close(HISTORY); + $HISTORY[$num - 1] = $line; + open(HISTORY, ">$search_mem") || exit; + print HISTORY reverse @HISTORY; + close(HISTORY); + } + exit if !($commands->{"stdin"} || $commands->{"x"} || + $commands->{"y"} || $commands->{"z"} || $commands->{"ftp"}); + } + + + ################ + # # + # POWERSEARCH # + # # + ################ + # powersearch with no -g option since this searchs all files. + if (($commands->{"powersearch"} || $commands->{"ps"}) && !$commands->{"g"}) { + open(FLATFILE, "$search_file"); + while () { + chomp $_; + if ($keyword =~ /\/i$/) { + $keyword =~ m,(.*)\/i$,; + if ($_ =~ /$1/i) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + print "$db{$ib{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$ib{$_}); + if (!defined $line) { + $line = (split(/_/,$ib{$_}))[0]; + } + else { + $line = $line . " " . (split(/_/,$ib{$_}))[0]; + } + $count++; + } + } + } + } + elsif ($keyword =~ /\/m$/) { + $keyword =~ m,(.*)\/m$,; + if ($_ =~ /$1/m ) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + print "$db{$ib{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$ib{$_}); + if (!defined $line) { + $line = (split(/_/,$ib{$_}))[0]; + } + else { + $line = $line . " " . (split(/_/,$ib{$_}))[0]; + } + $count++; + } + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $keyword =~ m,(.*)\/.[im]$,; + if ($_ =~ /$1/im ) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + print "$db{$ib{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$ib{$_}); + if (!defined $line) { + $line = (split(/_/,$ib{$_}))[0]; + } + else { + $line = $line . " " . (split(/_/,$ib{$_}))[0]; + } + $count++; + } + } + } + } + else { + if ($_ =~ /$keyword/) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + # ofcourse this won't work if a dir filters through. + # hummm. + #print "HUMM DIR $_ ", $ib{$_}, "\n"; + print "$db{$ib{$_}}\n" if !$commands->{"no"}; + push(@PACKAGES,$ib{$_}); + if (!defined $line) { + $line = (split(/_/,$ib{$_}))[0]; + } + else { + $line = $line . " " . (split(/_/,$ib{$_}))[0]; + } + $count++; + } + } + } + } + } # while () + close(FLATFILE); + + ####### + # DIR # + ####### + # Somebody wants to do a rare --dir search, but this is done by default + # for the n* because often enough more than one package shares one + # file. + if ($commands->{"dir"} || $commands{"n"}) { + open(FLATFILE, "$search_dir"); + while () { + chomp $_; + if ($keyword =~ /\/i$/) { + $keyword =~ m,(.*)\/i$,; + if ($_ =~ /$1/i) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + my @dir = split(/\s/,$ib{$_}); + foreach (@dir) { + $morethanone{$_}++; + if (defined $morethanone{$_}) { + if ($morethanone{$_} == 1) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + } + } + } + elsif ($keyword =~ /\/m$/) { + $keyword =~ m,(.*)\/m$,; + if ($_ =~ /$1/m ) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + my @dir = split(/\s/,$ib{$_}); + foreach (@dir) { + $morethanone{$_}++; + if (defined $morethanone{$_}) { + if ($morethanone{$_} == 1) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $keyword =~ m,(.*)\/.[im]$,; + if ($_ =~ /$1/im ) { + if (defined $ib{$_}) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + my @dir = split(/\s/,$ib{$_}); + foreach (@dir) { + $morethanone{$_}++; + if (defined $morethanone{$_}) { + if ($morethanone{$_} == 1) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + } + } + } + else { + if ($_ =~ /$keyword/) { + if (defined $ib{$_}) { + #my @dir = split(/\s/,$ib{$_}); + #foreach (@dir) { + $morethanone{$ib{$_}}++; + if ($morethanone{$ib{$_}} == 1) { + my @dir = split(/\s/,$ib{$_}); + foreach (@dir) { + $morethanone{$_}++; + if (defined $morethanone{$_}) { + if ($morethanone{$_} == 1) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + } + } + } + } # while () + close(FLATFILE); + } + + ################# + # NORMAL SEARCH # + ################# + # now we can do a normal search for the powersearch + if (defined $argument) { + if ($ib{"$argument"}){ + foreach (split(/\s/, $ib{$argument})) { + if ($keyword =~ /\/i$/) { + $morethanone{$_}++; + if ($morethanone{$_} == 1) { + $keyword =~ m,(.*)\/i$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/i) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + elsif ($keyword =~ /\/m$/) { + $morethanone{$_}++; + if ($morethanone{$_} == 1) { + $keyword =~ m,(.*)\/m$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/m ) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + elsif ($keyword =~ /\/.[im]$/) { + $morethanone{$_}++; + if ($morethanone{$_} == 1) { + $keyword =~ m,(.*)\/.[im]$,; + if (defined $db{$_}) { + if ($db{$_} =~ /$1/im ) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + else { + $morethanone{$_}++; + if ($morethanone{$_} == 1) { + if (defined $db{$_}) { + if ($db{$_} =~ /$keyword/) { + print "$db{$_}\n" if !$commands->{"no"}; + push(@PACKAGES,$_); + if (!defined $line) { + $line = (split(/_/,$_))[0]; + } + else { + $line = $line . " " . (split(/_/,$_))[0]; + } + $count++; + } + } + } + } + } + print "swim: found $count package(s)\n"; + if (!defined $line) { + $line = ""; + } + else { + $line = "$line\n"; + } + history($line,$search_mem); + #exit if !($commands->{"stdin"} || $commands->{"x"} || + # $commands->{"y"} || $commands->{"z"} || $commands->{"ftp"}); + } + } + } + + untie %ib; + untie %db; + + +} # end sub search + +# for finding the search flatfiles +sub searchdf { + + my ($commands) = @_; + + my($sfile,$sdir); + if (!$commands->{"n"}) { + my ($ramdisk) = ram_on(); + if ($ramdisk eq 1) { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sfile = "$parent$library/searchindex.deb"; + $sdir = "$parent$library/dirindex.deb"; + return ($sfile,$sdir); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sfile = "$parent$base/searchindex.deb"; + $sdir = "$parent$base/dirindex.deb"; + return ($sfile,$sdir); + } + } + elsif ($ramdisk eq "yes") { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sfile = "$parent$library/dramdisk/searchindex.deb.gz"; + $sdir = "$parent$library/dramdisk/dirindex.deb.gz"; + if (!-e $sdir && !-e $sfile) { + print "swim: found wrong database(s), use --ramdiskoff\n"; + exit; + } + return ($sfile,$sdir); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sfile = "$parent$base/dramdisk/searchindex.deb.gz"; + $sdir = "$parent$base/dramdisk/dirindex.deb.gz"; + if (!-e $sdir && !-e $sfile) { + print "swim: found wrong database(s), use --ramdiskoff\n"; + exit; + } + return ($sfile,$sdir); + } + } + } + else { + my ($ramdisk) = ram_on(); + my($arch,$dist) = which_archdist(\%commands); + if ($ramdisk eq 1) { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sfile = "$parent$library/nsearchindex$arch$dist.deb"; + $sdir = "$parent$library/ndirindex$arch$dist.deb"; + return ($sfile,$sdir); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sfile = "$parent$base/nsearchindex$arch$dist.deb"; + $sdir = "$parent$base/ndirindex$arch$dist.deb"; + return ($sfile,$sdir); + } + } + elsif ($ramdisk eq "yes") { + if (($commands->{"dbpath"} && $commands->{"root"}) || + ($commands->{"dbpath"} && !$commands->{"root"}) || + (!$commands->{"dbpath"} && !$commands->{"root"})) { + $sfile = "$parent$library/dramdisk/nsearchindex$arch$dist.deb.gz"; + $sdir = "$parent$library/dramdisk/ndirindex$arch$dist.deb.gz"; + if (!-e $sdir && !-e $sfile) { + print "swim: found wrong database(s), use --ramdiskoff\n"; + exit; + } + return ($sfile,$sdir); + } + elsif (!$commands->{"dbpath"} && $commands->{"root"}) { + $sfile = "$parent$base/dramdisk/nsearchindex$arch$dist.deb.gz"; + $sdir = "$parent$base/dramdisk/ndirindex$arch$dist.deb.gz"; + if (!-e $sdir && !-e $sfile) { + print "swim: found wrong database(s), use --ramdiskoff\n"; + exit; + } + return ($sfile,$sdir); + } + } + } + +} # end sub searchdf + +# print the search out to the right spot on the HISTORY +# this is just shift and push +sub history { + + my($line,$file) = @_; + my @HISTORY; + + if (-e "$file") { + open(HISTORY,"$file"); + @HISTORY = ; + close(HISTORY); + if ($#HISTORY < $HISTORY - 1) { + push(@HISTORY,$line); + } + else { + shift(@HISTORY); + push(@HISTORY,$line); + } + } + else { + @HISTORY = $line; + } + + open(HISTORY,">$file") or exit; + print HISTORY @HISTORY; + close(HISTORY); + +} # end sub history + + +1; diff --git a/swim b/swim new file mode 100755 index 0000000..b4c3151 --- /dev/null +++ b/swim @@ -0,0 +1,1991 @@ +#!/usr/bin/perl -w +#use diagnostics; +require 5.004; +use strict; +use Getopt::Long; +use SWIM::Conf; +use SWIM::Global; +use SWIM::Library; + + +################################################################################ +# Package administration and research tool for Debian # +# Copyright (C) 1999-2000 Jonathan D. Rosenbaum # +# # +# 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.# +################################################################################ + + +=pod + +Description: Show World Intelligent Management + Show World Packaging Method or .... + +Swim is a program which adds rpm-like quering capabilities to the Debian +system. Information for an installed Debian system is extracted from the +/var/lib/dpkg/info* files and the status file, information for an uninstalled +(not-installed) system is extracted from Packages and Contents files which can +be conveniently downloaded with a built-in ftp client. Although there are many +similarities which will feel comfortable to experienced rpm users, there are +also major differences between swim and rpm. Besides file queries, directory +queries will show all packages associated with the directories in relation to +the root directory. There is a simple and powerful search option to find +packages who's descriptions match the keyword, this can be combined with a very +fast search of all files and directories. If there are several packages to be +presented by a query, swim tells how many, and then the -t option can be used +to view the packages; the default output is easy to understand because packages +are labeled. Swim provides a perfect interface to apt-get. This interface is +perfected by the ability to manage many different types of databases: +databases for the real installed system, and databases for virtually (not real) +installed systems, the archictecture(s) and distribution(s) are your choice. +Virtual installation capabilities combined with searching, quering, and +readline editing provide an extrememly powerful upgrading experience. Swim +provides people the ability to make a customized distribution for +redistribution or for personal use. Non-Debian systems can use swim without +dpkg to compare Debian packages to non-Debian packages as well as downloading +source or even binaries for installation if everything checks out (a good way +to troubleshoot alien). Portablility shows the whole world an intelligent +package management system (with DOS in the picture). Troubleshooting is +greatly simplified for missing files, the integrated Debian menu system, and +many other things. You can double check the md5sums of both packages and +files; the statuses of both *deb packages, and not-installed packages are given +in relation to your installed system, and missing blanks are filled in. +Versatility..swim has a lot of this like it's DF (default directory) structure +which makes managing databases, packages, and even creating a customized +distribution a cinch. + + +Plan: + +Eventually add information about every executable and significant +program every source ball has, and provide sophisticated searching +capabilities. This information will come from the ThE_* Project +database, and will be able to be used by other packaging systems or +programs. Swim will have editing capabilities, and will be linked via +cgi to html files. And that's just the beginning, the possiblities +are enormous! Goal: Guru knowledge about an Open Source system for +anyone, find the program to do the job easily. + +=cut + + +# The MAIN +# First let's determine what options are being used. + +Getopt::Long::config("bundling","no_auto_abbrev"); # will use pass_through + +my($result) = + GetOptions (\%commands, + "query", "q", # query + "b", # build + "a", # all packages = /. + "f", # file query + "dir", # same as "f", but verifies dir + "i", # information + "l", # file listing + "df", # file/directory listing w/-l + "v", # verbose listing + "p", # package query + "extract=s", # extract all files/file from package + "remove", "r", # remove all, but conf. + "purge", # remove it all + "apt", # apt-get + "update", # using sources.list + "clean", # remove archives or apt2ftp + "autoclean", # remove some archives + "upgrade", # currently installed packages + "dist_upgrade", # whole dist. upgrade + "x", # simulate apt's actions + "y", # automatic yes for -z + "z", # apt install + "nz", # apt download + "source", # ftp source and package + "source_only", # ftp only source for package + "diff", # just grab diff for source + "stdin", # read in from stdin + "md5sum", # show md5sum + "c", # configuration files + "d", # show documentation + "g", # packages belonging to group (27) + "allgroups", # show all groups + "n", # not-installed + "pre_depends", # required before installation + "depends", # like requires, def. needed + "recommends", # packages important to this one + "suggests", # complimentary packages + "replaces", # package(s) being replaces + "provides", # capabilities provided (virtual) + "conflicts", # package(s) which conflict + "T", # all characteristics + "shlibs", # provided shared libraries + "total", "t", # when there is more than one + "no", # no output on searches + "scripts", # the scripts + "preinst", # before inst. script + "postinst", # after inst. script + "prerm", # before removal script + "postrm", # after removal script + "menu", "m", # menu script + "copyright", # copyright + "changelog", # changelog.Debian.gz changelog.gz + "root=s", # use alternative db & root dir + "db", # update the database + "initdb", # make the databases + "rebuilddb", # remake the database + "lowmem", # lowmem method + "initndb", # make not-installed database + "ndb", # update not-installed database + "report", # report for --ndb + "check", # show changes|update cache + "rebuildndb", # remake not-installed database + "cron", # intelligent cron + "Contents=s", # Contents file required + "onec", # download only 1 Contents + "nue", # non-US or Exp. in Contents + "main", # this section and/or + "contrib", # this section and/or + "non-free", # this section and/or + "non-us", # this section and/or + "arch=s", # architecture - i386 ... + "dists=s", # distribution - stable ... + "alt=s", # alternative base for dist + "dbpath=s", # override default db location + "split_data=s", # make things faster + "rebuildflatdb", # rebuild flat databases + "rebuildflatndb", # rebuild n-flat databases + "nopager", "n", # no pager + "search=s", # search database for package + "powersearch=s", # match files, directories, and + "ps=s", # packages. + "research=s", # search the results + "refinesearch=s", # refine the existing search + "searchfile", # search databases + "cs", # case sensitive search + "S", # query packages from search + "C", "audit", # dpkg standard options + "status", # clues one in about -C + "status_only", # n* update + "ramdiskon", # turn on the thing + "ramdiskoff", # turn it off + "ftp", # ftp client protocol + "apt2ftp", # mv archives to DF + "ftp2apt", # install DF with apt-get + "Packages=s", # Packages file + "Release_only", # grab Release files only + "version", # program version + "history", # swim history + "h", # "" + "testmenu", # tmp test for menuindex.deb + "help" # it better + + ); + + +command(); + + +# The module sub-monsters + +sub command { + + + # test + if ($commands{"testmenu"}) { + menuindex(); + } + + # Turn on pager for everything, -t value is usefull, since we don't + # want the pager working if the output is short. In situations where -t + # isn't prompted for, -t shouldn't be used, pretty beta. + # The best way is to read the output into a variable than use the pager. + # This can be done simply. + # if ($commands{"t"}) { + # open(STDOUT, "|$pager"); + # } + + + if ($#ARGV == -1 && !defined %commands){ + if ($Getopt::Long::error != 1) { + pager(usage()); + exit; + } + } + elsif (($commands{"n"} || $commands{"nopager"}) && + $#ARGV == -1 && !($commands{"q"} || $commands{"ps"} || + $commands{"research"} || $commands{"refinesearch"} || + $commands{"powersearch"} || $commands{"search"} || + $commands{"ramdiskon"} || $commands{"ramdiskoff"} || + $commands{"help"})) { + print nusage() if !($commands{"history"} || $commands{"h"}); + exit if !($commands{"history"} || $commands{"h"}); + } + elsif (!($commands{"n"} || $commands{"nopager"}) && $commands{"help"} + && $#ARGV == -1 && !($commands{"q"} || $commands{"ps"} || + $commands{"research"} || $commands{"refinesearch"} || + $commands{"powersearch"} || $commands{"search"} || + $commands{"ramdiskon"} || $commands{"ramdiskoff"})) { + pager(help()) if !($commands{"history"} || $commands{"h"}); + exit if !($commands{"history"} || $commands{"h"}); + } + elsif ((($commands{"n"} || $commands{"nopager"}) && $commands{"help"}) + && $#ARGV == -1 && !($commands{"q"} || $commands{"ps"} || + $commands{"research"} || $commands{"refinesearch"} || + $commands{"powersearch"} || $commands{"search"} || + $commands{"ramdiskon"} || $commands{"ramdiskoff"})) { + print help() if !($commands{"history"} || $commands{"h"}); + exit if !($commands{"history"} || $commands{"h"}); + } + + # version of the program + if ($commands{"version"}) { + print "SWIM version $swim_version\n"; + } + + + # Do the the dpkg -C thing, nice no need for a separate approach + if (($commands{"C"} || $commands{"audit"} || $commands{"status"}) && + defined $dpkg) { + system "$dpkg", "-C"; + exit; + } + + + # apt administration + if ($commands{"apt"}) { + if (defined $apt_get) { + my @amount = keys %commands; + if ($#amount == 0) { + print "swim: no options given for --apt\n"; + exit; + } + require SWIM::Apt; + SWIM::Apt->import(qw(apt)); + apt($apt_get,$sources,\%commands); + exit; + } + else { + print "swim: operation requires apt\n"; + exit; + } + } + + + # error testing for --md5sum + if ($commands{"md5sum"} && !($commands{"q"} || $commands{"query"})) { + print "swim: --md5sum may only be used during queries\n"; + exit; + } + elsif ($commands{"md5sum"} && + !($commands{"l"} || $commands{"d"} || $commands{"c"} || + $commands{"p"}) && ($commands{"q"} || $commands{"query"})) { + print "swim: --md5sum of queries must be used with -l, -d, -c, or -p\n"; + exit; + } + + + # Some error testing for major mode. Will handle all. + if (($commands{"initdb"} && $commands{"rebuilddb"}) || + ($commands{"initdb"} && $commands{"db"}) || + ($commands{"db"} && $commands{"rebuilddb"}) || + ($commands{"initdb"} && $commands{"db"}) || + ($commands{"initdb"} && $commands{"rebuilddb"} && $commands{"db"})) { + print "swim: only one major mode may be specified\n"; + exit; + } + + # this will handle options with arguments + if ($Getopt::Long::error == 1 || $commands{"root"} || $commands{"dbpath"}) { + # If two options are used + if ($Getopt::Long::error == 1) { + if ($commands{"dbpath"} && !$commands{"root"}) { + exit; + } + elsif (!$commands{"dbpath"} && $commands{"root"}) { + exit; + } + } + + # Check whether a different filesystem is being used with --root + my($arch, $dist) = which_archdist(\%commands); + if ($commands{"root"} && !$commands{"dbpath"}) { + if ($commands{"q"} || $commands{"query"} || $commands{"search"} || + $commands{"refinesearch"} || $commands{"research"} || + $commands{"powersearch"} || $commands{"ps"} || + $commands{"ramdiskon"} || $commands{"history"} || + $commands{"h"}) { + if ($commands{"root"} =~ m,^\/.*,) { + $parent = $commands{"root"}; + my $root; + if (!($commands{"n"} || $commands{"initndb"} || + $commands{"rebuildndb"} || $commands{"p"} || + $commands{"ndb"})) { + $root = "$parent$base/packages.deb"; + } + else { + $root = "$parent$base/npackages$arch$dist.deb"; + } + if (!-e $root && !-f $root) { + print "failed to open $root\n\n"; + exit; + } + } + elsif ($commands{"root"} ne "") { + print "swim: arguments to --root must begin with a /\n"; + exit; + } + } + else { + if ($commands{"initdb"} || $commands{"rebuilddb"} || + $commands{"db"} || $commands{"initndb"} || $commands{"ndb"} || + $commands{"rebuildndb"} || $commands{"rebuildflatdb"} || + $commands{"rebuildflatndb"}) { + if ($commands{"root"} =~ m,^\/.*,) { + $parent = $commands{"root"}; + my $root = "$parent$base"; + if (!-e $root && !-f $root) { + print "failed to open $root\n\n"; + exit; + } + } + elsif ($commands{"root"} ne "") { + print "swim: arguments to --root must begin with a /\n"; + exit; + } + } + else { + print "swim: --root may only be specified during querying, and database rebuilds\n"; + exit; + } + } + } + # check whether a different database location is being used with --dbpath. + elsif ($commands{"dbpath"} && !$commands{"root"}) { + if ($commands{"q"} || $commands{"query"} || $commands{"search"} || + $commands{"refinesearch"} || $commands{"research"} || + $commands{"powersearch"} || $commands{"ps"} || + $commands{"ramdiskon"} || $commands{"history"} || + $commands{"h"}) { + if ($commands{"dbpath"} =~ m,^\/.*,) { + my $dbpath; + $library = $commands{"dbpath"}; + if (!($commands{"n"} || $commands{"initndb"} || + $commands{"rebuildndb"} || + $commands{"p"} || $commands{"ndb"})) { + $dbpath = "$library/packages.deb"; + } + else { + $dbpath = "$library/npackages$arch$dist.deb"; + } + if (!-e $dbpath && !-f $dbpath) { + print "failed to open $dbpath\n\n"; + exit; + } + } + elsif ($commands{"dbpath"} ne "") { + print "swim: arguments to --dbpath must begin with a /\n"; + exit; + } + } + else { + if ($commands{"dbpath"} !~ m,^\/,) { + print "swim: arguments to --dbpath must begin with a /\n"; + } + else { + if ($commands{"initdb"} || $commands{"rebuilddb"} || + $commands{"db"} || $commands{"rebuildndb"} || + $commands{"initndb"} || $commands{"rebuildflatdb"} + || $commands{"ndb"} || $commands{"rebuildflatndb"}) { + if ($commands{"dbpath"} =~ m,^\/.*,) { + $library = $commands{"dbpath"}; + my $dbpath = "$library"; + if (!-e $dbpath && !-f $dbpath) { + print "failed to open $dbpath\n\n"; + exit; + } + } + elsif ($commands{"dbpath"} ne "") { + print "swim: arguments to --dbpath must begin with a /\n"; + exit; + } + } + else { + print "swim: --dbpath given for operation that does not use a database\n"; + exit; + } + } + } + } + # check whether a different database location is being used with --dbpath + # and --root / are being used, dbpath takes priority but uses --root as + # the base. + elsif ($commands{"dbpath"} && $commands{"root"}) { + if ($commands{"q"} || $commands{"query"} || $commands{"search"} || + $commands{"refinesearch"} || $commands{"research"} || + $commands{"powersearch"} || $commands{"ps"} || + $commands{"ramdiskon"} || $commands{"history"} || + $commands{"h"}) { + if ($commands{"dbpath"} =~ m,^\/.*, && + $commands{"root"} =~ m,^\/.*,) { + $parent = $commands{"root"}; + $library = $commands{"dbpath"}; + my $root = "$parent$library"; + my $dbpath; + if (!($commands{"n"} || $commands{"initndb"} || + $commands{"rebuildndb"} || $commands{"p"} || + $commands{"ndb"})) { + $dbpath = "$parent$library/packages.deb"; + } + else { + $dbpath = "$parent$library/npackages$arch$dist.deb"; + } + if (!-e $dbpath && !-f $dbpath) { + print "failed to open $dbpath\n\n"; + exit; + } + if (!-e $root && !-f $root) { + print "failed to open $root\n\n"; + exit; + } + } + elsif ($commands{"dbpath"} ne "") { + print "swim: arguments to --dbpath must begin with a /\n"; + exit; + } + } + else { + if ($commands{"dbpath"} !~ m,^\/,) { + print "swim: arguments to --dbpath must begin with a /\n"; + exit; + } + if ($commands{"initdb"} || $commands{"rebuilddb"} || + $commands{"db"} || $commands{"initndb"} || $commands{"ndb"} || + $commands{"rebuildndb"} || $commands{"rebuildflatdb"} || + $commands{"rebuildflatndb"}) { + if ($commands{"dbpath"} =~ m,^\/.*, && + $commands{"root"} =~ m,^\/.*,) { + $parent = $commands{"root"}; + $library = $commands{"dbpath"}; + my $root = "$parent$library"; + my $dbpath = "$parent$library"; + if (!-e $dbpath && !-f $dbpath) { + print "failed to open $dbpath\n\n"; + exit; + } + if (!-e $root && !-f $root) { + print "failed to open $root\n\n"; + exit; + } + } + elsif ($commands{"dbpath"} ne "") { + print "swim: arguments to --dbpath must begin with a /\n"; + exit; + } + } + else { + print "\nswim: --dbpath given for operation that does not use a database\n"; + exit; + } + } + } + # final monster ... but, really only as a trap. + elsif ($commands{"root"}) { + exit; + } + elsif ($commands{"dbpath"}) { + exit; + } + } # end if (Getopt + + + # need Package(s) and Contents file(s) --ftp + if ($commands{"ftp"} && !($commands{"q"} || + $commands{"search"} || $commands{"powersearch"} || + $commands{"ps"} || $commands{"research"} || + $commands{"refinesearch"})) { + require SWIM::Apt; + SWIM::Apt->import(qw(ftp)); + ftp(\%commands); + exit; + } + + + # make things a lot faster + if ($commands{"ramdiskon"} || $commands{"ramdiskoff"}) { + require SWIM::Ramdisk; + SWIM::Ramdisk->import(qw(ramdisk)); + ramdisk(\%commands); + } + + # swim history + if ($commands{"history"} || $commands{"h"}) { + my($arch,$dist) = which_archdist(\%commands); + my($place) = finddb(\%commands); + my $swim_history; + if ($commands{"n"}) { + $swim_history = "$place/.nswim$arch$dist" . "_history"; + } + else { + $swim_history = "$place/.swim" . "_history"; + } + open(HISTORY,"$swim_history") or exit; + my @HISTORY = ; my $h; $h = $#HISTORY + 1; + foreach (@HISTORY) { + printf "%5d %s",$h, $_; $h--; + } + exit; + } + + # The packages found by --search or --research become @ARGV + my ($arch,$dist) = which_archdist(\%commands); + my($place) = finddb(\%commands); + my $search_mem; + if ($commands{"n"}) { + $search_mem = "$place/.nswim$arch$dist" . "_history"; + } + else { + $search_mem = "$place/.swim" . "_history"; + } + + my $arg; + if ($commands{"S"} || $commands{"research"} || + $commands{"refinesearch"}) { + if ($#ARGV == 0) { + if ($ARGV[0] =~ /^\d{1,}$/ && $ARGV[0] ne 0) { + $arg = $ARGV[0]; undef @ARGV; + } + else { + $ARGV[0] =~ /^0$/ + ? print "swim: only one numeric argument (not 0) for -S allowed\n" + : print "swim: only one numeric argument for -S allowed\n"; + exit; + } + } + elsif ($#ARGV > 0) { + print "swim: only one numeric argument for -S allowed\n"; exit; + } + elsif ($#ARGV == -1) { + $arg = 1; + } + open(GREPER, "$search_mem") || exit; + my @LINES = reverse ; + if (defined $LINES[$arg - 1]) { + @ARGV = split(/\s/,$LINES[$arg - 1]); + } + close(GREPER); + } + + # let's do a search/research + if (((($commands{"search"} && + ($commands{"research"} || $commands{"refinesearch"})) || + ($commands{"research"} && + ($commands{"search"} || $commands{"refinesearch"})) || + ($commands{"refinesearch"} && + ($commands{"search"} || $commands{"research"}))) || + + ((($commands{"powersearch"} || $commands{"ps"}) && + ($commands{"research"} || $commands{"refinesearch"})) || + ($commands{"research"} && + ($commands{"powersearch"} || $commands{"ps"} || + $commands{"refinesearch"})) || + ($commands{"refinesearch"} && + ($commands{"powersearch"} || $commands{"research"} || + $commands{"ps"}))) || + + (($commands{"powersearch"} || $commands{"ps"}) && + $commands{"search"}))) { + print "swim: only one type of search permitted at one time\n"; + exit; + } + if ($commands{"search"}) { + require SWIM::Search; + SWIM::Search->import(qw(search)); + search($search_mem,\%commands); + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + exit; + } + if ($commands{"research"}) { + require SWIM::Search; + SWIM::Search->import(qw(search)); + search($search_mem,\%commands,$arg,\@ARGV); + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + exit; + } + if ($commands{"refinesearch"}) { + require SWIM::Search; + SWIM::Search->import(qw(search)); + search($search_mem,\%commands,$arg,\@ARGV); + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + exit; + } + if ($commands{"powersearch"} || $commands{"ps"}) { + require SWIM::Search; + SWIM::Search->import(qw(search)); + search($search_mem,\%commands); + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + exit; + } + + + + # Make new databases or rebuild existing databases from scratch + if ($commands{"initdb"}) { + require SWIM::DB_Init; + SWIM::DB_Init->import(qw(database)); + database(\%commands); + } + elsif ($commands{"rebuilddb"}) { + require SWIM::DB_Init; + SWIM::DB_Init->import(qw(database)); + database(\%commands); + } + elsif ($commands{"db"}) { + require SWIM::DB; + SWIM::DB->import(qw(db)); + db(\%commands); + } + elsif ($commands{"rebuildflatdb"}) { + require SWIM::DB; + SWIM::DB->import(qw(rebuildflatdb)); + rebuildflatdb(\%commands); + } + elsif ($commands{"rebuildflatndb"}) { + require SWIM::NDB; + SWIM::NDB->import(qw(rebuildflatndb)); + rebuildflatndb(\%commands); + } + + # parts above need to be edited to for --dbpath, --root and major mode + # whether --Contents will be required is still under consideration + elsif ($commands{"initndb"}) { + require SWIM::NDB_Init; + SWIM::NDB_Init->import(qw(initndb)); + initndb(\%commands); + } + elsif ($commands{"rebuildndb"}) { + require SWIM::NDB_Init; + SWIM::NDB_Init->import(qw(initndb)); + initndb(\%commands); + } + elsif ($commands{"ndb"}) { + require SWIM::NDB_Init; + SWIM::NDB_Init->import(qw(initndb)); + initndb(\%commands); + } + + + # *deb packages -p querys can be handled separately because they a particular to + # *debs. + if ($commands{"p"}) { + if ($commands{"f"} || $commands{"dir"} || $commands{"allgroups"} || + $commands{"a"} || $commands{"g"}) { + # check for some errors + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + require SWIM::Deb; + SWIM::Deb->import(qw(deb_package)); + deb_package(\%commands); + exit; + } + + # error testing for extract + if ($commands{"extract"}) { + if (!$commands{"p"}) { + print "swim: use major mode -p with --extract\n"; + } + } + + + # print out a nice tabular list of all the groups (Section:) on the + # system. + if ($commands{"allgroups"}) { + if ($commands{"f"} || $commands{"dir"} || + $commands{"a"} || $commands{"g"} || $commands{"p"}) { + # check for some errors + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + require SWIM::Groups; + SWIM::Groups->import(qw(allgroups)); + allgroups(\%commands); + } + +#@@@ + + + #Is this about a file or files? + if ($commands{"f"} || $commands{"dir"}) { + $| = 1; + + # check for some errors + if ($commands{"a"} || $commands{"g"}) { + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + + + # The description and info about the package. + if (($commands{"q"} || $commands{"query"}) && $commands{"i"}) { + if ($#ARGV != -1) { + require SWIM::Findex; + SWIM::Findex->import(qw(qindexer)); + foreach (@ARGV) { + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/(\w-+)+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + root(); + qindexer(\%commands); + } + else { print "swim: not implemented yet\n"; } + } + elsif ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + root(); + #print "ARG $argument\n"; + qindexer(\%commands); + } + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + qindexer(\%commands); + } + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + qindexer(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + # The file list and configuration files + elsif (($commands{"q"} || $commands{"query"}) && ($commands{"l"} && + $commands{"c"})) { + if ($#ARGV != -1) { + require SWIM::Indexer; + SWIM::Indexer->export(qw(indexer)); + foreach (@ARGV) { + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/(\w-+)+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + root(); + SWIM::Indexer::indexer(\%commands); + } + else { print "swim: not implemented yet\n"; } + } + elsif ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + root(); + SWIM::Indexer::indexer(\%commands); + } + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + SWIM::Indexer::indexer(\%commands); + } + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + SWIM::Indexer::indexer(\%commands); + } + } # end foreach + } + else { + print "swim: no arguments given for query\n"; + } + } + + # The file list + elsif (($commands{"q"} || $commands{"query"}) && $commands{"l"}) { + if ($#ARGV != -1) { + require SWIM::Findex; + SWIM::Findex->import(qw(findexer)); + foreach (@ARGV) { + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/(\w-+)+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + root(); + findexer(\%commands); + } + else { print "swim: not implemented yet\n"; } + } + elsif ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + root(); + findexer(\%commands); + } + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + findexer(\%commands); + } + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + findexer(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + # This should just grep Package: from description and produce + # the package name. There is a qa version to. + elsif ($commands{"q"} || $commands{"query"}) { + if ($#ARGV != -1) { + require SWIM::Indexer; + SWIM::Indexer->export(qw(indexer)); + foreach (@ARGV) { + if (m,\.\./|^\.\.$,) { + if ($_ !~ m,/(\w-+)+/[\.\$\^\+\?\*\[\]\w-]*$,) { + my $dd; tr/\/// ? ($dd = tr/\///) : ($dd = 1); + my @pwd = split(m,/,,$pwd); + s,\.\./,,g; + my $tpwd = ""; + for (1 .. $#pwd - $dd) { + $_ == 1 ? ($tpwd = "/$pwd[$_]") + : ($tpwd = $tpwd . "/$pwd[$_]"); + } + $_ ne ".." ? ($argument = "$tpwd/$_") : ($argument = "$tpwd/"); + root(); + SWIM::Indexer::indexer(\%commands); + } + else { print "swim: not implemented yet\n"; } + } + elsif ( m,\/,) { + $argument = $_; + if ($argument =~ m,^\.\/.*,) { + if ($pwd !~ m,^\/$,) { + $argument =~ m,^\.([^\.].*$),; + $argument = "$pwd$1"; + } + else { + $argument =~ m,^\.([^\.].*$),; + $argument = "$1"; + } + } + root(); + SWIM::Indexer::indexer(\%commands); + } + elsif ($pwd =~ m,^\/$,) { + $argument = "/$_"; + SWIM::Indexer::indexer(\%commands); + } + else { + $argument = "$pwd/$_"; + if ($argument =~ m,\.$,) { + $argument =~ m,(.*)\.$,; + $argument = $1; + } + SWIM::Indexer::indexer(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + } # about file + +#@@@ + + elsif ($commands{"g"}) { + $| = 1; + + #my @stuff; + + # check for some errors + if ($commands{"a"}) { + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + + # extract the packages related to the group. + if (!$commands{"n"}) { + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(gb)); + gb(\%commands); + } + else { + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(ngb)); + ngb(\%commands); + } + # someone may do something like this swim -qg text web so... + if ($commands{"g"} && !$commands{"q"}) { + print "swim: unexpected query source\n"; + exit; + } + if ($#ARGV != -1) { + foreach (@ARGV) { + $argument = $_; + if (defined $gb{$argument}) { + @stuff = split(/\s/, $gb{$argument}); + @PACKAGES = @stuff; + } + else { + print "group $argument does not contain any packages\n"; + } + } + } + else { + print "swim: no arguments given for query\n"; + } + + untie %gb; + + + # The description and info about the package. + if (($commands{"q"} || $commands{"query"}) && $commands{"i"}) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(description)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + foreach (@stuff) { + $argument = $_; + description(\%commands); + #print "\n" if $commands{"S"}; + print "\n"; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + # The file list and configuration files + elsif (($commands{"q"} || $commands{"query"}) && ($commands{"l"} && + $commands{"c"})) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(version)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + foreach (@stuff) { + $argument = $_; + version(\%commands); + q_description(\%commands); + print "\n"; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + # The file list + elsif (($commands{"q"} || $commands{"query"}) && $commands{"l"}) { + if ($#ARGV != -1) { + require SWIM::File; + SWIM::File->import(qw(file)); + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(version)); + require SWIM::Info; + SWIM::Info->import(qw(scripts)); + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + $file_now = "yes"; + foreach (@stuff) { + $argument = $_; + version(\%commands); + #print "$argument\n"; + if ($commands{"scripts"} || $commands{"preinst"} || + $commands{"postinst"} || $commands{"prerm"} || + $commands{"postrm"}) { + scripts(\%commands); + } + #copyright() if $commands{"copyright"}; + #changelog() if $commands{"changelog"}; + q_description(\%commands); + file(\%commands); + print "\n"; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + + # Find just the configuration files..mdsum included + elsif (($commands{"q"} || $commands{"query"}) && $commands{"c"}) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + foreach (@stuff) { + $argument = $_; + # we will have to provide a return value for q_description + # version produced notorious one + #version(); + # argument needs to be printed out in q_ + # print "$argument\n"; + q_description(\%commands); + print "\n"; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + # The documentation locations "d" takes priority over "l" + elsif (($commands{"q"} || $commands{"query"}) && $commands{"d"}) { + if ($#ARGV != -1) { + require SWIM::File; + SWIM::File->import(qw(file)); + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(version)); + require SWIM::Deps; + SWIM::Deps->import(qw(character)); + require SWIM::Info; + SWIM::Info-> + import(qw(scripts menu copyright changelog shlibs)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + foreach (@stuff) { + $argument = $_; + version(\%commands); + if ($commands{"scripts"} || $commands{"preinst"} || + $commands{"postinst"} || $commands{"prerm"} || + $commands{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands{"menu"} || $commands{"m"}; + copyright(\%commands) if $commands{"copyright"}; + changelog(\%commands) if $commands{"changelog"}; + # watch this + print "$argument\n"; + character(\%commands); + shlibs(\%commands) if $commands{"shlibs"}; + file(\%commands); + print "\n"; + } + if (!($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"})) { + if ($commands{"x"} || $commands{"ftp"} || $commands{"source"} || + $commands{"source_only"} || $commands{"remove"} || + $commands{"r"} || $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + + # This should just grep Package: from description and produce + # the package name. There is a qa version to. + elsif (($commands{"q"} || $commands{"query"})) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + $aptor_group = "yes" if ($commands{"y"} || $commands{"z"});; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @stuff = @PACKAGES; + foreach (@stuff) { + $argument = $_; + #print "$argument\n" if $commands{"S"}; + q_description(\%commands); + } + } + else { + print "swim: no arguments given for query\n"; + } + } + + } + + +#@@@ + + # not -g or -f, but -n + else { + + $| = 1; + + # check for some errors + if ($commands{"g"}) { + print "swim: one type of query/verify may be performed at a time\n"; + exit; + } + + # The description and info about the package. + if (($commands{"q"} || $commands{"query"}) && $commands{"i"} && + !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(description)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + foreach (@ARGV) { + $argument = $_; + description(\%commands); + print "\n" if $commands{"S"}; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && $commands{"i"} && + $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Findex; + SWIM::Findex->import(qw(qindexer)); + $argument = "/."; + qindexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + + # The file list and configuration files + elsif (($commands{"q"} || $commands{"query"}) && ($commands{"l"} && + $commands{"c"}) && !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::File; + SWIM::File->import(qw(file)); + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + $file_now = "yes"; + foreach (@ARGV) { + $argument = $_; + print "$argument\n" if $commands{"S"}; + q_description(\%commands); + file(\%commands) if !$commands{"md5sum"}; + print "\n" if $commands{"S"}; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && ($commands{"l"} && + $commands{"c"}) && $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Indexer; + SWIM::Indexer->import(qw(indexer)); + $argument = "/."; + indexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + # The file list + elsif (($commands{"q"} || $commands{"query"}) && $commands{"l"} && + !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::File; + SWIM::File->import(qw(file)); + require SWIM::Deps; + SWIM::Deps->import(qw(character)); + require SWIM::Info; + SWIM::Info->import(qw(scripts copyright changelog menu shlibs)); + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(version)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + foreach (@ARGV) { + $argument = $_; + #push(@PACKAGES,$argument); + print "$argument\n" if $commands{"S"}; + if ($commands{"scripts"} || $commands{"preinst"} || + $commands{"postinst"} || $commands{"prerm"} || + $commands{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands{"menu"} || $commands{"m"}; + copyright(\%commands) if $commands{"copyright"}; + changelog(\%commands) if $commands{"changelog"}; + version(\%commands); + character(\%commands); + shlibs(\%commands) if $commands{"shlibs"}; + file(\%commands); + print "\n" if $commands{"S"}; + } + if (!($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"})) { + if ($commands{"x"} || $commands{"ftp"} || $commands{"source"} || + $commands{"source_only"} || $commands{"remove"} || + $commands{"r"} || $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && $commands{"l"} && + $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Findex; + SWIM::Findex->import(qw(findexer)); + $argument = "/."; + findexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + + # Find just the configuration files..mdsum included + elsif (($commands{"q"} || $commands{"query"}) && $commands{"c"} && + !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + foreach (@ARGV) { + $argument = $_; + print "$argument\n" if $commands{"S"}; + q_description(\%commands); + print "\n" if $commands{"S"}; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && $commands{"c"} && + $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Indexer; + SWIM::Indexer->import(qw(indexer)); + $argument = "/."; + indexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + + # The documentation locations "d" takes priority over "l" + # Maybe this can be moved to indexer() + elsif (($commands{"q"} || $commands{"query"}) && $commands{"d"} && + !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::File; + SWIM::File->import(qw(file)); + require SWIM::Info; + SWIM::Info-> + import(qw(scripts menu copyright changelog shlibs)); + require SWIM::Deps; + SWIM::Deps->import(qw(character)); + require SWIM::DB_Library; + SWIM::DB_Library->import(qw(version)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + foreach (@ARGV) { + $argument = $_; + print "$argument\n" if $commands{"S"}; + if ($commands{"scripts"} || $commands{"preinst"} || + $commands{"postinst"} || $commands{"prerm"} || + $commands{"postrm"}) { + scripts(\%commands); + } + menu(\%commands) if $commands{"menu"} || $commands{"m"}; + copyright(\%commands) if $commands{"copyright"}; + changelog(\%commands) if $commands{"changelog"}; + # watch this + version(\%commands); + character(\%commands); + shlibs(\%commands) if $commands{"shlibs"}; + file(\%commands); + print "\n" if $commands{"S"}; + } + if (!($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"})) { + if ($commands{"x"} || $commands{"ftp"} || $commands{"source"} || + $commands{"source_only"} || $commands{"remove"} || + $commands{"r"} || $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && $commands{"d"} && + $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Indexer; + SWIM::Indexer->import(qw(indexer)); + $argument = "/."; + indexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + + # This should just grep Package: from description and produce + # the package name. There is a qa version to. + elsif (($commands{"q"} || $commands{"query"}) && + !$commands{"a"}) { + if ($#ARGV != -1) { + require SWIM::Ag; + SWIM::Ag->import(qw(q_description)); + @PACKAGES = @ARGV; + if ($commands{"z"} || + $commands{"ftp"} || $commands{"remove"} || $commands{"r"} || + $commands{"purge"}) { + require SWIM::Safex; + SWIM::Safex->import(qw(safex)); + safex(\%commands); + } + @ARGV = @PACKAGES; + foreach (@ARGV) { + $argument = $_; + #print "$argument\n" if $commands{"S"}; + q_description(\%commands); + #print "\n" if $commands{"S"}; + } + } + else { + print "swim: no arguments given for query\n"; + } + } + elsif (($commands{"q"} || $commands{"query"}) && $commands{"a"}) { + if ($#ARGV == -1) { + require SWIM::Indexer; + SWIM::Indexer->import(qw(indexer)); + $argument = "/."; + indexer(\%commands); + } + else { + print "swim: extra arguments given for query of all packages\n"; + } + } + + + } # not about file or -g + +#@@@ + +} # end sub command + + +sub usage { + +# Shameless publication of the ThE_* Project, and also shameless self +# agrandizing.... +print "SWIM version $swim_version +Copyright (C) 2000 - by Jonathan Rosenbaum for ThE_* Project +This may be freely redistributed under the terms of the GNU Public License\n"; + +$save = "SWIM version $swim_version +Copyright (C) 2000 - by Jonathan Rosenbaum for ThE_* Project +This may be freely redistributed under the terms of the GNU Public License + +Usage: swim [--nopager -n] + swim {--help} [--nopager -n] + swim {--version} + swim {--history -h} [--arch ] [--dists ] + [-n] [--dbpath ] [--root ] + swim {--initdb} [--dbpath ] [--root ] [--lowmem] + [--split_data ] + swim {--db} [--dbpath ] [--root ] [--check] + swim {--rebuilddb} [--dbpath ] [--root ] [--lowmem] + [--split_data ] + swim {--rebuildflatdb} [--dbpath ] [--root ] + swim {--search ? (--research || --refinesearch) } + [-g] [-n] [--dbpath ] [--root ] [--no] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--df2apt] [--purge] [<\\d{1,}>] + swim {--powersearch --ps ? (--research || --refinesearch) } + [-n] [--dir] [--dbpath ] [--root ] [--no] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--df2apt] [--purge] [<\\d{1,}>] + swim {--query -q} [-afpgn --dir] [--total -t] [-i] [-l ? <[--df]>] + [-d] [-c] [--scripts] [--preinst] [--postinst] + [--prerm] [--postrm] [-v] [--dbpath ] [--menu -m] + [--shlibs] [-T] [--pre_depends] [--depends] + [--recommends] [--suggests] [--conflicts] + [--replaces] [--provides] [--md5sum] [--root ] + [--copyright] [--changelog] [--allgroups] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [--stdin] [--extract ] + [-xyrz --remove ? <[--nz]>] [--purge] [--apt2df] + [--df2apt] [targets | -S ? <\\d{1,}>] + swim {--audit --status -C} + swim {--ftp} [--Contents ] [--Packages ] + [--arch ] [--dists ] + [--onec] [--Release_only] + swim {--apt} [--update] [--clean] [--autoclean] [--check] + swim {--apt} [-xyz] [--upgrade] [--dist_upgrade] + swim {--initndb} [--Contents ? <[--nue]>] + [--main] [--contrib] [--non-free] [--non-us] [--alt] + [--arch ] [--dists ] + [--dbpath ] [--root ] [--split_data ] + [-v] [--cron] [targets|APT|DF] + swim {--ndb ? <[--report]>} [--main] [--contrib] [--non-free] [--non-us] + [--Contents ? <[--nue]>] + [--arch ] [--dists ] + [--dbpath ] [--root ] [--check] [--alt] + [--status_only] [-v] [--cron] [targets|APT|DF] + swim {--rebuildndb} [--Contents ? <[--nue]>] + [--main] [--contrib] [--non-free] [--non-us] [--alt] + [--arch ] [--dists ] + [--dbpath ] [--root ] [-v] [--cron] + [--split_data ] [targets|APT|DF] + swim {--rebuildflatndb} [--dbpath ] [--root ] + [--arch ] [--dists ] + swim {--ramdiskon} [-n] [--searchfile] [--arch ] + [--dists ] [--dbpath] [--root] + swim {--ramdiskoff} + +Hints: Searches - equiv. negated [^...] + escapes: word boundaries - \\b \\B + [0-9] - \\d \\D + [a-zA-Z0-9_] - \\w \\W + [ \\r\\t\\n\\f] - \\s \\S + case insensitive: \"pattern/i\" + string = multi lines: \"pattern/m\" + string beginning: \^, \\A + string end: \$, \\Z + single character: \. + quantifiers: \*, \?, \+ + alternatives: \"pattern|pattern\" + + Groups - subject(below) contrib\/subject or non-free\/subject + or non-us\/subject or swim -q --allgroups + exceptions - no contrib\/contrib or non-free\/non-free + contrib, non-free, admin, base, comm, devel, doc, + editors, electronics, experimental, games, graphics, + hamradio, interpreters, libs, mail, math, misc, net, + news, oldlibs, otherosfs, shells, sound, tex, text, + utils, web, x11 + +Quit?:press q here\n"; +} + + +# nusage +sub nusage { + +$save = "SWIM version $swim_version +Copyright (C) 2000 - by Jonathan Rosenbaum for ThE_* Project +This may be freely redistributed under the terms of the GNU Public License + +Usage: swim [--nopager -n] + swim {--help} [--nopager -n] + swim {--version} + swim {--history -h} [--arch ] [--dists ] + [-n] [--dbpath ] [--root ] + swim {--initdb} [--dbpath ] [--root ] [--lowmem] + [--split_data ] + swim {--db} [--dbpath ] [--root ] [--check] + swim {--rebuilddb} [--dbpath ] [--root ] [--lowmem] + [--split_data ] + swim {--rebuildflatdb} [--dbpath ] [--root ] + swim {--search ? (--research || --refinesearch) } + [-g] [-n] [--dbpath ] [--root ] [--no] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--df2apt] [--purge] [<\\d{1,}>] + swim {--powersearch --ps ? (--research || --refinesearch) } + [-n] [--dir] [--dbpath ] [--root ] [--no] + [--arch ] [--dists ] + [--ftp ? --source | --source_only <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--df2apt] [--purge] [<\\d{1,}>] + swim {--query -q} [-afpgn --dir] [--total -t] [-i] [-l ? <[--df]>] + [-d] [-c] [--scripts] [--preinst] [--postinst] + [--prerm] [--postrm] [-v] [--dbpath ] [--menu -m] + [--shlibs] [-T] [--pre_depends] [--depends] + [--recommends] [--suggests] [--conflicts] + [--replaces] [--provides] [--md5sum] [--root ] + [--copyright] [--changelog] [--allgroups] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [--stdin] [--extract ] + [-xyrz --remove ? <[--nz]>] [--purge] [--apt2df] + [--df2apt] [targets | -S ? <\\d{1,}>] + swim {--audit --status -C} + swim {--ftp} [--Contents ] [--Packages ] + [--arch ] [--dists ] + [--onec] [--Release_only] + swim {--apt} [--update] [--clean] [--autoclean] [--check] + swim {--apt} [-xyz] [--upgrade] [--dist_upgrade] + swim {--initndb} [--Contents ? <[--nue]>] + [--main] [--contrib] [--non-free] [--non-us] + [--arch ] [--dists ] + [--dbpath ] [--root ] [--split_data ] + [-v] [--cron] [targets|APT|DF] + swim {--ndb ? <[--report]>} [--main] [--contrib] [--non-free] [--non-us] + [--Contents ? <[--nue]>] + [--arch ] [--dists ] + [--dbpath ] [--root ] [--check] + [--status_only] [-v] [--cron] [targets|APT|DF] + swim {--rebuildndb} [--Contents ? <[--nue]>] + [--main] [--contrib] [--non-free] [--non-us] + [--arch ] [--dists ] + [--dbpath ] [--root ] [-v] [--cron] + [--split_data ] [targets|APT|DF] + swim {--rebuildflatndb} [--dbpath ] [--root ] + [--arch ] [--dists ] + swim {--ramdiskon} [-n] [--searchfile] [--arch ] + [--dists ] [--dbpath] [--root] + swim {--ramdiskoff} + +Hints: Searches - equiv. negated [^...] + escapes: word boundaries - \\b \\B + [0-9] - \\d \\D + [a-zA-Z0-9_] - \\w \\W + [ \\r\\t\\n\\f] - \\s \\S + case insensitive: \"pattern/i\" + string = multi lines: \"pattern/m\" + string beginning: \^, \\A + string end: \$, \\Z + single character: \. + quantifiers: \*, \?, \+ + alternatives: \"pattern|pattern\" + + Groups - subject(below) or contrib\/subject or non-free\/subject + or non-us\/subject or swim -q --allgroups + exceptions - no contrib\/contrib or non-free\/non-free + contrib, non-free, admin, base, comm, devel, doc, + editors, electronics, experimental, games, graphics, + hamradio, interpreters, libs, mail, math, misc, net, + news, oldlibs, otherosfs, shells, sound, tex, text, + utils, web, x11\n"; +} # end sub nusage + +# Tries to emulate rpm --help, but rather futile, because of the great +# differnces between swim and rpm. +sub help { + +$save = "SWIM version $swim_version +Copyright (C) 2000 - by Jonathan Rosenbaum for ThE_* Project +This may be freely redistributed under the terms of the GNU Public License + +usage: + --help - print this message + --nopager -n - no pager wanted + --version - print the version of swim being used + + --history - print the search and stdin history + + --query + -q - query mode + -S - search result argument + -t - override output suppressor + --allgroups - display all groups to which packages belong + --dbpath - use as the directory for the database + --root - use as the top level directory + --arch - database architecture + --dist - database distribution + Package specification options: + -a - query all packages + -g - query all packages belong to a group + -f - query package owning + --dir - query package owning + -p - query debian package + -n - query not-installed system package + Information selection options: + -i - display package information + -l - display package file list + --df - display package directories (used with -l) + -v - ls -l listing (-p only) + -d - list documentation files (overrides -l) + -c - list configuration files and MD5 checksums + --scripts - print the various scripts + -t can be used to show title for an individual script + --preinst - display pre-installation scripts + --postinst - display post-installation scripts + --prerm - display pre-removal scripts + --postrm - display post-removal scritps + --changelog - display the package's changelog + --copyright - display the package's copyright + --menu + -m - display menufile for package + --shlibs - display shared libraries file for package + -T - display all package relationships + --pre_depends - display any pre-depends package + --depends - display any real or virtual depends package + --recommends - display any real or virtual recommends package + --suggests - display any real or virtual suggests package + --conflicts - display any real or virtual conflict package + --replaces - display packages this package can replace + --provides - display any declared virtual package + MD5 checksum option + --md5sum - display result for MD5 checksum for -l, -d, + -c, or -p + Extraction option + --extract + - extract archive, choice (-l), or + choice (-l) in pwd (-p only) + + Virtual options + -x - simulate apt-get installation + -y - answer yes to all apt-get prompts + -z - get and install package using apt-get + --nz - only download package when using apt-get + --ftp - download package + --source - download source package + --source_only - only download source package + --diff - only download the source package's diff file + --purge - remove the installed package, and the + package's configuration files + --remove + -r - remove the installed package, but not the + package's configuration files + --apt2df - not implemented + --df2apt - not implemented + Editing Option + --stdin - allows readline editing capabilities when + used with virtual options + Arguments + - package, packagename, packagename_version, + files/dirs, group + -S <\\d{1,}> - results from search/stdin history, 1 is + default. + + --search - search package information + --powersearch + --ps - search package information and all files + --research - research a previous search without making + the new results permanent + --refinesearch - research a previous search making the new + results permanent + --dbpath - use as the directory for the + --root - use as the top level directory + database + --arch - database architecture + --dist - database distribution + Package specification options: + -g - search all packages belong to a group + -n <-g> - search not-installed system package + Database selection option: + --dir - search all directories (powersearch only) + Virtual options + -x - simulate apt-get installation + -y - answer yes to all apt-get prompts + -z - get and install package using apt-get + --nz - only download package when using apt-get + --ftp - download package + --source - download source package + --source_only - only download source package + --diff - only download the source package's diff file + --purge - remove the installed package, and the + package's configuration files + --remove + -r - remove the installed package, but not the + package's configuration files + --apt2df - not implemented + --df2apt - not implemented + Editing Option + --stdin - allows readline editing capabilities when + used with virtual options + Output + --no - no output during search + Argument + <\\d{1,}> - search/stdin history, 1 is + default. + + --ramdiskon - create and mount ramdisk + --ramdiskoff - unmount ramdisk + --dbpath - use as the directory for the + --root - use as the top level directory + database + --arch - database architecture + --dist - database distribution + Database selection options + -n - use not-installed system databases + --searchfile - use search databases + + --audit + --status + -C - audit package statuses + + --ftp - get specified databases + --Release_only - only check and update Release version + --arch - database architecture + --dist - database distribution + Database Selection + --Packages - put Packages database in default + directory or specified directory + --Contents - put Contents database in default + directory or specified directory + --onec - retrieve only one Contents per + distribution/architecture + + + --apt - important apt-get options + --update - retrieve Package databases, update cache, and + update Release version + --clean - removes packages from archives directory + --autoclean - remove only packages not found in cache + --check - check and update cache + + --apt - apt-get options allowing major changes to + installed system + --upgrade - install newest versions of the packages + installed on the system + --dist_upgrade - do an upgrade as well as intelligently + installing new packages + Control options + -x - simulate apt-get installation + -y - answer yes to all apt-get prompts + -z - get and install package using apt-get + + --initdb - make databases for installed system + --db - update databases for installed system + --rebuilddb - rebuild databases for installed system + --rebuildflatdb - rebuild the search databases + --dbpath - use as the directory for the database + --root - use as the top level directory + --lowmem - use low memory method to make databases + --split_data - change size of database making files by + altering the amount of lines + --check - check what will be updated (--db) + + --initndb - make database for not-installed system + --ndb - update not-installed system + --rebuildndb - rebuild database for not-installed system + --rebuildflatndb - rebuild the search databases + --dbpath - use as the directory for the database + --root - use as the top level directory + --arch - database architecture + --dist - database distribution + --alt - alternative Debian archival distribution + --lowmem - use low memory method to make databases + --split_data - change size of database making files by + altering the amount of lines + --check - check what will be updated (--ndb) + --status_only - update status only (--ndb) + --report - not implemented (--ndb) + + Alternative Sections + --main - extract main section + --contrib - extract contrib section + --non-free - extract non-free section + --non-us - extract non-us section + Automate + --cron - automate database production + Test + -v - check built-in comparison function + Contents Database + --Contents + - use Contents database (FDB - make + only a flat database from the Contents + database allowing file listing) + --nue - use if non-us or experimental have + files/dirs in Contents (unusual). + + Packages Database + [targets|APT|DF] - use Packages database specified in a + particular directory, apt's, or the + default directory. + + + +\n"; + +} # end sub help + +# Pulled this from dftp, but I like "less" (the default) ! +sub pager { + my($text) = @_; + open(PAGER, "| $ENV{PAGER}") or + die "Couldn't open your pager ($ENV{PAGER})"; + print PAGER $text; + close PAGER; +} # end sub pager diff --git a/swim.8 b/swim.8 new file mode 100644 index 0000000..c55afe8 --- /dev/null +++ b/swim.8 @@ -0,0 +1,1558 @@ +.rn '' }` +''' $RCSfile$$Revision$$Date$ +''' +''' $Log$ +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.ie n \{\ +.ds -- \(*W- +.ds PI pi +.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH swim 8 " " "15/Jun/99" " " +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.bd B 3 +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds ? ? +. ds ! ! +. ds / +. ds q +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +swim \- package administration and research tool for Debian packages +.SH "SYNOPSIS" +swim [options] +.SH "DESCRIPTION" +\fBswim\fR is a powerful \fIpackage administration\fR and \fIresearch tool\fR for +both an \fIinstalled Debian distribution\fR, and/or \fInot-installed virtual +Debian distribution(s)\fR allowing querying of software packages with a +variety of package information options, and powerful searches. Virtual +options which include ftp, installation, and package removal capabilities +can be seamlessly combined with querying or searches. \fBswim\fR can be used +on computer systems which either have, or do not have a Debian +distribution installed. +.SH "COMMAND LINE OPTION SYNTAX" +When you press ``\fBswim\fR <\fBenter\fR>`` you will see a listing of command +line options in a particular syntax. This is to help you understand under +what context to use the options. When you enter the options on the command +line, the brackets, parentheses, braces, diamonds, and question marks are +not actually used. +.PP +\fBMajor Mode Option\fR +.PP +All command line options for \fBswim\fR always start with a +\fBmajor mode option\fR, except for ``swim +`` which will show the whole listing of +options. A major mode option is surrounded in braces +\fB{ major mode option }\fR. In the case of +{--search} there are the alternative major mode +options {--refinesearch} and +{--research}, but because --search needs +to be used first before either of these two options, +--refinesearch and --research are +surrounded in parentheses (). +.PP +Note: Through the other chapters of this manual \fB{}\fR is +assumed for the \fBmajor modes\fR in the +\fBusage:\fR section shown at the beginning of every chapter. +.PP +Let's take a closer look at this situation: +.PP +.Vb 1 +\& {--search ? (--research || --refinesearch) } +.Ve +`\fB||\fR\*(R' or `\fB|\fR\*(R' are used to indicate `\fBor\fR\*(R', `\fB?\fR\*(R' indicates +`\fBoptional\fR\*(R', indicates an \fBargument\fR (a required argument \- +see Arguments below), (parenthesis) means `if used, must be used after the +previous required option was used\*(R'. Note: for readability \f(CW--research\fR +and \f(CW--refinesearch\fR are not surrounded in \f(CW{}\fR. +.PP +\fBNormal Options\fR +.PP +Options to the major mode options are enclosed in brackets \fB[ option to +major mode ]\fR. \f(CWswim [-n]\fR <\f(CWenter\fR>; (assume enter from here on out), +for instance, will show all the command line options without using the +pager. The pager which swim uses can be set in \fIswimrc\fR (see +\fIswimrc(8)\fR). ``\f(CWswim {--help} [-n]\fR'\*(R' will provide brief explanations +of all of swim's options without using the pager. In this case the major +mode option \fB{--help}\fR, and the option \fB[\-n]\fR were used. +.PP +\fBDashes\fR +.PP +Options which have a single dash can be combined with other single dashed +options \fB(\-qaint)\fR. Double dashed options need to be entered by +themselves \fB(--help --nopager)\fR, many double dashed options have an +alternative single dash option \fB(\-n for --nopager)\fR. The meaning of +options is related to the major mode they are being used with. \fB[\-n]\fR +means no pager when called with \fB{--help}\fR, but it's a reference to the +not-installed databases when used with \fB{\-q --query}\fR, fortunately most +options do not have double meanings. +.PP +\fBArguments\fR +.PP +Many options require an argument. Arguments are enclose in diamonds +<\fBargument\fR>. An argument to an option may also be optional in which case +a question mark ``\fB?\fR'\*(R' will be placed between the option and the +argument. \fB[\-l ?\fR <\fB[--df]\fR>\fB]\fR illustrates such a situation. \fB[\-l]\fR +shows a file listings, and optionally the option \fB[--df]\fR can be use with +\fB[\-l]\fR to show an expanded listing. +.PP +\fB[--dbpath\fR <\fBdir\fR>\fB]\fR requires an argument, this time the argument +would not be another option, but rather it is a directory. +.PP +Rule: When an option is an argument to another option it can be written +anywhere, but when a non-option is an argument <\fBdir\fR>; \fB(notice no +brackets)\fR it has to be placed directly after the option. Sometimes, +there may be alternative arguments divided with ``\fB|\fR'\*(R'. +<\fBargument1|argument2\fR>; means use argument1 or argument2, but not both. +.PP +Based on what we now know, let's compare this situation to the +\fB{--search}\fR situation shown above: +.PP +.Vb 1 +\& [--ftp ? --source | --source_only ? <[--diff]>] +.Ve +In this case \fB--source\fR or alternatively +\fB--source_only\fR can be optionally used along with +\fB--ftp\fR because they aren't in parentheses +\fB()\fR (also notice: | was used instead of ||, but means the +same thing ``or''). \fB--diff\fR can optionally be provided as +an argument to either \fB--source\fR or +\fB--source_only\fR. For readability --source and --source_only +weren't enclosed in brackets. +.PP +\fBGlobal Arguments\fR +.PP +A \fBglobal argument\fR can be typed anywhere on the command +line, and can be an option or text. If global arguments +exist they are placed last after the list of normal +options that can be used with a major mode +option. +.PP +[targets | \-S] and [targets|APT|DF] are +examples. {\-q}, {--initndb}, and +{--rebuildndb} all use global arguments. +.PP +\fBMinor Mode Options\fR +.PP +{\-q --query} will generally use zero or more +minor mode options [\-afpgn --dir], with +one exception (see QUERYING). +.SH "VERSION" +usage: \fBswim --version\fR +.PP +This shows the version for the swim program. +.SH "HISTORY" +usage: \fBswim --history\fR + \fBswim \-h\fR +.PP +options: \fB[--arch\fR <\fBarchitecture\fR>\fB] [--dists\fR <\fBdistribution\fR>\fB]\fR + \fB[--n] [--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB]\fR +.PP +This shows a shell-like history of searches and the most recent --stdin +edit. History is numbered with the most recent action being 1, and the +earlier actions being of a higher number until the maximum amount of lines +set in the HISTORY variable in \fIswimrc\fR\|(5). A separate history is kept for +each architecture-distribution. +.SH "MAKING INSTALLED SYSTEM DATABASES" +.Sh "Initial database making, and Rebuilding for an Installed system." +usage: \fBswim --initdb\fR + \fBswim --rebuilddb\fR +.PP +Options: \fB[--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB] [--lowmem]\fR + \fB[--split_data\fR <\fBlines\fR>\fB]\fR +.PP +An \fIinstalled Debian distribution\fR is one in which packages are installed +using \fBdpkg\fR or some front-end to \fBdpkg\fR like \fBapt\fR or \fBdselect\fR; +\fBswim\fR supports installation through \fBapt\fR. These major modes are for a +computer with an \fIinstalled Debian distribution\fR and make the databases +which allow querying and searching capabilities for the installed +distribution. +.PP +\fB--initdb\fR is run when the databases do not exist yet, \fB--rebuilddb\fR is +run if the databases have become corrupt, or you want to rebuild the +databases instead of updating them. +.PP +\fB--dbpath\fR can be specified as an alternative location for where the +databases will be made. The default location is \*(L"\fI/var/lib/dpkg\fR\*(R". An +argument like \*(L"\fI/otherstuff\fR\*(R" could be provided, and then the databases +would be made here instead. +.PP +\fB--root\fR allows a database to be made for a Debian distribution installed +on a different partition. If the distribution is mounted on +\fI/New_Debian\fR, \*(L"\fI/New_Debian\fR\*(R" would be the argument to root. The +databases would be made for the Debian distribution installed on the +\*(L"\fI/New_Debian\fR\*(R" partition. +.PP +\fB--dbpath\fR and \fB--root\fR can be used together. Given the previous two +examples, the databases would be made on \*(L"\fI/New_Debian/otherstuff\fR\*(R", +assuming \*(L"\fI/New_Debian/otherstuff\fR\*(R" actually existed. +.PP +\fB--lowmem\fR uses a method which uses a small amount of memory to make the +databases. By default \fB--initdb\fR and \fB--rebuilddb\fR use a method which +fully takes advantage of memory, this is a good thing, because it means +the databases are made in a quicker manner. On a computer with a K6-200 +\s-1CPU\s0, 64MB of memory, and 1500 installed packages, the databases can be +made in 4.5 minutes using the default method, and 11 minutes using the low +memory method. The high memory method is the default because in general +the size of a distribution is related to how much resources a computer +has, and probably a large installation is unusual. If you get an \*(L"out of +memory\*(R" when you use the default method, or if your system is overloaded +to begin with, the \fB--lowmem method\fR is the prefered way. +.PP +\fB--split_data\fR determines the size of the files in the temporary +directory used to contruct the database. The default is 25000 lines per +file. If you are using the \fB--lowmem method\fR you may want to provide a +different argument to \fB--split_data\fR, like \*(L"\fB--split_data 10000\fR\*(R". This +is a subject of experimentation. +.Sh "\s-1UPDATING\s0" +usage: \fBswim --db\fR +.PP +options: \fB[--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB] [--check]\fR +.PP +\fB--db\fR allows you to update the databases by hand when packages have been +removed, added, or changed. swim will automatically run \fB--db\fR under +certain conditions. +.PP +\fB--check\fR prints out the changes to \s-1STDERR\s0, and the total to \s-1STDOUT\s0 +without proceeding with the update. +.PP +See \fB--initdb\fR for options \fB--dbpath\fR and \fB--root\fR. +.Sh "\s-1REBUILDING\s0 \s-1THE\s0 \s-1SEARCH\s0" +usage: \fBswim --rebuildflatdb\fR +.PP +options: \fB[--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB]\fR +.PP +swim makes the flat databases \fIsearchindex.deb\fR and \fIdirindex.deb\fR for +doing \fIpowersearches\fR. Instead of rebuilding these databases everytime +\fB--db\fR is run, new information is just appended to these databases, and +old information is kept. Generally, this is not a problem because only +files and directories which the other databases actually know something +about will be refered to. But in a situation where a file has changed +into a directory, the \fIpowersearch\fR may not work properly, because the +old file name remains in \fIsearchindex.deb\fR, and the new directory name is +now in \fIdirindex.deb\fR directory. In general, it takes a lot of changes +to the installed system before it is really becomes necessary to rebuild +the flat databases. This process takes less than a minute on a K6-200 +with 1500 packages. +.PP +See \fB--initdb\fR for options \fB--dbpath\fR and \fB--root\fR. +.Sh "\s-1FILES\s0" +Databases which are made: +.PP +.Vb 6 +\& packages.deb +\& fileindex.deb +\& statusindex.deb +\& groupindex.deb +\& searchindex.deb +\& dirindex.deb +.Ve +.SH "IMPORTANT DEBIAN DATABASES FOR NOT\-INSTALLED DATABASES" +.Sh "A. downloading the important databases with --ftp." +usage: \fBswim --ftp\fR +.PP +options: \fB--Contents\fR <\fB\s-1DF\s0|directory\fR> + \fB--Packages\fR <\fB\s-1DF\s0|directory\fR> + \fB[--dists\fR <\fBdistribution\fR>\fB] [--arch\fR <\fBarchitecture\fR>\fB]\fR + \fB[--onec] [--Release_only]\fR +.Sh "\s-1OVERVIEW\s0" +\fBswim\fR provides a method so that all information about an existing Debian +distribution is quickly accessible through databases. Debian already +provides flat file databases for all its distributions. One database +called \*(L"\fIContents-(architecture)\fR\*(R" provides a complete listing of all the +files associated with each package, the other much more important database +called \*(L"\fIPackages\fR\*(R" provides everything from the Package's description, +to all the dependencies for that package. The Packages database is a +crucial database for other important Debian administrative tools like +\fBdpkg\fR and \fBapt\fR. +.Sh "\s-1DISTRIBUTION\s0 \s-1DEFINED\s0" +Debian Distributions choose a name which reflect the development state of +that distribution. The distribution named \*(L"\fIunstable\fR\*(R" is where the +majority of the development processing occurs, after \fIunstable\fR has +reached a certain level of maturity, it's copied over to a new +distribution called \*(L"\fIfrozen\fR\*(R" which is tested extensively before +becoming the new \*(L"\fIstable\fR\*(R" distribution. The \fIfrozen distribution\fR +retains the \fIRelease version number\fR of the \fIunstable distribution\fR, and +the \fIunstable distribution\fR receives a new \fIRelease version number\fR. +Eventually, \fIfrozen\fR becomes \fIstable\fR, and at this point both \fIfrozen\fR, +and the older \fIstable distribution\fR are removed. Code names are +associated with the \fIRelease Version number\fR given for each of the +distributions. This is much better for mirroring Debian sites. +.PP +\fBswim\fR was designed to ignore these code names, and instead shows the +user the \fIRelease version number\fR associated with the distribution. Swim +users must always use the real distribution name, or swim will not work +properly. This is a nice feature because it allows user to make decisions +related to the management of their databases, and makes research much more +easier. +.PP +The other Debian distribution which swim recognizes is \fIexperimental\fR. +This distribution \fIdoes not have any Release version number\fR, and +contains packages which are considered risky because of their development +level. +.Sh "\s-1SECTIONS\s0" +Each Debian distribution has sections related to the relationship of each +of the packages to the \fIDebian's Policy Manual\fR. In \*(L"\fImain\fR\*(R" there are +packages which have a correct relationship with these Policies. Packages +in \*(L"\fIcontrib\fR\*(R" comply with the \fI\s-1DFSG\s0\fR (\fIDebian Free Software +Guidelines\fR found in the \fIDebian Policy Manual\fR) but have various +limitations like requiring a package which is found in non-free, or is not +in the Debian archive. Packages in \*(L"\fInon-free\fR\*(R" do not comply with the +\fI\s-1DFSG\s0\fR but are electronically distributable across international borders. +The \*(L"\fInon-us\fR\*(R" section is found outside of the United States and exists +for packages which have export restrictions. +.Sh "\s-1ARCHITECTURES\s0" +Distributions also have architecture specific sections since not all +packages compiled for one architecture can run on all other +archictectures, however, there are a large percentage of packages which do +run on all architectures. The architectures are \fIalpha\fR, \fIarm\fR, +\fIi386\fR, \fIm68k\fR, \fIpowerpc\fR, \fIsparc\fR, and more recently \fIhurd-i386\fR +which represents packages for the hurd \s-1GNU\s0 kernel for the i386 +architecture. +.Sh "\s-1SWIMZ\s0.\s-1LIST\s0" +\fB--ftp\fR uses a file called \fIswimz.list\fR which has the same type of +format (see format below) as the \fIsources.list(5)\fR which \fBapt\fR uses. +There are some differences. The \fBfirst difference\fR mentioned above +requires that the distribution names never should be the code names for +the \fIRelease version\fR. \fBSecondly\fR, \fBapt\fR only retrieves databases +specific to one archictecture, normally the one you are running \fBapt\fR on. +With \fBswim\fR though you can fetch databases for any, or every architecture +by adding the architecture to \*(L"deb\*(R" with a hyphen (deb-hurd-i386). If deb +has no architecture appended it is assumed that the architecture you want +is the same as the system you are running \fBswim\fR on. \fBThirdly\fR, at this +time \fBswim\fR only supports the ftp method. \fBFourthly\fR, you can change +\fIswimz.list\fR as often as you want without worrying about databases being +removed so that that the \fIswimz.list\fR and the downloaded databases match. +This would occur with \fBapt's\fR \fIsources.list(5)\fR if you removed a site. +\fBFifthly\fR, databases are kept in a compressed state. \fBSixthly\fR, because +the list is used for both Contents and Packages, more flexibility is +provided by only allowing the default distribution/archictecture or +distribution/architecture provided on the commandline to be downloaded. +.PP +For \fBapt\fR users: If you are using \fBapt\fR, and \fBswim\fR together it is a +good strategy to use the real distribution name in the \fIsources list(8)\fR, +and to have an exact copy of the \fIsources.list(5)\fR ftp sites in the +\fIswimz.list\fR. Packages databases specific to the architecture \fBapt\fR is +using can be retrieved using \fBswim --apt --update\fR (this also will keep +track of the Release version), and then \fBswim\fR can be used to fetch the +architecture specific \fIContents database\fR as shown below. It should also +be of interest to note that Packages downloaded by either swim or apt can +be used interchangeably by using \*(L'cp \-a\*(R' and \*(L'gzip \-d\*(R' or \*(L'gzip \-9\*(R'. +.PP +Here is a brief outline of the format required by \fIswimz.list\fR. +.PP +\fBdeb uri distribution [section ... ]\fR +.PP +\fBdeb\fR \- represents a standard Debian distribution. And is simply written +as deb or with the architecture appended (\fBdeb\fR or \fBdeb-alpha\fR). +.PP +\fBuri\fR \- Universal Resource Identifier is exactly how you would enter an +address into a web browser. This address is the base of a Debian +distribution, generally this is right before the directory called +\*(L"\fIdists\fR\*(R". So if \fIdists\fR is found in \fI/stuff/pub/debian/dists\fR, and the +site is \fBsomewhere.com\fR then the uri would be +\fIftp://somewhere.com/stuff/pub/debian\fR. +.PP +\fBdistribution\fR \- This can be \fIunstable\fR, \fIfrozen\fR, \fIstable\fR, +\fIexperimental\fR. Distribution can also be a path which must end with a +slash like \fIunstable/binary-i386/\fR. This is used when there is no section +as in the experimental distribution or in sites which do not have symlinks +to the non-us section. No section would be mentioned in this situation. + +\fBsection\fR \- \fImain\fR, \fIcontrib\fR, \fInon-free\fR, \fInon-\s-1US\s0\fR (write it this +way). +.Sh "\s-1SWIMZ\s0.\s-1LIST\s0 \s-1EXAMPLES\s0" +Examples (each on one line): +.PP +\fBdeb-alpha ftp://somewhere.com/stuff/pub/debian unstable main contrib +non-\s-1US\s0\fR +.PP +This will fetch the alpha databases from somewhere.com for the unstable +distribution for the main, contrib and non-\s-1US\s0 sections. +.PP +Note: In these next two examples you can not append any architecture to +deb with a hyphen. +.PP +\fBdeb ftp://somewhere.com/stuff/pub/debian project/experimental/\fR +.PP +This will fetch the experimental database, but there is +not a Contents-(architecture) database for this distribution. Notice that +it ends with a slash. +.PP +\fBdeb ftp://somewhere.com/stuff/pub/debian-non-\s-1US\s0 stable/binary-i386/\fR +.PP +This will fetch the i386 databases for the stable distribution for non-us, +.Sh "\s-1FTP\s0 \s-1OR\s0 \s-1APT\s0?" +How you use major mode \fB--ftp\fR depends on your goals. Even if you are +using \fBapt\fR, you may be interested in keeping tabs on different +architectures. In this case you would have to download the \fIPackages +databases\fR specific to these architectures. If you are only interested in +the architecture which \fBapt\fR is interested in, then you only need to use +\fB--ftp\fR to fetch the \fIContents database(s)\fR. But, because it isn't a +requirement to set up a virtual filesystem, you are not required to fetch +the Contents database. The \fBadvantages\fR of fetching the Contents +database is determined by the method you choose to make the database (see +\f(CW--initndb\fR). These advantages include the ability to \fIview a listing +of the files and directories\fR associated with a package, the ability to +\fIquery files and directories\fR to find out which packages relate to them, +and the ability to perform a \fIpowersearch\fR on all the files and +directories to find the associated packages. +.Sh "\s-1OPTIONS\s0" +\fBRemember:\fR If you want to download a different +distribution/architecture other than the default specified in your +configuration file, you must specify this on the commandline. +.PP +\fB--Packages\fR determines where you want the Packages database as well as +the Release data put when they are downloaded. The \fB\s-1DF\s0 argument\fR implies +that the databases will be put in your default directory (see \fIswimrc\fR\|(8)). +These databases can later be located by the major modes \fB--initndb and +--rebuildndb\fR just by using \fB\s-1DF\s0\fR as an argument. Alternatively, these +databases can be put in any directory you choose by providing a +\fBdirectory as an argument\fR. +.PP +\fB--Contents\fR determines where you want the \fIContent-(architecture)\fR +\fIdatabase\fR\|(s) put. (see --Packages). +.PP +\fB--onec\fR will download only one Contents-arch per +distribution/architecture specified on the commandline or by default. +.PP +\fB--Release_only\fR will download only the Release data for the +\fIswimz.list\fR or particular \fIPackage(s)\fR mentioned on the command line. +.PP +\fB--dists\fR will only find the distribution which corresponds to the +argument provided this option. +.PP +\fB--arch\fR will only find the architecture which corresponds +to the argument provided this option. The different architecture needs to +be specified in swimz.list with a hyphen and the architecture appended to +deb (deb-(arch)). +.Sh "B. downloading the important databases with apt, and maintenance options." +usage: \fBswim --apt\fR +.PP +options: \fB[--update] [--clean] [--autoclean] [--check]\fR +.PP +Please read \*(L"\fBA. downloading the important databases with --ftp\fR\*(R" for +more information. +.PP +\fB--update\fR calls \fBapt\fR to download the Packages databases. +.PP +\fB--clean\fR is a call to an \fBapt\fR option to remove any packages stored in +\fBapt's\fR storage area for downloaded packages. The default for this +storage area is \fI/var/cache/apt/arhives\fR +.PP +\fB--autoclean\fR will only clean out packages which are not +found in apt's cache. + +.PP +\fB--check\fR tests and updates apt's cache. +.SH "MAKING NOT\-INSTALLED DATABASES" +usage: \fBswim --initndb\fR + \fBswim --ndb\fR + \fBswim --rebuildndb\fR +.PP +options: \fB[--Contents\fR <\fBtarget|FDBtarget|DF|FDBDF\fR>\fB]\fR + \fB[--main] [--contrib] [--non-free] [--non-us]\fR + \fB[--arch\fR <\fBarchitecture\fR>\fB]\fR \fB[--dists\fR <\fBdistribution\fR>\fB]\fR + \fB[--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB] [--alt]\fR + \fB[--split_data\fR <\fBlines\fR>\fB] [\-v] [--cron]\fR + \fB[targets|APT|DF]\fR +.Sh "\s-1OVERVIEW\s0" +The \fBnot-installed database\fR provides swim with many capabilities like +the searching, and querying of packages which do not actually exist on the +live filesystem, as well as the ability to seamlessly install packages +while searching or quering, or the ability to fetch the packages source +code. The \fIvirtual filesystem\fR is optional, but it is highly recommended. +These two major mode options set up these databases, after determining the +level of interaction which you want. +.PP +Whenever \fBswim\fR makes databases it thinks only in terms of one +distribution and one architecture. This keeps things logical. \fBswim\fR +does have the ability to take Packages files with multiple architectures, +and distributions, and to extract information for one distribution and one +archictecture to make its databases. This could provide interesting +information from dumps from \fBapt\fR (\f(CWapt-cache dumpavail\fR). +.PP +\fB--initndb\fR creates the initial not-installed databases for a particular +architecture and distribution, and \fB--rebuildndb\fR remakes the +not-installed databases for that same architecure and distribution. If not +otherwise specified \fBswim\fR \fIwill use the values\fR it finds in \fIswimrc\fR +to determine what architecture and distribution you want to use to make +\fBswim's\fR databases. Otherwise... +.Sh "\s-1OPTIONS\s0" +\fB--arch\fR allows an argument to override the \fBarchitecture\fR found in +\fIswimrc\fR. +.PP +\fB--dists\fR allows an argument to override the \fBdistribution\fR found in +\fIswimrc\fR. +.PP +\fB--alt\fR is used for a distribution with a Debian archival +structure, but which has a different name. This allows for alternative +distributions. +.PP +When \fB\s-1APT\s0\fR or \fB\s-1DF\s0\fR are provided as arguments (see below), by default the +\fIPackages\fR which pertain to the sections found in \fIswimrc\fR will be +shown. If you only want certain sections you may specify them on the +command line. If you are not using \fB\s-1APT\s0\fR or \fB\s-1DF\s0\fR, it is a good idea to +make sure that either the sections found in \fIswimrc\fR or the sections you +put on the command line match the \fIPackages\fR you a targetting because +this is much more effecient. +.PP +\fB--main\fR will override the sections found in \fIswimrc\fR, and will use this +section. +.PP +\fB--contrib\fR will override the sections found in \fIswimrc\fR, and will use +this section +.PP +\fB--non-free\fR will override the sections found in \fIswimrc\fR, and will use +this section +.PP +\fB--non-us\fR will override the sections found in \fIswimrc\fR, and will use +this section +.PP +Global arguments \fBtargets|\s-1APT\s0|\s-1DF\s0\fR must be used with either of these two +major modes to find the \fIPackages\fR databases. targets can be a full path +to one or a set of \fIPackages\fR. \fB\s-1APT\s0\fR will use the \fIPackages\fR found in +\fI/var/state/apt/lists\fR, and \fB\s-1DF\s0\fR will use the Packages found in the +default directory for \fBswim\fR (see \f(CW--ftp\fR). If you use either \fB\s-1APT\s0\fR or +\fB\s-1DF\s0\fR you will be given an \fBinterface\fR which allows you to choose one +\fIPackages\fR database for each section you would like to use from the +various sites. This \fBinterface\fR shows the \fBsite\fR, \fBdate\fR, \fBsize\fR and +\fBRelease version\fR for each \fIPackages\fR. +.PP +\fB--cron\fR allows you to override the \fBinterface\fR produced when \fB\s-1APT\s0\fR or +\fB\s-1DF\s0\fR is provided as an argument. This is useful if you want to automate +the database making process. \fB--cron\fR will choose the newest +\fIdatabase\fR\|(s), if cron notices that the Release version has changed, cron +will not proceed, but will provide a warning instead. This allows you to +make the appropriate changes and choices. +.PP +\fB--Contents\fR can be give one of four arguments: +.PP +\fB1).\fR If you have a \fIContents-(architecture)\fR database in a target +location you know about you may provide a path to the location. The +\fIContents\fR database can be compressed. +.PP +\fB2).\fR If you prepend the path with the letters \fB\s-1FDB\s0\fR (meaning flat +database) when the databases for swim are made, instead of using the +Contents database to make: +.PP +.Vb 3 +\& nfileindex-arch-dists.deb +\& nsearchindex-arch-dists.deb +\& ndirindex-arch-dists.deb +.Ve +only the \fIncontentsindex-arch-dists.deb.gz\fR database will be made which +allows the ability to view file/dir listing for not-installed packages, +but does not provide the virtual file system or powersearch capabilities +which the other databases would have provided. +.PP +\fB3).\fR The argument \fB\s-1DF\s0\fR may be used if you have used \fB--ftp\fR with the +\fB\s-1DF\s0\fR argument to the option \fB--Contents\fR (see \f(CW--ftp\fR). In this case +it is assumed you are also using global arguments \fB\s-1DF\s0\fR or \fB\s-1APT\s0\fR for the +Packages databases. This will give you an \fBinterface\fR (if --cron isn't +used) allowing you to choose one \fIContents\fR database for the particular +distribution you want to make the databases for. +.PP +\fB4).\fR \fB\s-1FDB\s0\fR does the same exact thing with \fB\s-1DF\s0\fR as it does with the +before mentioned \fBFDBtarget\fR, and provides the \fBinterface\fR. +.PP +\fB\-v\fR will only work if you have dpkg installed. It allows swim to verify +\fBswim's\fR own built-in version comparison function with \fBdpkg's version +comparison function\fR. This is good for debugging purposes, and produces a +report called \fI.version_compare\fR in the same location that \fBswim's\fR +databases are made. +.PP +\fB--split_data\fR is only advantageous if \fB--Contents\fR is being used. See +\fB--initdb\fR for more information about the \fB--split_data\fR option. +.PP +See \f(CW--initdb\fR for options \f(CW--dbpath\fR and \f(CW--root\fR. +.Sh "\s-1UPDATING\s0" +\fB--ndb\fR has the same options as --initndb and --rebuildndb except for +--split_data. It also has a new option \fB--nue\fR which will never have to +be used unless the experimental distribution or non-us section are found +in Contents (which presently isn't the case). \fB--check\fR prints out the +changes to \s-1STDERR\s0, and the total to \s-1STDOUT\s0 without proceeding with the +update. \fB--status_only\fR can be used after a new package has been +installed to update the status, after which \-qni and \-qi will correlate +properly. +.Sh "\s-1REBUILDING\s0 \s-1THE\s0 \s-1SEARCH\s0 " +\fB--rebuildflatndb\fR serves the same purpose that --rebuildflatdb serves. +.Sh "\s-1FILES\s0" +Databases and reports which are made (arch = architecture dists = +distribution): +.PP +.Vb 8 +\& npackages-arch-dists.deb +\& nfileindex-arch-dists.deb requires --Contents +\& nstatusindex-arch-dists.deb +\& ngroupindex-arch-dists.deb +\& nsearchindex-arch-dists.deb +\& ndirindex-arch-dists.deb +\& ncontenstsindex-arch-dists.deb.gz requires --Contents +\& .packagesdiff-arch-dists.deb requires --Contents +.Ve +.SH "PREPARING YOUR INSTALLATION FOR APT" +usage: \fBswim --audit\fR + \fBswim --status\fR + \fBswim \-C\fR +.PP +If you are using \fBapt\fR with \fBswim\fR, and this is the first time you are +using it with your installation, check your live installation with this +major mode. This is a call to \fBdpkg \-C (--audit)\fR, and will show any +packages which are not properly configured or installed. If you get any +output, make corrections. The goal is to get absolutely no output +whatsoever because it is under these conditions that apt will work +properly. See the \fB--purge\fR, \fB\-r\fR, \fB--remove\fR options for \fB\-q\fR to +remove the offending packages. You may have to remove the package by hand +under unusual situations like when it is not just dependencies (see \f(CW-T\fR) +between packages keeping the package from being removed perhaps due to a +broken script (see \f(CW--scripts\fR). In an extreme case you could manually +remove the entry for this package from the \fI/var/lib/dpkg/status\fR +database, and hunt down and remove all the files associated with the +package with \fBswim's \-l\fR option. When you are done if you still want +some of the packages you removed, use \fBapt\fR to reinstall them with +\fBswim's \-xyz\fR option. Also, \fBapt\fR provides its own built-in method to +clean up your system, and will provide instructions, but you still may +have to do some of the cleaning yourself as discussed above. +.SH "QUERYING THE INSTALLED AND NOT\-INSTALLED DATABASES" +usage: \fBswim \-q [\-fpgn --dir] [targets | \-S]\fR + \fBswim --query [\-fpgn --dir] [targets | \-S]\fR + \fBswim \-qa || swim --query \-a\fR +.PP +options: \fB[--total \-t] [\-i] [\-l ?\fR <\fB[--df]\fR>\fB] [\-d] [\-c]\fR + \fB[--scripts] [--preinst] [--postinst] [--prerm]\fR + \fB[--postrm] [\-v] [--dbpath\fR <\fBdir\fR>\fB] [--menu \-m]\fR + \fB[--shlibs] [\-T] [--pre_depends] [--depends\fR + \fB[--recommends] [--suggests] [--conflicts]\fR + \fB[--replaces] [--provides] [--md5sum]]\fR + \fB[--copyright] [--changelog] [--allgroups]\fR + \fB[--arch\fR <\fBarchitecture\fR>\fB] [--dists\fR <\fBdistribution\fR>\fB]\fR + \fB[--ftp ? --source | --source_only ?\fR <\fB[--diff]\fR>\fB]\fR + \fB[--stdin] [--extract\fR <\fBALL|archive|PWD!archive\fR>\fB]\fR + \fB[\-xyrz --remove\fR <\fB[--nz]\fR>\fB] [--purge] [--apt2df]\fR + \fB[--df2apt] [--root\fR <\fBdir\fR>\fB]\fR +.PP +global arguments: \fB[targets | \-S ?\fR <\fB\ed{1,}\fR>\fB]\fR +.PP +Quering almost always involves using \fB\-q or --query\fR with zero or one or +a combination of the \fBminor mode options\fR (package specification +options), and one or more (only one for \f(CW-g\fR) targets specific to the +minor mode, or the results of a search (\f(CW-S\fR). [\f(CW-S\fR can be provided a +numerical argument pertaining to the past history.] This can be combined +with one or more options. The one exception is \*(L"\fBswim \-q --allgroups\fR\*(R". +.PP +\fB--query or \-q\fR can be used by itself or with \fB\-n\fR to query known +package names or package names with versions. \*(L"\fBswim \-q test1 +test2_0.3-1\fR\*(R" would produce the output: +.PP +.Vb 2 +\& test1_1.0-2 +\& test2_0.3-1 +.Ve +.Sh "\s-1MINOR\s0 \s-1MODES\s0" +\fB\-n\fR is the minor mode option to access the \fInot-installed system\fR, it +can be combined with the minor mode options \fB\-a\fR, \fB\-g\fR, \fB\-f\fR, or it can +be used by itself. +.PP +\fB\-a\fR allows \fIevery package\fR on an installed or not-installed (\fB\-n\fR) +system to be queried. \*(L"\fBswim \-qan\fR\*(R" will show all the package names with +versions for the not-installed system +.PP +\fB\-f\fR allows \fIfiles or directories\fR to be queried, when used without any +options the package name with version is shown. \fB--dir\fR will only query +directories, this is useful if you are not sure whether what you are +quering is a directory or a file. When a directory is queried, swim shows +all packages which exist below the queried directory. \*(L"\fBswim \-qf /\fR\*(R" is +exactly the same as \*(L"\fBswim \-qa\fR\*(R". Hint: \*(L"\fBswim \-qf .\fR\*(R" and \*(L"\fBswim \-qf +*\fR\*(R" are quite different, the first shows all packages which exist below +the current directory, and the second will show the package which each +file in the current directory comes from. + +\fB\-g\fR will query a \fIgroup\fR (also called a section, see \f(CW-i\fR)) of +packages. Groups represent subjects which packages with similiar +characteristics are catagorized by. To view all the groups found in an +installed or not-installed system use \*(L"\fBswim \-q --allgroups\fR\*(R" or \*(L"\fBswim +\-qn --allgroups\fR\*(R". \*(L"\fBswim \-qg hamradio\fR\*(R" or \*(L"\fBswim \-qng hamradio\fR\*(R" +shows all the package names for the hamradio group. +.PP +\fB\-p\fR is used to query a \fIDebian package\fR, these packages are +distinguished by their \*(L"deb\*(R" ending, but swim can tell whether a file is a +debian package even without the ending. Called without any options the +package name with version will be shown. +.Sh "\s-1SPECIFYING\s0 \s-1THE\s0 \s-1DATABASES\s0 \s-1TO\s0 \s-1USE\s0" +\fB--dists\fR will use the databases for the argument given, otherwise the +databases pertaining to the value found in swimrc will be used. +.PP +\fB--arch\fR will use the databases for the argument given, otherwise the +databases pertaining to the value found in swimrc will be used. +.PP +Example: \fBswim \-qat --arch hurd-i386 --dists unstable\fR +.PP +Assuming these databases exist this will show all packages and their +versions for the unstable distribution and architecture hurd-i386 even if +the values in \fIswimrc\fR are i386 and stable. +.PP +see \f(CW--ftp\fR and \f(CW--initndb\fR for more information about the databases. +.Sh "\s-1OPTIONS\s0" +\fB--total or \-t\fR are \fIused to override the output suppressor\fR. The +output suppressor will not show output if a certain number of packages is +exceeded, instead it will show the number of packages you are querying. +This is useful for two reasons, first, knowing the number of packages you +are quering can be very informative, second, it gives you a chance to add +to the command line a pipe to a pager, ex: \*(L"\fBswim \-qat | less\fR\*(R". You can +set the number that the output suppressor works at as high or low as you +want in the \fIswimrc(8)\fR file. By design the \fB\-t\fR option will have to be +used if the \fB\-i\fR option is used and more than one package is being +queried. This option can also be used to alter the output of the script +related options (see \f(CW--script\fR). +.PP +\fB\-i\fR provides \fIinformation\fR about each package being queried. The +format differs slightly for the installed packages versus the +not-installed packages. See \s-1FORMAT\s0: +.PP +\fB\-l\fR provides a listing of the files associated with a package. If the +option \fB--df\fR is provided as an argument, all the directories associated +with package will be shown. It is important to remember that many +packages provide directories which become important to them after they are +installed, so the option \fB--df\fR often provides necessary information +which \fB\-l\fR called by itself would have not. +.PP +\fB\-d\fR shows the documentation which the package provides found in +\fI/usr/doc/*\fR, \fI/usr/man/*\fR, \fI/usr/info/*\fR. Other documentation which +the package may provide in a non-standard location will not be shown. +\fB\-d\fR takes precedence over \fB\-l\fR, so if \fB\-l\fR is used on the command line +with \fB\-d\fR, only the output for \fB\-d\fR will be shown. +.PP +\fB\-v\fR is a special option which works only with the minor mode \fB\-p\fR. It +can be used with \fB\-l\fR, \fB--df\fR, \fB\-d\fR, to show the packages files and/or +directories in long format (\f(CWls -l\fR). +.PP +\fB\-c\fR will show the configuration files packages use. If the package does +not have a configuration file then nothing will be shown. The output will +show the file and its path indented one space with the \fB\s-1MD5\s0 checksum\fR. +This will not work with \fB\-n\fR. +.PP +\fB--scripts\fR shows all scripts associated with a package with the name of +the script presented before each script in this way +\fB#####scriptname######\fR. If the scripts are called individually by using +the script options \fB--preinst\fR, \fB--postinst\fR, \fB--prerm\fR, or \fB--postrm\fR +no title is shown, this is nice for writing to a file. If \fB\-t\fR is used +with the individual script options a title will be shown, this makes sense +because normally only individual packages would be queried to write a +script to a file, and \fB\-t\fR wouldn't be used in this situation. Scripts +are the soul of Debianized packages allowing packages to be installed, +configured, and removed seamlessly and cleanly under all kinds of +conditions. These options do no work with \fB\-n\fR. +.PP +\fB--menu or \-m\fR is used to view menufiles which belong to various +packages. If the package does not have a menufile nothing will be shown. +This option can be useful in troubleshooting a menu entry which does not +seem to work, or in finding out where the menu entry is. \fIJoost +Witteveen's Debian menu system\fR is a centralized program which interacts +with all kinds of menus. \fIPlease read the documentation\fR \*(L"\fBswim \-qd +menu\fR\*(R" which comes with the menu package to find out more. This will not +work with \fB\-n\fR. +.PP +\fB--shlibs\fR shows a list of shared libraries certain packages supply. The +\fIDebian Packaging Manual\fR (packaging-manual) provides detailed +information about the format of a shlibs file. This will not work with +\fB\-n\fR. +.PP +\fB--copyright\fR does a case insensitive search for copy or license in the +\fI/usr/doc/packagename\fR directory. This should show how the package +relates to \fIDebian's Policy Manual\fR. +.PP +\fB--changelog\fR searches for any files in \fI/usr/doc/packagename\fR which +look like changelogs. Debian packages always have a \fIMaintainer's\fR +changelog for the package. There may be a separate changelog kept by the +author of the program. +.Sh "\s-1PACKAGE\s0 \s-1RELATIONSHIPS\s0" +\fB\-T\fR shows all the package relationships of packages. Individual package +relationships can be viewed using \fB--pre_depends\fR, \fB--depends\fR, +\fB--recommends\fR, \fB--suggests\fR, \fB--replaces\fR, \fB--conflicts\fR or +\fB--provides\fR. Package relationships are the spirit of Debian packages, +here is a quick overview briefly reiterating what can be found in the +\fIDebian Packaging Manual\fR. \fIPackage Maintainers\fR set these +relationships in control file fields of the same name. +.Sh "Dependencies " +\fIPre-depends\fR \- means that the pre-depended package or packages must be +installed before the queried package can be installed. Most packages +which have pre-dependencies are usually essential and required packages. +.PP +\fIDepends\fR \- declares an absolute dependency to another package or +packages either \fIreal or virtual\fR. The queried package cannot function +without this other package. +.PP +\fIRecommends\fR \- declares a strong, but not absolute dependency to another +package or packages either \fIreal or virtual\fR. You would usually find the +recommended package together with the queried package in a normal +installation. +.PP +\fISuggests\fR \- can be one or more packages either \fIreal or virtual\fR which +would be useful to the queried package, but are not necessary. +.Sh "Alternative Packages" +\fIConflicts\fR \- is a package or packages either \fIreal or virtual\fR +which would cause problems with the queried package, and would not be +allowed to be installed while the queried package was installed. +.Sh "Overwriting files and Replacing Packages " +\fIReplaces\fR \- allows the queried package to replace another package or +packages by overwriting their files, after which the previous package +would be considered to have disappeared. Essentially this allows the +queried package to take over the package or packages. In a situation +where there was a Conflict between the queried package and these packages +this field would help determine which packages should be removed. +.Sh "Virtual Packages " +\fIProvides\fR \- declares a virtual package which may be mentioned in +\fIDepends\fR, \fIRecommends\fR, \fISuggests\fR, or \fIConflicts\fR. \fIVirtual +packages\fR allow one or more packages to share the same name of another +package, which means if the queried package has a reference to a virtual +package in one of the before mentioned package relationship fields, then +whatever packages provide the virtual package are also being listed. + +\fB--md5sum\fR checks \fB\s-1MD5\s0 checksums\fR. It can be used with \fB\-l\fR, \fB\-d\fR, +\fB\-c\fR, or \fB\-p\fR. If there are checksums available the md5sum result will +be either \fB\s-1OK\s0\fR, \fB\s-1FAILED\s0\fR, or \fB\s-1MISSING\s0\fR. \fB\s-1MISSING\s0\fR means that although +a checksum exists, the file can not be found. The result is put after the +file and its path and the \fB\s-1MD5\s0 checksum\fR or the package name and version +and the \fB\s-1MD5\s0 checksum\fR. +.Sh "\s-1FORMAT\s0" +\fB1). Installed system\fR +.PP +.Vb 8 +\& Package: name Status: hold ok installed +\& Version: 1.1-1 Essential: no +\& Section: namers Priority: extra +\& Installed-Size: 10 Source: generatename (2.0-1) +\& Maintainer: name +\& Description: hostname maker +\& A nice way to figure out a hostname nobody +\& else has. +.Ve +\fB2) Not-installed system\fR +.PP +.Vb 10 +\& Package: name Status: r> hold ok installed (1.1-1) +\& Version: 1.1-2 Essential: no +\& Section: names Priority: extra +\& Installed-Size: 11 Source: generatename (2.0-1) +\& Size: 43000 Architecture: i386 +\& Distribution: experimental +\& Maintainer: name +\& Description: hostname maker +\& A nice way to figure out a hostname nobody +\& else has. +.Ve +There are several things to point out. The difference between the two +outputs relates to the addition of the Distribution, Size, and +Architecture fields for the not-installed query. Installed-Size is how +many kilobytes the package will occupy when it is unpacked, whereas Size +is the size in bytes of the package. +.Sh "\s-1STATUS\s0 \s-1FIELD\s0 " +The Status field provides the installation status of the package, this +holds true for the not-installed query as well. In a sense, the +not-installed database isn't always not-installed. If the not-installed +package is actually already installed, and the version numbers are exactly +the same, then the status will be the same for either query. If the +not-installed package is not installed then the status will be +\*(L"not-installed\*(R". In cases where the not-installed package is already +installed, swim uses it's comparison function to figure out whether it is +a newer of older package which is installed. In the above example, swim +realizes the same package is installed, and only the debian-revision has +changed, hence the only difference is that the revision number is greater +\*(L"r>\*(R" for the not-installed package. When only the debian-revision has +changed it can safely be assumed that the author (creator, programmer) of +the same program has not made any changes to the same program, but the +Debian maintainer has made a change to an aspect of the package like a +change in the script the package uses to properly install. You may have +also noticed that the status field shows the version number of the +installed package enclosed in parenthesis. +.Sh "\s-1SOURCE\s0 \s-1FIELD\s0" +The Source field is present in these examples, but the Source field will +not always be present for packages. In cases where the name of the source +package is the same as the the name found in the Package field, and the +version number of the source package is also the same as found in the +Version field, then there will be no Source field. In the above examples +there is a Source field. In this case name was probably one of many +packages generated from the source package called generatename. In this +particular example generatename also has its own unique version number +2.0-1 enclosed in parentheses, if no version number had been mentioned +then the source package would have the same version number as found in the +Version field. +.Sh "\s-1SECTION\s0 \s-1AND\s0 \s-1PRIORITY\s0 " +Section shows the subject which a package is categorized with (see \f(CW-g\fR). +Priority shows how important the package is to have installed. In the +case of the not-installed databases the information for these fields is +almost always available from the Packages databases, but this is not +always the case for Debian packages. For packages which do no provide +this information swim will do its best to fill in the blanks from +information found in the installed and not-installed databases. If proper +information can not be found it will be indicated as \*(L"unavailable\*(R" or +\*(L"unknown.\*(R" Unavailable would indicate that information about the package +exists, but it is from a different version (includes debian-revision), and +no information exists for this version. Unknown means no similiar package +exists, and there is absolutely no information about this package in the +databases. +.Sh "\s-1DEBIAN\s0 \s-1PACKAGE\s0 \s-1OUTPUT\s0" +When a Debian package is queried using the \fB\-p\fR option you will get +output like the first example shows, the status field is also calculated. +.Sh "\s-1VIRTUAL\s0 \s-1OPTIONS\s0" +.Sh "\s-1FTP\s0 " +For ftp capabilities swim uses the \fIswimz.list\fR to determine which sites +it will check for the requested packages. The first site which fills the +request will be used, otherwise \fBswim\fR will go through all the sites +avoiding repeats, and if no sites can fill the request, \fBswim\fR will +either quit or proceed on to check for another request. +.PP +\fB--ftp\fR allows the queried package, its source package, or just the +source package diff to be downloaded while being queried. This is refered +to as virtual downloading because the quering and the downloading are +seamless as though the package already exists locally. This has to be +used with the option \fB\-n\fR because packages which which are not part of +the not-installed database are considered to already have been downloaded. +Packages which are already installed can be downloaded or their source +retrieved by setting up a database which corresponds to these packages; if +the installed packages belong to the stable distribution, set-up the +not-installed stable databases. +.PP +Packages or source code are placed in an area below the default directory +mirroring the remote directory they were downloaded from after their size +and modification times are checked for correct values. This area is +called the \fB\s-1DF\s0\fR directory, and although this directory mirrors remote +directories, it is not an exact mirror, but specific to the requirements +of swim because code names for Release versions are not taken into +account. For real mirroring capabilities there exist many excellent +programs. If a package has a \fB\s-1MD5\s0 checksum\fR, \fB--md5sum\fR will +automatically be run and the value shown. Regardless of whether or not +the md5sum check is \fB\s-1OK\s0\fR or not, the package will still be put in the +\fB\s-1DF\s0\fR directory to allow the package to be looked at, so watch the output +from \fB--ftp\fR to check for \fB\s-1FAILED\s0 md5sums\fR. +.PP +Packages or source code packages will not be downloaded again if they are +found in the \fB\s-1DF\s0\fR directory unless their \fIupstream-version\fR has changed +in the not-installed database, if the packages are not in the \s-1DF\s0 directory +and the remote \fIupstream-version\fR is different than the not-installed +\fIupstream-version\fR then the packages will not be downloaded until the +not-installed database is updated or rebuilt to reflect the version +change. Changes in the package's \fIupstream-version\fR indicates that the +\fIauthor\fR\|(s) of the program have made changes to the computer code for the +program contained in the package or the source code package. On the other +hand, swim will check for a \fIdebian-revision\fR change at the remote site +if the package can not immediately be found. If the package's +\fIdebian-revision\fR has changed and the package does not exist locally in +the \fB\s-1DF\s0\fR directory, it will be downloaded. This is a nice feature, +especially for the unstable distribution, because it tends to extend the +time needed before the not-installed database has to be updated or rebuilt +to match the changes at remote sites. +.PP +\fB--source\fR is used with \fB--ftp\fR to download the source code package. +\fB--source_only\fR will download the source code package without the deb +package. \fISource packages consist of three files\fR. The \fIsource control +file\fR which ends in \*(L"dsc\*(R", the \fIoriginal source archive\fR which is a +compressed tar file, and the \fIunified context diff\fR showing the changes +necessary to make the original source into Debian source. The diff can be +downloaded by itself if \fB--diff\fR is provided as an argument to \fB--source +or --source_only\fR. +.PP +For \fBapt\fR users: \fBapt\fR allows packages to be downloaded, but if more +than one package is required for the package relationships to be proper, +\fBapt\fR will download all these packages. \fB--ftp\fR allows specific +packages to be downloaded, packages from other architectures, and source +packages to be downloaded, here lies the advantage of this option over +using \fB\-xyz --nz\fR (see below). If a particular package has been +dowloaded into the \fB\s-1DF\s0\fR directory and it is needed by \fBapt\fR for +installation, simply copy or move the package from the \fB\s-1DF\s0\fR directory to +\fI/var/cache/apt/archives\fR before running \fBapt\fR, and the package will not +be downloaded by \fBapt\fR again; future versions of \fBswim\fR will have an +option to automatically accomplish this (see \f(CW--df2apt\fR). +.Sh "\s-1APT\s0" +apt-\fIget\fR\|(8) is a nice package relationship checker from the \fBapt\fR package +which figures out what needs to be done to properly install a package or +packages when one or more package names are provided to it. \fBapt-get\fR +will get all packages which are needed using a variety of methods, and +then \fBapt-get\fR interacts with \fBdpkg\fR in a way which allows for a +successful installation. +.PP +\fB\-xyrz, --remove and --nz\fR can be used if \fBapt-get\fR from the \fBapt\fR +package is installed. These options allow for what is refered to as +virtual installation/removal. It is prudent to always test what will +happen by using the \fB\-x\fR option alone before actually proceeding with the +installation with the \fB\-z\fR option. \fB\-x\fR will actually simulate what +would happen in an installation, showing which and how many packages will +be changed, which and how many new packages will need to be installed, +which and how many packages will need to be removed, any conflicts, and +what needs to be configured. \fB\-y\fR will automatically answer yes to any +prompts \fBapt-get\fR may produce allowing \fBapt-get\fR to run +non-interactively. \fB\-z\fR as mentioned before actually proceeds with the +installation using \fBdpkg\fR after the \fBapt-get\fR gets the packages. You +can append a minus sign to a package name to cause it to be removed. +\fB--nz\fR when used as an optional argument with \fB\-xz or \-xyz\fR will only +download the packages into \fI/var/cache/apt/archives\fR or into whatever +directory you configured for holding archives for \fBapt\fR. +.PP +\fB\s-1IMPORTANT\s0\fR: \fBapt\fR makes it so easy to make changes to your +installation that it is highly recommended to do your research with swim +first. This can be done by checking package relationships, file/dir +listings, comparing the not-installed package to an installed package if +such exists, checking \fB--md5sum\fR and \fB\-c\fR for the installed package, and +checking the Source field by running a \fB--search\fR (see below) to check to +see how the source package has been split into binary packages for the +not-installed package versus an installed package if such exists. +Ofcourse, there are many other things you could look at, and you can +always do your research after the fact. Presently \fB--db\fR is run only by +hand, so you can check the old state after an installation if you have not +already run \fB--db\fR, yourself. +.Sh "\s-1REMOVING\s0 \s-1AN\s0 \s-1INSTALLED\s0 \s-1PACKAGE\s0 " +\fB--purge\fR uses \fBdpkg\fR to remove an installed package or packages and the +configuration files as shown with \*(L"\fBswim \-qc packagename\fR\*(R". +.PP +\fB\-r or --remove\fR removes an installed package or packages with \fBapt\fR, +but not the configuration files as shown with \*(L"\fBswim \-qc packagename\fR\*(R". +You may also append a plus sign to a package name to cause it to be +installed. This option is used with \-x or \-\fIx\fR\|(y)z. +.Sh "\s-1STDIN\s0 " +\fB--stdin\fR works with either \fB--ftp\fR, \fB\-x\fR, \fB\-xyz\fR, \fB\-xz\fR, \fB--purge\fR, +\fB\-r\fR, or \fB--remove\fR. +.PP +\fB--stdin\fR provides the \fIreadline capabilities\fR commonly found in shells +allowing you to edit what is on the command line. You can edit the command +line, press enter and then recall the history, and make more changes, or +\fItype in exit to process the changed or unchanged command line\fR. To find +out more about what readline commands your shell supports please read the +man pages which apply to your shell. Information for the bash shell can +be found in \fIbash\fR\|(1) under the title \*(L"\fBReadline Command Names\fR\*(R". +.PP +Example: \*(L"\fBswim \-qgnx --stdin hamradio\fR\*(R" will list all the packages from +the not-installed hamradio group on the command line, this list can be +edited then submitted to \fBapt-get\fR for a simulated installation. Another +instance of \fBswim\fR can be run at the same time, perhaps \*(L"\fBswim \-qinTg +hamradio\fR\*(R" to help in making editing decisions for \fB--stdin\fR. +.Sh "\s-1PACKAGE\s0 \s-1MANIPULATION\s0" +\fB--extract\fR only works with the \fBminor mode \-p\fR to extract parts or all +of a Debian package. If the \fBargument \s-1ALL\s0\fR is provided then \fIeverything +found in the package will be extracted\fR below the current directory in the +exact directories found in the package. A particular \fIfile may be +extracted in its exact location\fR below the current directory by \fIentering +the exact path for the file\fR as shown by \*(L"\fBswim \-qpl\fR\*(R" or \*(L"\fBswim \-qpd\fR\*(R" +as the argument. Alternativily, a \fIfile may be extracted in the current +directory\fR regardless of its proper location by \fIprepending \s-1PWD\s0\e! before +the path\fR shown by \*(L"\fBswim \-qpl\fR\*(R" or \*(L"\fBswim \-qpd\fR\*(R". Notice the backslash +before the exclamation point, this is because shells consider ! a special +character, so it has to be backslashed so that the shell knows that it is +not such a special character. Example: \*(L"\fBswim \-qpi --extract +\s-1PWD\s0\e!usr/bin/name --scripts name_1.1-2.deb\fR\*(R" will extract the binary name +in the current directory from the name package, show information for the +name package, and show any scripts for the name package. +.Sh "\s-1DATABASE\s0 \s-1LOCATIONS\s0" +\fB--dbpath\fR can be specified as an alternative location for where the +databases would be found. The default location is \*(L"\fI/var/lib/dpkg\fR\*(R". An +argument like \*(L"\fI/otherstuff\fR\*(R" can be provided, and then the databases +would be found here instead. +.PP +\fB--root\fR allows a database to be found for a Debian distribution +installed on a different partition. If the distribution is mounted on +\fI/New_Debian\fR, \*(L"\fI/New_Debian\fR\*(R" would be the argument to root. The +databases would be found for the Debian distribution installed on the +\*(L"\fI/New_Debian\fR\*(R" partition. +.PP +\fB--dbpath and --root\fR can be used together. Given the previous two +examples, the databases would be found on \*(L"\fI/New_Debian/otherstuff\fR\*(R", +assuming \*(L"\fI/New_Debian/otherstuff\fR\*(R" actually existed. +.SH "UPGRADING WITH APT" +usage: \fBswim --apt\fR +.PP +options: \fB[\-xyz] [--upgrade] [--dist_upgrade]\fR +.PP +\fBapt-get\fR provides powerful methods to change an installion. When these +methods are called using \fB--apt\fR, \fBswim\fR will not allow you to proceed +until you are absolutely sure this is what you want to do. Before using +these methods do a \*(L"\fBswim --apt --update\fR\*(R" so that \fBapt-get\fR knows the +newest versions of available packages. This major mode requires a +combination of \fB\-x\fR, \fB\-xz\fR or \fB\-xyz\fR to be used along with either +\fB--upgrade\fR or \fB--dist_upgrade\fR. \fB\-x\fR used alone will simulate what +would happen if \fB\-xz or \-xyz\fR were used (also see \f(CW-xyz\fR above). +.PP +\fB--upgrade\fR is somewhat similiar to doing \*(L"\fBswim \-qatxz\fR\*(R" except that it +is a more intelligent method because \fBapt\fR does some behind the scene +calculations in regards to package relationships, in fact the \*(L"\fBswim +\-qatxz\fR\*(R" approach will provide totally different results, or maybe these +were the results you really wanted. \*(L"\fBswim --apt --upgrade \-xz\fR\*(R" is the +prefered, proper, and built-in way provided by \fBapt-get\fR to install the +newest versions for all packages installed on your system. This method +will not install any newer versions of packages which would change the +install status of other packages. Note: It is not recommended to combine +the query option \fB\-a\fR with \fB\-xz or \-xyz\fR, but combining the query option +\fB\-a\fR just with \fB\-x\fR can be educational. +.PP +\fB--dist_upgrade\fR combines an \fB--upgrade\fR with the installation of +packages which are not installed. This method carefully examines +dependencies, and resolves conflicts, and given these factors it will +upgrade the most important packages before considering the installation of +less important packages. Less important packages will be installed only +if there are not any conflicts. +.SH "SEARCHING" +usage: \fBswim --search ? (--research || --refinesearch)\fR + \fBswim --powersearch ? (--research || --refinesearch)\fR + \fBswim --ps ? (--research || --refinesearch)\fR + <\fBpattern(s)\fR> + +options: \fB[\-g] [\-n] [--dbpath\fR <\fBdir\fR>\fB] [--root\fR <\fBdir\fR>\fB]\fR + \fB[--arch\fR <\fBarchitecture\fR>\fB] [--dists\fR <\fBdistribution\fR>\fB]\fR + \fB[--ftp ? --source | --source_only --diff]\fR + \fB[\-xyrz --remove ?\fR <\fB[--nz]\fR>\fB] [--stdin] [--apt2df]\fR + \fB[--no] [--df2apt] [--purge] [\fR\fB\ed{1,}\fR\fB]\fR + + \fB[--dir]\fR and no \fB[\-g]\fR for \fB--powersearch or --ps\fR +.Sh "\s-1OVERVIEW\s0" +\fBswim\fR provides two major types of searches. A search with \fB--search\fR +\fIsearches package information\fR, and a search with \fB--powersearch or +--ps\fR \fIsearches package information, and all files and/or directories +associated with each package\fR. +.PP +The results of either of these searches can be \fInarrowed down\fR by running +a test search with \fB--research\fR (this step can be skipped) and/or setting +the results in stone with \fB--refinesearch\fR. \fB--search\fR can be +\fInarrowed down\fR initially by specifying a particular \fIgroup\fR, and +\fB--powersearch\fR can be \fIexpanded\fR initially by specifying that +\fIdirectories\fR be searched as well as files. Both searches can \fIuse the +same virtual options\fR which the major mode \fB\-q or --query\fR use. +Generally, it is preferable to run a search, and then to provide the +results of a search (\fBusing \-S\fR) as an argument to \fB\-q or --query\fR; this +allows the results of a search to be queried. Every time a search is run +the results are appended to the history, past searches can be refined or +researched by providing the numerical argument pertaining to the history. +\ed{1,} is simply Perl notation meaning a number with one of more digits. +.PP +\fIPerl regexps\fR (see \fIperlre\fR\|(1p)) can be used to define the pattern +(string) provided as an argument to a search. Do not surround a pattern +in slashes, a slash is only used after all patterns and before the +\fImodifiers i and/or m\fR (swim supports these two modifiers). To search +for more than one pattern, patterns are separated with \fIbars (|)\fR. +Patterns may include \fIquatifiers, and metacharacters\fR, also found in +\fIegrep\fR\|(1). +.PP +If a search finds any packages which match the search, the package +information will be displayed as the package is found. The package will +only be shown once regardless of how many times it is found while the +search progresses. When the search is over the number of packages found is +shown. +.PP +\fB--search\fR provides a search of package information. This is similiar to +grepping \*(L"\fBswim \-qait\fR\*(R" or \*(L"\fBswim \-qaint\fR\*(R", but it is significantly +faster. A search can be performed on a particular group by using \fB\-g\fR +with a group as an argument +.PP +\fB--powersearch\fR is somewhat similiar to \*(L"\fBdpkg --search\fR\*(R" which searches +all files and directories on an installed system, but it combines +\fB--search\fR with the file and/or directory search, and can also be +performed on a not-installed system. A \fIpowersearch\fR is significantly +faster than the search which \fBdpkg\fR provides (even more so when \*(L"\f(CWswim +--ramdiskon --searchfile\fR\*(R" is used) and even more importantly provides a +logical output of the search (like \*(L"\f(CWswim -qi packagename\fR"). By default +a search of all directories is not performed because usually this is +redundant except in rare cases. To enable a search of all directories use +the \fB--dir\fR option. +.Sh "\s-1NARROWING\s0 A \s-1PREVIOUS\s0 \s-1SEARCH\s0" +\fB--research\fR allows the results of a previous search to be researched +without making the new results permanent. +.PP +\fB--refinesearch\fR allows the results of a previous search to be researched +while making the new results permanent. +.PP +\fB\ed{1,}\fR is a numerical argument to refine or research a +past search from the history. +.Sh "\s-1MINOR\s0 \s-1MODES\s0" +\fB\-n\fR allows the not-installed databases to be searched. These databases +will not exist if the not-installed databases were made with the \s-1FDB\s0 +argument (see \f(CW--initndb\fR). +.PP +\fB\-g\fR (see \f(CW--search\fR) +.Sh "\s-1OTHER\s0 \s-1OPTIONS\s0" +\fB--no\fR prevents normal output from a search, but does show how many +packages were found. +.PP +See the section \*(L"\fB\s-1SPECIFYING\s0 \s-1THE\s0 \s-1DATABASES\s0 \s-1TO\s0 \s-1USE\s0\fR\*(R" for options +\fB--arch\fR, \fB\-dists\fR. +.PP +See the section \*(L"\fB\s-1VIRTUAL\s0 \s-1OPTIONS\s0\fR\*(R" for options \fB--ftp\fR, +\fB--source\fR, \fB--source_only\fR, \fB--diff\fR, \fB\-xyz\fR, \fB--nz\fR, \fB--stdin\fR, +\fB--purge\fR, \fB--remove\fR, \fB\-r\fR. +.PP +See the section \*(L"\fB\s-1DATABASE\s0 \s-1LOCATIONS\s0\fR\*(R" for options \fB--dbpath\fR +and \fB--root\fR. +.Sh "\s-1EXAMPLES\s0" +\fBswim \-gn hamradio --search \*(L"radio network/i\*(R" --dbpath /test --arch alpha\fR +.PP +will search the alpha architecture not-installed system databases in the +/test directory for all package information from the hamradio group using +the case insensitive pattern \*(L"radio network\*(R". +.PP +\fBswim --powersearch dpkg \-xn\fR +.PP +will search the not-installed system databases for all package information +and all files using the case sensitive pattern dpkg, after which apt-get +will run a simulation of what would happen if it got and installed these +packages. +.SH "RAMDISK" +usage: \fBswim --ramdiskon\fR + \fBswim --ramdiskoff\fR +.PP +options: \fB[\-n] [--searchfile] [--arch\fR <\fBarchitecture\fR>\fB]\fR + \fB[--dists\fR <\fBdistribution\fR>\fB] [--dbpath] [--root]\fR + + no options for \fB--ramdiskoff\fR +.Sh "\s-1OVERVIEW\s0" +A ramdisk can be mounted below the default path or the specified path for +the databases in the dramdisk directory. The ramdisk is used to speed up +powersearchs and/or file/dir listings for packages from the not-installed +system. Also, this is useful if a computer system is heavily loaded with +other processes using the memory, and the ramdisk tends to persist even +after being unmounted. Modern kernels usually are built with support for +ramdisks. If these options do not work the kernel will need to be compiled +to support ramdisks by answering yes to \s-1RAM\s0 disk support. Perhaps the +best \fI\s-1README\s0\fR showing how to configure and compile a kernel comes with +the \fIkernel sources\fR in the main directory. +.PP +\fB--ramdiskon\fR allows a ramdisk to be created and mounted. If called with +\fB\-n\fR (not-installed databases) \fIncontents-arch-dists.deb.gz\fR will +automatically be written to the mounted ramdisk. This provides faster +file/dir listing capabilities when using \fB\-l\fR, \fB--df\fR, or \fB\-d\fR when +querying the not-installed system. Faster powersearch capabilities are +available through the option \fB--searchfile\fR. If the search databases are +not already compressed, they will now be compressed, this usually only +needs to be done once or until the databases are updated or rebuilt again. +The search databases will then be written to the mounted ramdisk. An +installed system only writes the search databases to the mounted ramdisk, +so always use --searchfile when specifying installed system databases. +.PP +\fB--ramdiskoff\fR is used to unmount the ramdisk. The not-installed +databases and the installed databases can not be simultaneously provided +by a mounted ramdisk, use \fB--ramdiskoff\fR first, then \fB--ramdiskon\fR to +install the other databases of choice. This also pertains to different +distributions and/or architectures. +.PP +See the section \*(L"\fB\s-1SPECIFYING\s0 \s-1THE\s0 \s-1DATABASES\s0 \s-1TO\s0 \s-1USE\s0\fR\*(R" for options +\fB--arch\fR, \fB\-dists\fR. +.PP +See the section \*(L"\fB\s-1DATABASE\s0 \s-1LOCATIONS\s0\fR\*(R" for options \fB--dbpath\fR +and \fB--root\fR. +.SH "FILES" +.PP +.Vb 1 +\& Configuration files: +.Ve +.Vb 2 +\& swimz.list +\& swimrc +.Ve +.SH "SEE ALSO" +\fIswimrc\fR\|(5), apt-\fIget\fR\|(8), sources.\fIlist\fR\|(5), \fIdpkg\fR\|(8) +.SH "BUGS" +Send directly to mttrader@access.mountain.net +.SH "AUTHOR" +Jonathan D. Rosenbaum +.SH "COPYRIGHT" +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +.rn }` '' +.IX Title "swim 8" +.IX Name "swim - package administration and research tool for Debian packages" + +.IX Header "NAME" + +.IX Header "SYNOPSIS" + +.IX Header "DESCRIPTION" + +.IX Header "COMMAND LINE OPTION SYNTAX" + +.IX Header "VERSION" + +.IX Header "HISTORY" + +.IX Header "MAKING INSTALLED SYSTEM DATABASES" + +.IX Subsection "Initial database making, and Rebuilding for an Installed system." + +.IX Subsection "\s-1UPDATING\s0" + +.IX Subsection "\s-1REBUILDING\s0 \s-1THE\s0 \s-1SEARCH\s0" + +.IX Subsection "\s-1FILES\s0" + +.IX Header "IMPORTANT DEBIAN DATABASES FOR NOT\-INSTALLED DATABASES" + +.IX Subsection "A. downloading the important databases with --ftp." + +.IX Subsection "\s-1OVERVIEW\s0" + +.IX Subsection "\s-1DISTRIBUTION\s0 \s-1DEFINED\s0" + +.IX Subsection "\s-1SECTIONS\s0" + +.IX Subsection "\s-1ARCHITECTURES\s0" + +.IX Subsection "\s-1SWIMZ\s0.\s-1LIST\s0" + +.IX Subsection "\s-1SWIMZ\s0.\s-1LIST\s0 \s-1EXAMPLES\s0" + +.IX Subsection "\s-1FTP\s0 \s-1OR\s0 \s-1APT\s0?" + +.IX Subsection "\s-1OPTIONS\s0" + +.IX Subsection "B. downloading the important databases with apt, and maintenance options." + +.IX Header "MAKING NOT\-INSTALLED DATABASES" + +.IX Subsection "\s-1OVERVIEW\s0" + +.IX Subsection "\s-1OPTIONS\s0" + +.IX Subsection "\s-1UPDATING\s0" + +.IX Subsection "\s-1REBUILDING\s0 \s-1THE\s0 \s-1SEARCH\s0 " + +.IX Subsection "\s-1FILES\s0" + +.IX Header "PREPARING YOUR INSTALLATION FOR APT" + +.IX Header "QUERYING THE INSTALLED AND NOT\-INSTALLED DATABASES" + +.IX Subsection "\s-1MINOR\s0 \s-1MODES\s0" + +.IX Subsection "\s-1SPECIFYING\s0 \s-1THE\s0 \s-1DATABASES\s0 \s-1TO\s0 \s-1USE\s0" + +.IX Subsection "\s-1OPTIONS\s0" + +.IX Subsection "\s-1PACKAGE\s0 \s-1RELATIONSHIPS\s0" + +.IX Subsection "Dependencies " + +.IX Subsection "Alternative Packages" + +.IX Subsection "Overwriting files and Replacing Packages " + +.IX Subsection "Virtual Packages " + +.IX Subsection "\s-1FORMAT\s0" + +.IX Subsection "\s-1STATUS\s0 \s-1FIELD\s0 " + +.IX Subsection "\s-1SOURCE\s0 \s-1FIELD\s0" + +.IX Subsection "\s-1SECTION\s0 \s-1AND\s0 \s-1PRIORITY\s0 " + +.IX Subsection "\s-1DEBIAN\s0 \s-1PACKAGE\s0 \s-1OUTPUT\s0" + +.IX Subsection "\s-1VIRTUAL\s0 \s-1OPTIONS\s0" + +.IX Subsection "\s-1FTP\s0 " + +.IX Subsection "\s-1APT\s0" + +.IX Subsection "\s-1REMOVING\s0 \s-1AN\s0 \s-1INSTALLED\s0 \s-1PACKAGE\s0 " + +.IX Subsection "\s-1STDIN\s0 " + +.IX Subsection "\s-1PACKAGE\s0 \s-1MANIPULATION\s0" + +.IX Subsection "\s-1DATABASE\s0 \s-1LOCATIONS\s0" + +.IX Header "UPGRADING WITH APT" + +.IX Header "SEARCHING" + +.IX Subsection "\s-1OVERVIEW\s0" + +.IX Subsection "\s-1NARROWING\s0 A \s-1PREVIOUS\s0 \s-1SEARCH\s0" + +.IX Subsection "\s-1MINOR\s0 \s-1MODES\s0" + +.IX Subsection "\s-1OTHER\s0 \s-1OPTIONS\s0" + +.IX Subsection "\s-1EXAMPLES\s0" + +.IX Header "RAMDISK" + +.IX Subsection "\s-1OVERVIEW\s0" + +.IX Header "FILES" + +.IX Header "SEE ALSO" + +.IX Header "BUGS" + +.IX Header "AUTHOR" + +.IX Header "COPYRIGHT" + diff --git a/swim.html/ch-aptprep.html b/swim.html/ch-aptprep.html new file mode 100644 index 0000000..9f203c9 --- /dev/null +++ b/swim.html/ch-aptprep.html @@ -0,0 +1,49 @@ + +swim - PREPARING YOUR INSTALLATION FOR APT + + + +

+swim - chapter 8
+PREPARING YOUR INSTALLATION FOR APT + +

+ +
usage: swim --audit
+       swim --status
+       swim -C
+

+ +If you are using apt with swim, and this +is the first time you are using it with your installation, check your live +installation with this major mode. This is a call to dpkg -C +(--audit), and will show any packages which are not properly +configured or installed. If you get any output, make corrections. The goal +is to get absolutely no output whatsoever because it is under these +conditions that apt will work properly. See the REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS +, section 9.8 with +-q to remove the offending packages. You may have to +remove the package by hand under unusual situations like when it is not +just dependencies (see -T) between packages keeping the package +from being removed perhaps due to a broken script (see +--scripts). In an extreme case you could manually remove the +entry for this package from the /var/lib/dpkg/status database, +and hunt down and remove all the files associated with the package with +swim's -l option. When you are done if you still want +some of the packages you removed, use apt to reinstall +them with swim's -xyz option. Also, apt +provides its own built-in method to clean up your system, and will provide +instructions, but you still may have to do some of the cleaning yourself +as discussed above. + +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-commandline.html b/swim.html/ch-commandline.html new file mode 100644 index 0000000..65ecfaf --- /dev/null +++ b/swim.html/ch-commandline.html @@ -0,0 +1,158 @@ + +swim - COMMAND LINE OPTION SYNTAX + + + +

+swim - chapter 2
+COMMAND LINE OPTION SYNTAX + +

+ When you press ``swim +<enter>`` you will see a listing of command line +options in a particular syntax. This is to help you understand under what +context to use the options. When you enter the options on the command +line, the brackets, parentheses, braces, diamonds, and question marks are +not actually used. +

+ + +Major Mode Option +

+ +All command line options for swim always start with a +major mode option, except for ``swim <enter>`` +which will show the whole listing of options. A major mode option is +surrounded in braces { major mode option }. In the case +of {--search} there are the alternative major mode options +{--refinesearch} and {--research}, but because --search needs to be used +first before either of these two options, --refinesearch and --research +are surrounded in parentheses (). +

+ +Note: Through the other chapters of this manual {} is +assumed for the major modes in the +usage: section shown at the beginning of every chapter. +

+ +Let's take a closer look at this situation: + +

+ +{--search ? (--research || --refinesearch)<pattern(s)>} +

+ `||' or `|' are used to indicate +`or', `?' indicates +`optional', <diamond> indicates an +argument (a required argument - see Arguments below), +(parenthesis) means `if used, must be used after the +previous required option was used'. Note: for readability +--research and --refinesearch are not surrounded in +{}. +

+ +Normal Options +

+ +Options to the major mode options are enclosed in brackets [ +option to major mode ]. swim [-n] +<enter> (assume enter from here on out), for instance, +will show all the command line options without using the pager. The pager +which swim uses can be set in swimrc (see swimrc(8)). +``swim {--help} [-n]'' will provide brief explanations of all of +swim's options without using the pager. In this case the major mode option +{--help}, and the option [-n] were used. +

+ +Dashes +

+ +Options which have a single dash can be combined with other single dashed +options (-qaint). Double dashed options need to be +entered by themselves (--help --nopager), many double +dashed options have an alternative single dash option (-n for +--nopager). The meaning of options is related to the major +mode they are being used with. [-n] means no pager +when called with {--help}, but it's a reference to the +not-installed databases when used with {-q --query}, +fortunately most options do not have double meanings. +

+ +Arguments +

+ +Many options require an argument. Arguments are enclose in diamonds < +argument >. An argument to an option may also be +optional in which case a question mark ``?'' will be +placed between the option and the argument. [-l ? +<[--df]>] illustrates such a situation. +[-l] shows a file listings, and optionally the option +[--df] can be use with [-l] to show an +expanded listing. +

+ +[--dbpath <dir>] requires an +argument, this time the argument would not be another option, but rather +it is a directory. +

+ +Rule: When an option is an argument to another option it can be written +anywhere, but when a non-option is an argument +<dir> (notice no brackets) it has +to be placed directly after the option. Sometimes, there may be +alternative arguments divided with ``|''. +<argument1|argument2> means use argument1 or +argument2, but not both. +

+ +Based on what we now know, let's compare this situation to the +{--search} situation shown above: +

+ +[--ftp ? --source | --source_only ? <[--diff]>] +

+ + +In this case --source or alternatively +--source_only can be optionally used along with +--ftp because they aren't in parentheses +() (also notice: | was used instead of ||, but means the +same thing ``or''). --diff can optionally be provided as +an argument to either --source or +--source_only. For readability --source and --source_only +weren't enclosed in brackets. +

+ +Global Arguments +

+ +A global argument can be typed anywhere on the command +line, and can be an option or text. If global arguments +exist they are placed last after the list of normal +options that can be used with a major mode +option. +

+ +[targets | -S] and [targets|APT|DF] are +examples. {-q}, {--initndb}, and +{--rebuildndb} all use global arguments. +

+ +Minor Mode Options +

+ +{-q --query} will generally use zero or more +minor mode options [-afpgn --dir], with +one exception (see QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES +, chapter 9). +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-description.html b/swim.html/ch-description.html new file mode 100644 index 0000000..33b3536 --- /dev/null +++ b/swim.html/ch-description.html @@ -0,0 +1,32 @@ + +swim - DESCRIPTION + + + +

+swim - chapter 1
+DESCRIPTION + +

+ + +swim is a powerful package administration +and research tool for both an installed Debian +distribution, and/or not-installed virtual Debian +distribution(s) allowing querying of software packages with a variety +of package information options, and powerful searches. Virtual options +which include ftp, installation, and package removal capabilities can be +seamlessly combined with querying or searches. swim can +be used on computer systems which either have, or do not have a Debian +distribution installed. +
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-history.html b/swim.html/ch-history.html new file mode 100644 index 0000000..d8ed004 --- /dev/null +++ b/swim.html/ch-history.html @@ -0,0 +1,37 @@ + +swim - HISTORY + + + +

+swim - chapter 4
+HISTORY + +

+ +
+usage: swim --history
+       swim -h
+
+options: [--arch <architecture>] [--dists <distribution>]
+         [--n] [--dbpath <dir>] [--root <dir>]
+
+

+ +This shows a shell-like history of searches and the most recent --stdin +edit. History is numbered with the most recent action being 1, and the +earlier actions being of a higher number until the maximum amount of lines +set in the HISTORY variable in swimrc(5). A separate history is +kept for each architecture-distribution. + +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-important.html b/swim.html/ch-important.html new file mode 100644 index 0000000..c5d05eb --- /dev/null +++ b/swim.html/ch-important.html @@ -0,0 +1,330 @@ + +swim - IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED +DATABASES + + + +

+swim - chapter 6
+IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED +DATABASES + +

+
+

+6.1 A. downloading the important databases with --ftp. + +

+ +
usage: swim --ftp
+
+options: --Contents <DF|directory>
+         --Packages <DF|directory> 
+         [--dists <distribution>] [--arch <architecture>]
+         [--onec] [--Release_only]
+
+

+6.2 OVERVIEW + +

+ swim provides a method so that all information about +an existing Debian distribution is quickly accessible through databases. +Debian already provides flat file databases for all its distributions. One +database called ``Contents-(architecture)'' provides a complete +listing of all the files associated with each package, the other much more +important database called ``Packages'' provides everything from +the Package's description, to all the dependencies for that package. The +Packages database is a crucial database for other important Debian +administrative tools like dpkg and apt. +
+

+6.3 DISTRIBUTION DEFINED + +

+Debian Distributions choose a name which reflect the development state of +that distribution. The distribution named ``unstable'' is where +the majority of the development processing occurs, after unstable +has reached a certain level of maturity, it's copied over to a new +distribution called ``frozen'' which is tested extensively before +becoming the new ``stable'' distribution. The frozen +distribution retains the Release version number of the +unstable distribution, and the unstable distribution +receives a new Release version number. Eventually, +frozen becomes stable, and at this point both +frozen, and the older stable distribution are removed. +Code names are associated with the Release Version number given +for each of the distributions. This is much better for mirroring Debian +sites. + +

+ +swim was designed to ignore these code names, and instead +shows the user the Release version number associated with the +distribution. Swim users must always use the real distribution name, or +swim will not work properly. This is a nice feature because it allows user +to make decisions related to the management of their databases, and makes +research much more easier. + +

+ +The other Debian distribution which swim recognizes is +experimental. This distribution does not have any Release +version number, and contains packages which are considered risky +because of their development level. + + +

+


+

+6.4 SECTIONS + +

+ Each Debian distribution has sections related to the relationship of +each of the packages to the Debian's Policy Manual. In +``main'' there are packages which have a correct relationship +with these Policies. Packages in ``contrib'' comply with the +DFSG (Debian Free Software Guidelines found in the +Debian Policy Manual) but have various limitations like requiring +a package which is found in non-free, or is not in the Debian archive. +Packages in ``non-free'' do not comply with the DFSG but +are electronically distributable across international borders. The +``non-us'' section is found outside of the United States and +exists for packages which have export restrictions. + + +

+


+

+6.5 ARCHITECTURES + +

+ Distributions also have architecture specific sections since not all +packages compiled for one architecture can run on all other +archictectures, however, there are a large percentage of packages which do +run on all architectures. The architectures are alpha, +arm, i386, m68k, powerpc, +sparc, and more recently hurd-i386 which represents +packages for the hurd GNU kernel for the i386 architecture. + +

+


+

+6.6 SWIMZ.LIST + +

+ --ftp uses a file called swimz.list which +has the same type of format (see format below) as the +sources.list(5) which apt uses. There are some +differences. The first difference mentioned above (see +DISTRIBUTION DEFINED +, section 6.3) requires that the distribution names never should be the +code names for the Release version. Secondly, +apt only retrieves databases specific to one +archictecture, normally the one you are running apt on. +With swim though you can fetch databases for any, or +every architecture by adding the architecture to ``deb'' with a hyphen +(deb-hurd-i386). If deb has no architecture appended it is assumed that +the architecture you want is the same as the system you are running +swim on. Thirdly, at this time +swim only supports the ftp method. +Fourthly, you can change swimz.list as often as +you want without worrying about databases being removed so that that the +swimz.list and the downloaded databases match. This would occur +with apt's sources.list(5) if you removed a +site. Fifthly, databases are kept in a compressed state. +Sixthly because the list is used for both Contents and +Packages, more flexibility is provided by only allowing the default +distribution/archictecture or distribution/architecture provided on the +commandline to be downloaded. +

+ + +For apt users: If you are using apt, and +swim together it is a good strategy to use the real +distribution name in the sources list(8), and to have an exact +copy of the sources.list(5) ftp sites in the swimz.list. +Packages databases specific to the architecture apt is +using can be retrieved using swim --apt --update (this +also will keep track of the Release version), and then +swim can be used to fetch the architecture specific +Contents database as shown below. It should also be of interest +to note that Packages downloaded by either swim or apt can be used +interchangeably by using 'cp -a' and 'gzip -d' or 'gzip -9'. +

+ +Here is a brief outline of the format required by swimz.list. + +

+ +deb uri distribution [section ... ] +

+ +deb - represents a standard Debian distribution. And is +simply written as deb or with the architecture appended +(deb or deb-alpha). + +

+ +uri - Universal Resource Identifier is exactly how you +would enter an address into a web browser. This address is the base of a +Debian distribution, generally this is right before the directory called +``dists''. So if dists is found in +/stuff/pub/debian/dists, and the site is +somewhere.com then the uri would be +ftp://somewhere.com/stuff/pub/debian. +

+ +distribution - This can be unstable, +frozen, stable, experimental. Distribution can +also be a path which must end with a slash like +unstable/binary-i386/. This is used when there is no section as +in the experimental distribution or in sites which do not have symlinks to +the non-us section. No section would be mentioned in this situation. +

+section - main, contrib, +non-free, non-US (write it this way). + +

+


+

+6.7 SWIMZ.LIST EXAMPLES + +

+Examples (each on one line): + +

+ +deb-alpha ftp://somewhere.com/stuff/pub/debian unstable main contrib non-US +

+ +This will fetch the alpha databases from somewhere.com for the unstable +distribution for the main, contrib and non-US sections. + +

+ +Note: In these next two examples you can not append any architecture to deb +with a hyphen. +

+ +deb ftp://somewhere.com/stuff/pub/debian project/experimental/ + +

+ +This will fetch the experimental database, but there is not a +Contents-(architecture) database for this distribution. Notice that it ends +with a slash. + +

+ +deb ftp://somewhere.com/stuff/pub/debian-non-US stable/binary-i386/ +

+ +This will fetch the i386 databases for the stable distribution for non-us, + +


+

+6.8 FTP OR APT? + +

+ How you use major mode --ftp depends on your goals. +Even if you are using apt, you may be interested in +keeping tabs on different architectures. In this case you would have to +download the Packages databases specific to these architectures. +If you are only interested in the architecture which apt +is interested in, then you only need to use --ftp to +fetch the Contents database(s). But, because it isn't a +requirement to set up a virtual filesystem, you are not required to fetch +the Contents database. The advantages of fetching the +Contents database is determined by the method you choose to make the +database (see MAKING NOT-INSTALLED DATABASES +, chapter 7). These advantages include the +ability to view a listing of the files and directories associated +with a package, the ability to query files and directories to +find out which packages relate to them, and the ability to perform a +powersearch on all the files and directories to find the +associated packages. +

+


+

+6.9 OPTIONS + +

+Remember: If you want to download a different +distribution/architecture other than the default specified in your +configuration file, you must specify this on the commandline. +

+ --Packages determines where you want the Packages +database as well as the Release data put when they are downloaded. The +DF argument implies that the databases will be put in +your default directory (see swimrc(5)). These databases can later +be located by the major modes --initndb and --rebuildndb +just by using DF as an argument. Alternatively, these +databases can be put in any directory you choose by providing a +directory as an argument. +

+ +--Contents determines where you want the +Content-(architecture) database(s) put. (see +--Packages). +

+ +--onec will download only one Contents-arch per +distribution/architecture specified on the commandline or by default. +

+ +--Release_only will download only the Release data for +the swimz.list or particular Package(s) mentioned on the +command line. +

+ +--dists will only find the distribution which corresponds +to the argument provided this option. +

+ +--arch will only find the architecture which corresponds +to the argument provided this option. The different architecture needs to +be specified in swimz.list with a hyphen and the architecture appended to +deb (deb-(arch)). +


+

+6.10 B. downloading the important databases with apt, and maintenance +options. + +

+usage: swim --apt +

+ +options: [--update] [--clean] [--autoclean] [--check] + +

+ +Please read A. downloading the important databases with --ftp. +, section 6.1 for more information. +

+ +--update calls apt to download the +Packages databases. +

+ +--clean is a call to an apt option to +remove any packages stored in apt's storage area for +downloaded packages. The default for this storage area is +/var/cache/apt/arhives +

+ +--autoclean will only clean out packages which are not +found in apt's cache. +

+ +--check tests and updates apt's cache. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-makinginst.html b/swim.html/ch-makinginst.html new file mode 100644 index 0000000..6dc6578 --- /dev/null +++ b/swim.html/ch-makinginst.html @@ -0,0 +1,180 @@ + +swim - MAKING INSTALLED SYSTEM DATABASES + + + +

+swim - chapter 5
+MAKING INSTALLED SYSTEM DATABASES + +

+ +
+

+5.1 Initial database making, and Rebuilding for an +Installed system. + +

+ +
+usage: swim --initdb       
+       swim --rebuilddb
+
+options:  [--dbpath <dir>] [--root <dir>] [--lowmem]  
+          [--split_data <lines>]
+
+
+

+ +An installed Debian distribution is one in which packages are +installed using dpkg or some front-end to +dpkg like apt or +dselect; swim supports installation +through apt. These major modes are for a computer with an +installed Debian distribution and make the databases which allow +querying and searching capabilities for the installed distribution. +

+ +--initdb is run when the databases do not exist yet, +--rebuilddb is run if the databases have become corrupt, +or you want to rebuild the databases instead of updating them. + +

+ +--dbpath can be specified as an alternative location for +where the databases will be made. The default location is +``/var/lib/dpkg''. An argument like ``/otherstuff'' +could be provided, and then the databases would be made here instead. + +

+ +--root allows a database to be made for a Debian distribution installed on a +different partition. If the distribution is mounted on +/New_Debian, ``/New_Debian'' would be the argument to root. The databases would be made for the +Debian distribution installed on the ``/New_Debian'' partition. + +

+ +--dbpath and --root can be used +together. Given the previous two examples, the databases would be made on +``/New_Debian/otherstuff'', assuming +``/New_Debian/otherstuff'' actually existed. + +

+ +--lowmem uses a method which uses a small amount of +memory to make the databases. By default --initdb and +--rebuilddb use a method which fully takes advantage of +memory, this is a good thing, because it means the databases are made in a +quicker manner. On a computer with a K6-200 CPU, 64MB of memory, and 1500 +installed packages, the databases can be made in 4.5 minutes using the +default method, and 11 minutes using the low memory method. The high +memory method is the default because in general the size of a distribution +is related to how much resources a computer has, and probably a large +installation is unusual. If you get an ``out of memory'' when you use the +default method, or if your system is overloaded to begin with, the +--lowmem method is the prefered way. + +

+ +--split_data determines the size of the files in the +temporary directory used to contruct the database. The default is 25000 +lines per file. If you are using the --lowmem method you +may want to provide a different argument to --split_data, +like ``--split_data 10000''. This is a subject of +experimentation. +

+


+

+5.2 UPDATING + +

+usage: swim --db + + + +

+ +options: [--dbpath <dir>] +[--root <dir>] [--check] + +

+ +--db allows you to update the databases by hand when +packages have been removed, added, or changed. swim will automatically run +--db under certain conditions. +

+--check prints out the changes to STDERR, and the +total to STDOUT without proceeding with the update. +

+ +See Initial database making, and Rebuilding for an +Installed system. +, section 5.1 for options --dbpath and +--root. + +

+


+

+5.3 REBUILDING THE SEARCH + + +

+ +usage: swim --rebuildflatdb + + + +

+ +options: [--dbpath <dir>] +[--root <dir>] + +

+ +swim makes the flat databases searchindex.deb and +dirindex.deb for doing powersearches. Instead of +rebuilding these databases everytime --db is run, new +information is just appended to these databases, and old information is +kept. Generally, this is not a problem because only files and directories +which the other databases actually know something about will be refered +to. But in a situation where a file has changed into a directory, the +powersearch may not work properly, because the old file name +remains in searchindex.deb, and the new directory name is now in +dirindex.deb directory. In general, it takes a lot of changes to +the installed system before it is really becomes necessary to rebuild the +flat databases. This process takes less than a minute on a K6-200 with +1500 packages. + +

+ +See Initial database making, and Rebuilding for an +Installed system. +, section 5.1 for options --dbpath and +--root. +


+

+5.4 FILES + +

+ +Databases which are made: +

+ +

 packages.deb
+ fileindex.deb
+ statusindex.deb
+ groupindex.deb
+ searchindex.deb
+ dirindex.deb
+
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-notinstalled.html b/swim.html/ch-notinstalled.html new file mode 100644 index 0000000..5b91b46 --- /dev/null +++ b/swim.html/ch-notinstalled.html @@ -0,0 +1,230 @@ + +swim - MAKING NOT-INSTALLED DATABASES + + + +

+swim - chapter 7
+MAKING NOT-INSTALLED DATABASES + +

+ +
+usage:  swim --initndb
+        swim --ndb
+        swim --rebuildndb
+
+options: [--Contents <target|FDBtarget|DF|FDBDF>]
+         [--main] [--contrib] [--non-free] [--non-us]
+         [--arch <architecture>]  [--dists <distribution>] 
+         [--dbpath <dir>] [--root <dir>] [--alt]
+         [--split_data <lines>] [-v] [--cron] 
+         [targets|APT|DF]
+
+

+


+

+7.1 OVERVIEW + +

+The not-installed database provides swim with many capabilities like the searching, and querying of +packages which do not actually exist on the live filesystem, as well as the +ability to seamlessly install packages while searching or quering, or the +ability to fetch the packages source code. The virtual filesystem is optional, but it is highly recommended. These two major mode options set +up these databases, after determining the level of interaction which you +want. +

+ +Whenever swim makes databases it thinks only in terms of +one distribution and one architecture. This keeps things logical. +swim does have the ability to take Packages files with +multiple architectures, and distributions, and to extract information for +one distribution and one archictecture to make its databases. This could +provide interesting information from dumps from apt +(apt-cache dumpavail). +

+ +--initndb creates the initial not-installed databases for +a particular architecture and distribution, and +--rebuildndb remakes the not-installed databases for that +same architecure and distribution. If not otherwise specified +swim will use the values it finds in +swimrc to determine what architecture and distribution you want +to use to make swim's databases. Otherwise... + +


+

+7.2 OPTIONS + +

+ --arch allows an argument to override the +architecture found in swimrc. + +

+ +--dists allows an argument to override the +distribution found in swimrc. +

+ +--alt is used for a distribution with a Debian archival +structure, but which has a different name. This allows for alternative +distributions. +

+ +When APT or DF are provided as arguments +(see below), by default the Packages which pertain to the +sections found in swimrc will be shown. If you only want certain +sections you may specify them on the command line. If you are not using +APT or DF, it is a good idea to make +sure that either the sections found in swimrc or the sections you +put on the command line match the Packages you a targetting +because this is much more effecient. +

+ +--main will override the sections found in +swimrc, and will use this section. +

+ +--contrib will override the sections found in +swimrc, and will use this section +

+ +--non-free will override the sections found in +swimrc, and will use this section +

+ +--non-us will override the sections found in +swimrc, and will use this section +

+ +Global arguments targets|APT|DF must be used with either +of these two major modes to find the Packages databases. targets +can be a full path to one or a set of Packages. +APT will use the Packages found in +/var/state/apt/lists, and DF will use the +Packages found in the default directory for swim (see +--ftp). If you use either APT or +DF you will be given an interface which +allows you to choose one Packages database for each section you +would like to use from the various sites. This interface +shows the site, date, +size and Release version for each +Packages. +

+ +--cron allows you to override the +interface produced when APT or +DF is provided as an argument. This is useful if you want +to automate the database making process. --cron will +choose the newest database(s), if cron notices that the Release +version has changed, cron will not proceed, but will provide a warning +instead. This allows you to make the appropriate changes and choices. +

+ +--Contents can be give one of four arguments: +

+ +1). If you have a Contents-(architecture) +database in a target location you know about you may provide a path to the +location. The Contents database can be compressed. +

+ +2). If you prepend the path with the letters +FDB (meaning flat database) when the databases for swim +are made, instead of using the Contents database to make: + +

 
+ nfileindex-arch-dists.deb
+ nsearchindex-arch-dists.deb 
+ ndirindex-arch-dists.deb
+

+ +Only the ncontentsindex-arch-dists.deb.gz database will be made +which allows the ability to view file/dir listing for not-installed +packages, but does not provide the virtual file system or powersearch +capabilities which the other databases would have provided. +

+ +3). The argument DF may be used if you +have used --ftp with the DF argument to +the option --Contents (see --ftp). In this case +it is assumed you are also using global arguments DF or +APT for the Packages databases. This will give you an +interface (if --cron isn't used) allowing you to choose +one Contents database for the particular distribution you want to +make the databases for. +

+ +4). FDB does the same exact thing with +DF as it does with the before mentioned +FDBtarget, and provides the interface. +

+ +-v will only work if you have dpkg installed. It allows +swim to verify swim's own built-in version comparison +function with dpkg's version comparison function. This is +good for debugging purposes, and produces a report called +.version_compare in the same location that +swim's databases are made. +

+ +--split_data is only advantageous if +--Contents is being used. See --initdb +for more information about the --split_data option. +

+ +See Initial database making, and Rebuilding for an +Installed system. +, section 5.1 for options --dbpath and --root. +


+

+7.3 UPDATING + +

+ +--ndb has the same options as --initndb and --rebuildndb except +for --split_data. It also has a new option --nue which will +never have to be used unless the experimental distribution or non-us +section are found in Contents (which presently isn't the case). +--check prints out the changes to STDERR, and the total to STDOUT +without proceeding with the update. --status_only can be used +after a new package has been installed to update the status, after which +-qni and -qi will correlate properly. +
+

+7.4 REBUILDING THE SEARCH + +

+--rebuildflatndb serves the same purpose as --rebuildflatdb. See +REBUILDING THE SEARCH + +, section 5.3 +
+

+7.5 FILES + +

+Databases and reports which are made (arch = architecture dists = +distribution): +

+ +

 
+ npackages-arch-dists.deb
+ nfileindex-arch-dists.deb requires <--Contents>
+ nstatusindex-arch-dists.deb
+ ngroupindex-arch-dists.deb
+ nsearchindex-arch-dists.deb
+ ndirindex-arch-dists.deb
+ .packagesdiff-arch-dists.deb requires <--Contents>
+

+


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-query.html b/swim.html/ch-query.html new file mode 100644 index 0000000..011a323 --- /dev/null +++ b/swim.html/ch-query.html @@ -0,0 +1,672 @@ + +swim - QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES + + + +

+swim - chapter 9
+QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES + +

+
usage: swim -q [-fpgn --dir] [targets | -S]
+       swim --query [-fpgn --dir] [targets | -S]
+       swim -qa || swim --query -a 
+

+ +

options: [--total -t] [-i] [-l ? <[--df]>] [-d] [-c]
+         [--scripts] [--preinst] [--postinst] [--prerm] 
+         [--postrm] [-v] [--dbpath <dir>] [--menu -m] 
+         [--shlibs] [-T] [--pre_depends] [--depends] 
+         [--recommends] [--suggests] [--conflicts] 
+         [--replaces] [--provides] [--md5sum] [--root <dir>] 
+         [--copyright] [--changelog] [--allgroups] 
+         [--arch <architecture>] [--dists <distribution>] 
+         [--ftp ? --source | --source_only ? <[--diff]>] 
+         [--stdin] [--extract] <ALL|archive|PWD!archive>]
+         [-xyrz --remove ? <[--nz]>] [--purge] [--apt2df] 
+         [--df2apt] 

+ +global arguments: [targets | -S ? <\d{1,}>] +

+ +Quering almost always involves using -q or --query with +zero or one or a combination of the minor mode options +(package specification options), and one or more (only one for +-g) targets specific to the minor mode, or the results of a +search (-S). [-S can be provided a numerical argument +pertaining to the past history.] This can be combined with one or more +options. The one exception is ``swim -q --allgroups''. + +

+ +--query or -q can be used by itself or with +-n to query known package names or package names with +versions. ``swim -q test1 test2_0.3-1'' would produce the +output: + +

+ +

test1_1.0-2
+test2_0.3-1
+
+

+9.1 MINOR MODES + +

+ -n is the minor mode option to access the +not-installed system, it can be combined with the minor mode +options -a, -g, -f, or +it can be used by itself. + +

+ +-a allows every package on an installed or +not-installed (-n) system to be queried. ``swim +-qan'' will show all the package names with versions for the +not-installed system + +

+ +-f allows files or directories to be queried, +when used without any options the package name with version is shown. +--dir will only query directories, this is useful if you +are not sure whether what you are quering is a directory or a file. When a +directory is queried, swim shows all packages which exist below the +queried directory. ``swim -qf /'' is exactly the same as +``swim -qa''. Hint: ``swim -qf .'' and +``swim -qf *'' are quite different, the first shows all +packages which exist below the current directory, and the second will show +the package which each file in the current directory comes from. +

+ +-g will query a group (also called a section, +see SECTION AND PRIORITY +, subsection 9.5.3)) of packages. Groups represent subjects which +packages with similiar characteristics are catagorized by. To view all the +groups found in an installed or not-installed system use ``swim -q +--allgroups'' or ``swim -qn --allgroups''. +``swim -qg hamradio'' or ``swim -qng +hamradio'' shows all the package names for the hamradio group. +

+ +-p is used to query a Debian package, these +packages are distinguished by their ``deb'' ending, but swim can +tell whether a file is a debian package even without the ending. Called +without any options the package name with version will be shown. +


+

+9.2 SPECIFYING THE DATABASES TO USE + +

+ --dists will use the databases for the argument +given, otherwise the databases pertaining to the value found in swimrc +will be used. + +

+ +--arch will use the databases for the argument given, +otherwise the databases pertaining to the value found in swimrc will be +used. + +

+ +Example: swim -qat --arch hurd-i386 --dists unstable + +

+ +Assuming these databases exist this will show all packages and their +versions for the unstable distribution and architecture hurd-i386 even if +the values in swimrc are i386 and stable. + +

+ +see A. downloading the important databases with --ftp. +, section 6.1 and MAKING NOT-INSTALLED DATABASES +, chapter 7 for more +information about the databases. + +


+

+9.3 OPTIONS + +

+ --total or -t are used to override the output +suppressor. The output suppressor will not show output if a certain +number of packages is exceeded, instead it will show the number of +packages you are querying. This is useful for two reasons, first, knowing +the number of packages you are quering can be very informative, second, it +gives you a chance to add to the command line a pipe to a pager, ex: +``swim -qat | less''. You can set the number that the +output suppressor works at as high or low as you want in the +swimrc(8) file. By design the -t option will +have to be used if the -i option is used and more than +one package is being queried. This option can also be used to alter the +output of the various script options (--scripts, --preinst, --postinst, +--prerm, and --postrm). + +

+ +-i provides information about each package being +queried. The format differs slightly for the installed packages versus the +not-installed packages. see FORMAT +, section 9.5: + +

+ +-l provides a listing of the files associated with a +package. If the option --df is provided as an argument, +all the directories associated with package will be shown. It is important +to remember that many packages provide directories which become important +to them after they are installed, so the option --df +often provides necessary information which -l called by +itself would have not. + +

+ +-d shows the documentation which the package provides +found in /usr/doc/*, /usr/man/*, /usr/info/*. +Other documentation which the package may provide in a non-standard +location will not be shown. -d takes precedence over +-l, so if -l is used on the command line +with -d, only the output for -d will be +shown. + +

+ +-v is a special option which works only with the minor +mode -p. It can be used with -l, +--df, -d, to show the packages files +and/or directories in long format (ls - +l). + +

+ +-c will show the configuration files packages use. If the +package does not have a configuration file then nothing will be shown. The +output will show the file and its path indented one space with the +MD5 checksum. This will not work with +-n. + +

+ +--scripts shows all scripts associated with a package +with the name of the script presented before each script in this way +#####scriptname######. If the scripts are called +individually by using the script options --preinst, +--postinst, --prerm, or +--postrm no title is shown, this is nice for writing to a +file. If -t is used with the individual script options a +title will be shown, this makes sense because normally only individual +packages would be queried to write a script to a file, and +-t wouldn't be used in this situation. Scripts are the +soul of Debianized packages allowing packages to be installed, configured, +and removed seamlessly and cleanly under all kinds of conditions. These +options do no work with -n. + +

+ +--menu or -m is used to view menufiles which belong to +various packages. If the package does not have a menufile nothing will be +shown. This option can be useful in troubleshooting a menu entry which +does not seem to work, or in finding out where the menu entry is. +Joost Witteveen's Debian menu system is a centralized program +which interacts with all kinds of menus. Please read the +documentation ``swim -qd menu'' which comes with the +menu package to find out more. This will not work with +-n. + +

+ +--shlibs shows a list of shared libraries certain +packages supply. The Debian Packaging Manual (packaging-manual) +provides detailed information about the format of a shlibs file. This will +not work with -n. +

+ +--md5sum checks MD5 checksums. It can be +used with -l, -d, -c, +or -p. If there are checksums available the md5sum result +will be either OK, FAILED, or +MISSING. MISSING means that although a +checksum exists, the file can not be found. The result is put after the +file and its path and the MD5 checksum or the package +name and version and the MD5 checksum. + +

+ +--copyright does a case insensitive search for copy or +license in the /usr/doc/packagename directory. This should show +how the package relates to Debian's Policy Manual. + +

+ +--changelog searches for any files in +/usr/doc/packagename which look like changelogs. Debian packages +always have a Maintainer's changelog for the package. There may +be a separate changelog kept by the author of the program. +


+

+9.4 PACKAGE RELATIONSHIPS + +

+ +-T shows all the package relationships of packages. +Individual package relationships can be viewed using +--pre_depends, --depends, +--recommends, --suggests, +--replaces, --conflicts or +--provides. Package relationships are the spirit of +Debian packages, here is a quick overview briefly reiterating what can be +found in the Debian Packaging Manual. Package +Maintainers set these relationships in control file fields of the +same name. +

+ +Dependencies + + Pre-depends - means that the pre-depended package or packages +must be installed before the queried package can be installed. Most +packages which have pre-dependencies are usually essential and required +packages. + +

+ +Depends - declares an absolute dependency to another package or +packages either real or virtual. The queried package cannot +function without this other package. + +

+ +Recommends - declares a strong, but not absolute dependency to +another package or packages either real or virtual. You would +usually find the recommended package together with the queried package in +a normal installation. + +

+ +Suggests - can be one or more packages either real or +virtual which would be useful to the queried package, but are not +necessary. + + +Alternative Packages +

+ +Conflicts - is a package or packages either real or +virtual which would cause problems with the queried package, and +would not be allowed to be installed while the queried package was +installed. +

+ +Overwriting files and Replacing Packages +

+ +Replaces - allows the queried package to replace another package +or packages by overwriting their files, after which the previous package +would be considered to have disappeared. Essentially this allows the +queried package to take over the package or packages. In a situation where +there was a Conflict between the queried package and these packages this +field would help determine which packages should be removed. +

+ +Virtual Packages +

+ +Provides - declares a virtual package which may be mentioned in +Depends, Recommends, Suggests, or +Conflicts. Virtual packages allow one or more packages +to share the same name of another package, which means if the queried +package has a reference to a virtual package in one of the before +mentioned package relationship fields, then whatever packages provide the +virtual package are also being listed. +


+

+9.5 FORMAT + +

+ +1). Installed system + +

+ +

 Package: name                        Status: hold ok installed
+ Version: 1.1-1                       Essential: no
+ Section: namers                      Priority: extra
+ Installed-Size: 10                   Source: generatename (2.0-1)
+ Maintainer: name <name@name.org>
+ Description: hostname maker
+  A nice way to figure out a hostname nobody
+  else has.
+

+ +2) Not-installed system + + + +

+ +

 Package: name                        Status: r> hold ok installed (1.1-1)
+ Version: 1.1-2                       Essential: no
+ Section: names                       Priority: extra
+ Installed-Size: 11                   Source: generatename (2.0-1)
+ Size: 43000                          Architecture: i386
+ Distribution: experimental
+ Maintainer: name <name@name.org>
+ Description: hostname maker
+  A nice way to figure out a hostname nobody
+  else has.
+

+ +There are several things to point out. The difference between the two +outputs relates to the addition of the Distribution, Size, and +Architecture fields for the not-installed query. Installed-Size is how +many kilobytes the package will occupy when it is unpacked, whereas Size +is the size in bytes of the package. +


+

+9.5.1 STATUS FIELD + +

+ + +The Status field provides the installation status of the package, this +holds true for the not-installed query as well. In a sense, the +not-installed database isn't always not-installed. If the not-installed +package is actually already installed, and the version numbers are exactly +the same, then the status will be the same for either query. If the +not-installed package is not installed then the status will be +``not-installed''. In cases where the not-installed package is already +installed, swim uses it's comparison function to figure out whether it is +a newer of older package which is installed. In the above example, swim +realizes the same package is installed, and only the debian-revision has +changed, hence the only difference is that the revision number is greater +``r>'' for the not-installed package. When only the debian-revision has +changed it can safely be assumed that the author (creator, programmer) of +the same program has not made any changes to the same program, but the +Debian maintainer has made a change to an aspect of the package like a +change in the script the package uses to properly install. You may have +also noticed that the status field shows the version number of the +installed package enclosed in parenthesis. +
+

+9.5.2 SOURCE FIELD + +

+ +The Source field is present in these examples, but the Source field will +not always be present for packages. In cases where the name of the source +package is the same as the the name found in the Package field, and the +version number of the source package is also the same as found in the +Version field, then there will be no Source field. In the above examples +there is a Source field. In this case name was probably one of many +packages generated from the source package called generatename. In this +particular example generatename also has its own unique version number +2.0-1 enclosed in parentheses, if no version number had been mentioned +then the source package would have the same version number as found in the +Version field. +
+

+9.5.3 SECTION AND PRIORITY + +

+ +Section shows the subject which a package is categorized with (see +-g). Priority shows how important the package is to have +installed. In the case of the not-installed databases the information for +these fields is almost always available from the Packages databases, but +this is not always the case for Debian packages. For packages which do no +provide this information swim will do its best to fill in the blanks from +information found in the installed and not-installed databases. If proper +information can not be found it will be indicated as ``unavailable'' or +``unknown.'' Unavailable would indicate that information about the package +exists, but it is from a different version (includes debian-revision), and +no information exists for this version. Unknown means no similiar package +exists, and there is absolutely no information about this package in the +databases. +

+ +When a Debian package is queried using the -p +option you will get output like the first example shows, the status field +is also calculated. +


+

+9.6 FTP - VIRTUAL OPTIONS + +

+ +For ftp capabilities swim uses the swimz.list to determine which +sites it will check for the requested packages. The first site which fills +the request will be used, otherwise swim will go through +all the sites avoiding repeats, and if no sites can fill the request, +swim will either quit or proceed on to check for another +request. +

+ +--ftp allows the queried package, its source package, or +just the source package diff to be downloaded while being queried. This is +refered to as virtual downloading because the quering and the downloading +are seamless as though the package already exists locally. This has to be +used with the option -n because packages which which are +not part of the not-installed database are considered to already have been +downloaded. Packages which are already installed can be downloaded or +their source retrieved by setting up a database which corresponds to these +packages; if the installed packages belong to the stable distribution, +set-up the not-installed stable databases. +

+ +Packages or source code are placed in an area below the default directory +mirroring the remote directory they were downloaded from after their size +and modification times are checked for correct values. This area is called +the DF directory, and although this directory mirrors +remote directories, it is not an exact mirror, but specific to the +requirements of swim because code names for Release versions are not taken +into account. For real mirroring capabilities there exist many excellent +programs. If a package has a MD5 checksum, +--md5sum will automatically be run and the value shown. +Regardless of whether or not the md5sum check is OK or +not, the package will still be put in the DF directory to +allow the package to be looked at, so watch the output from +--ftp to check for FAILED md5sums. + +

+ +Packages or source code packages will not be downloaded again if they are +found in the DF directory unless their +upstream-version has changed in the not-installed database, if +the packages are not in the DF directory and the remote +upstream-version is different than the not-installed +upstream-version then the packages will not be downloaded until +the not-installed database is updated or rebuilt to reflect the version +change. Changes in the package's upstream-version indicates that +the author(s) of the program have made changes to the computer +code for the program contained in the package or the source code package. +On the other hand, swim will check for a debian-revision change +at the remote site if the package can not immediately be found. If the +package's debian-revision has changed and the package does not +exist locally in the DF directory, it will be downloaded. +This is a nice feature, especially for the unstable distribution, because +it tends to extend the time needed before the not-installed database has +to be updated or rebuilt to match the changes at remote sites. + +

+ +--source is used with --ftp to download +the source code package. --source_only will download the +source code package without the deb package. Source packages consist +of three files. The source control file which ends in +``dsc'', the original source archive which is a compressed tar +file, and the unified context diff showing the changes necessary +to make the original source into Debian source. The diff can be downloaded +by itself if --diff is provided as an argument to +--source or --source_only. + +

+ +For apt users: apt allows packages to be +downloaded, but if more than one package is required for the package +relationships to be proper, apt will download all these +packages. --ftp allows specific packages to be +downloaded, packages from other architectures, and source packages to be +downloaded, here lies the advantage of this option over using -xyz +--nz (see below). If a particular package has been dowloaded into +the DF directory and it is needed by apt +for installation, simply copy or move the package from the +DF directory to /var/cache/apt/archives before +running apt, and the package will not be downloaded by +apt again; future versions of swim will +have an option to automatically accomplish this (see --df2apt). +


+

+9.7 APT - VIRTUAL OPTIONS + +

+ +apt-get(8) is a nice package relationship checker from the +apt package which figures out what needs to be done to +properly install a package or packages when one or more package names are +provided to it. apt-get will get all packages which are +needed using a variety of methods, and then apt-get +interacts with dpkg in a way which allows for a +successful installation. + +

+ +-xyrz, --remove, and --nz can be used if +apt-get from the apt package is +installed. These options allow for what is refered to as virtual +installation/removal. It is prudent to always test what will happen by +using the -x option alone before actually proceeding with +the installation with the -z option. -x +will actually simulate what would happen in an installation, showing which +and how many packages will be changed, which and how many new packages +will need to be installed, which and how many packages will need to be +removed, any conflicts, and what needs to be configured. +-y will automatically answer yes to any prompts +apt-get may produce allowing apt-get to +run non-interactively. -z as mentioned before actually +proceeds with the installation using dpkg after the +apt-get gets the packages. You can append a minus sign +to a package name to cause it to be removed. --nz when +used as an optional argument with -xz or -xyz will only +download the packages into /var/cache/apt/archives or into +whatever directory you configured for holding archives for +apt. +

+ +IMPORTANT: apt makes it so easy to make +changes to your installation that it is highly recommended to do your +research with swim first. This can be done by checking package +relationships, file/dir listings, comparing the not-installed package to +an installed package if such exists, checking --md5sum +and -c for the installed package, and checking the Source +field by running a --search (see SEARCHING +, chapter 11) to +check to see how the source package has been split into binary packages +for the not-installed package versus an installed package if such exists. +Ofcourse, there are many other things you could look at, and you can +always do your research after the fact. Presently --db is +run only by hand, so you can check the old state after an installation if +you have not already run --db, yourself. +


+

+9.8 REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS + +

+ +--purge uses dpkg to remove an installed +package or packages and the configuration files as shown with +``swim -qc packagename''. +

+ +-r or --remove removes an installed package or packages +with apt, but not the configuration files as shown with +``swim -qc packagename''. You may also append a plus +sign to a package name to cause it to be installed. This option is used +with -x or -x(y)z. +


+

+9.9 STDIN - VIRTUAL OPTIONS + +

+ +--stdin works with either --ftp, +-x, -xyz, -xz, +--purge, -r, or +--remove. +

+ +--stdin provides the readline capabilities +commonly found in shells allowing you to edit what is on the command line. +You can edit the command line, press enter and then recall the history, +and make more changes, or type in exit to process the changed or +unchanged command line. To find out more about what readline commands +your shell supports please read the man pages which apply to your shell. +Information for the bash shell can be found in bash(1) under the +title ``Readline Command Names''. +

+ +Example: ``swim -qgnx --stdin hamradio'' will list all +the packages from the not-installed hamradio group on the command line, +this list can be edited then submitted to apt-get for a +simulated installation. Another instance of swim can be +run at the same time, perhaps ``swim -qinTg hamradio'' to +help in making editing decisions for --stdin. +


+

+9.10 PACKAGE MANIPULATION - VIRTUAL OPTIONS + +

+ +--extract only works with the minor mode +-p to extract parts or all of a Debian package. If the +argument ALL is provided then everything found in the +package will be extracted below the current directory in the exact +directories found in the package. A particular file may be extracted +in its exact location below the current directory by entering the +exact path for the file as shown by ``swim -qpl'' or +``swim -qpd'' as the argument. Alternativily, a file +may be extracted in the current directory regardless of its proper +location by prepending PWD\! before the path shown by +``swim -qpl'' or ``swim -qpd''. Notice +the backslash before the exclamation point, this is because shells +consider ! a special character, so it has to be backslashed so that the +shell knows that it is not such a special character. Example: +``swim -qpi --extract PWD\!usr/bin/name --scripts +name_1.1-2.deb'' will extract the binary name in the current +directory from the name package, show information for the name package, +and show any scripts for the name package. +
+

+9.11 DATABASE LOCATIONS + +

+ +--dbpath can be specified as an alternative location for +where the databases would be found. The default location is +``/var/lib/dpkg''. An argument like ``/otherstuff'' can +be provided, and then the databases would be found here instead. + +

+ +--root allows a database to be found for a Debian +distribution installed on a different partition. If the distribution is +mounted on /New_Debian, ``/New_Debian'' would be the +argument to root. The databases would be found for the Debian distribution +installed on the ``/New_Debian'' partition. +

+ +--dbpath and --root can be used together. Given the +previous two examples, the databases would be found on +``/New_Debian/otherstuff'', assuming +``/New_Debian/otherstuff'' actually existed. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-ramdisk.html b/swim.html/ch-ramdisk.html new file mode 100644 index 0000000..c3f050b --- /dev/null +++ b/swim.html/ch-ramdisk.html @@ -0,0 +1,82 @@ + +swim - RAMDISK + + + +

+swim - chapter 12
+RAMDISK + +

+ +
usage: swim --ramdiskon
+       swim --ramdiskoff
+
+options: [-n] [--searchfile] [--arch <architecture>] 
+         [--dists <distribution>] [--dbpath] [--root]
+ 
+         no options for --ramdiskoff
+
+

+


+

+12.1 OVERVIEW + +

+ +A ramdisk can be mounted below the default path or the specified path for +the databases in the dramdisk directory. The ramdisk is used to speed up +powersearchs and/or file/dir listings for packages from the not-installed +system. Also, this is useful if a computer system is heavily loaded with +other processes using the memory, and the ramdisk tends to persist even +after being unmounted. Modern kernels usually are built with support for +ramdisks. If these options do not work the kernel will need to be compiled +to support ramdisks by answering yes to RAM disk support. Perhaps the best +README showing how to configure and compile a kernel comes with +the kernel sources in the main directory. +

+ +--ramdiskon allows a ramdisk to be created and mounted. +If called with -n (not-installed databases) +ncontents-arch-dists.deb.gz will automatically be written to the +mounted ramdisk. This provides faster file/dir listing capabilities when +using -l, --df, or -d +when querying the not-installed system. Faster powersearch capabilities +are available through the option --searchfile. If the +search databases are not already compressed, they will now be compressed, +this usually only needs to be done once or until the databases are updated +or rebuilt again. The search databases will then be written to the mounted +ramdisk. An installed system only writes the search databases to the +mounted ramdisk, so always use --searchfile when specifying installed +system databases. +

+ +--ramdiskoff is used to unmount the ramdisk. The +not-installed databases and the installed databases can not be +simultaneously provided by a mounted ramdisk, use +--ramdiskoff first, then --ramdiskon to +install the other databases of choice. This also pertains to different +distributions and/or architectures. +

+ + +See the section ``SPECIFYING THE DATABASES TO USE +, section 9.2'' for +options --arch, -dists. +

+ +See the section ``DATABASE LOCATIONS +, section 9.11'' for options +--dbpath and --root. + +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-search.html b/swim.html/ch-search.html new file mode 100644 index 0000000..0202c14 --- /dev/null +++ b/swim.html/ch-search.html @@ -0,0 +1,191 @@ + +swim - SEARCHING + + + +

+swim - chapter 11
+SEARCHING + +

+ +
usage: swim --search ? (--research || --refinesearch) <pattern(s)>
+       swim --powersearch ? (--research || --refinesearch) <pattern(s)> 
+       swim --ps ? (--research || --refinesearch) <pattern(s)> 
+
+options: [-g] [-n] [--dbpath <dir>] [--root <dir>] [--no]
+         [--arch <architecture>] [--dists <distribution>
+         [--ftp ? --source | --source_only <[--diff]>] 
+         [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df]
+         [--no] [--df2apt] [--purge] [<\d{1,}>]
+ 
+         [--dir] and no [-g]for --powersearch or --ps
+
+ +

+


+

+11.1 OVERVIEW + +

+ + +swim provides two major types of searches. A search with +--search searches package information (see FORMAT +, section 9.5), and a search with --powersearch or --ps +searches package information, and all files and/or directories +associated with each package. +

+ +The results of either of these searches can be narrowed down by +running a test search with --research (this step can be +skipped) and/or setting the results in stone with +--refinesearch. --search can be +narrowed down initially by specifying a particular +group, and --powersearch can be +expanded initially by specifying that directories be +searched as well as files. Both searches can use the same virtual +options which the major mode -q or --query use. +Generally, it is preferable to run a search, and then to provide the +results of a search (using -S) as an argument to +-q or --query; this allows the results of a search to be +queried. Every time a search is run the results are appended to the +history, past searches can be refined or researched by providing the +numerical argument pertaining to the history. \d{1,} is simply Perl +notation meaning a number with one of more digits. + +

+ +Perl regexps (see perlre(1p)) can be used to define the +pattern (string) provided as an argument to a search. Do not surround a +pattern in slashes, a slash is only used after all patterns and before the +modifiers i and/or m (swim supports these two modifiers). To +search for more than one pattern, patterns are separated with bars +(|). Patterns may include quatifiers, and metacharacters, +also found in egrep(1). +

+ +If a search finds any packages which match the search, the package +information will be displayed as the package is found. The package will +only be shown once regardless of how many times it is found while the +search progresses. When the search is over the number of packages found is +shown. +

+ +--search provides a search of package information. This +is similiar to grepping ``swim -qait'' or ``swim +-qaint'', but it is significantly faster. A search can be +performed on a particular group by using -g with a group +as an argument +

+ +--powersearch is somewhat similiar to ``dpkg +--search'' which searches all files and directories on an +installed system, but it combines --search with the file +and/or directory search, and can also be performed on a not-installed +system. A powersearch is significantly faster than the search +which dpkg provides (even more so when ``swim +--ramdiskon --searchfile'' is used) and even more importantly +provides a logical output of the search (like ``swim -qi +packagename''). By default a search of all directories is not +performed because usually this is redundant except in rare cases. To +enable a search of all directories use the --dir option. +


+

+11.2 NARROWING A PREVIOUS SEARCH + +

+ +--research allows the results of a previous search to be +researched without making the new results permanent. +

+ +--refinesearch allows the results of a previous search to +be researched while making the +new results permanent. +

+ +\d{1,} is a numerical argument to refine or research a +past search from the history. +


+

+11.3 MINOR MODES + +

+ +-n allows the not-installed databases to be searched. +These databases will not exist if the not-installed databases were made +with the FDB argument (see --initndb). +

+ +-g (see -g above and MINOR MODES +, section 9.1). +


+

+11.4 OTHER OPTIONS + +

+ +--no prevents normal output from a search, but does show +how many packages were found. +

+ +See the section ``SPECIFYING THE DATABASES TO USE +, section 9.2'' for options +--arch, -dists. +

+ +See the section ``FTP - VIRTUAL OPTIONS +, section 9.6'' for +--ftp, --source, +--source_only, --diff, +

+ +See the section ``APT - VIRTUAL OPTIONS +, section 9.7'' for +-xyz, --nz, --stdin, +

+ +See the section ``REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS +, section 9.8'' for +--purge, --remove, -r. + +

+ +See the section ``DATABASE LOCATIONS +, section 9.11'' for options +--dbpath and --root. + +


+

+11.5 EXAMPLES + +

+ +swim -gn hamradio --search "radio network/i" --dbpath +/test --arch alpha +

+ +will search the alpha architecture not-installed system databases in the +/test directory for all package information from the hamradio group using +the case insensitive pattern ``radio network''. +

+ +swim --powersearch dpkg -xn +

+ +will search the not-installed system databases for all package information +and all files using the case sensitive pattern dpkg, after which apt-get +will run a simulation of what would happen if it got and installed these +packages. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-seealso.html b/swim.html/ch-seealso.html new file mode 100644 index 0000000..f9ecedc --- /dev/null +++ b/swim.html/ch-seealso.html @@ -0,0 +1,23 @@ + +swim - SEE ALSO + + + +

+swim - chapter 14
+SEE ALSO + +

+ +swimrc(5), apt-get(8), sources.list(5), dpkg(8) +
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch-version.html b/swim.html/ch-version.html new file mode 100644 index 0000000..e7ecc45 --- /dev/null +++ b/swim.html/ch-version.html @@ -0,0 +1,26 @@ + +swim - VERSION + + + +

+swim - chapter 3
+VERSION + +

+usage: swim --version +

+ +This shows the version for the swim program. + +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch10.html b/swim.html/ch10.html new file mode 100644 index 0000000..299c9ee --- /dev/null +++ b/swim.html/ch10.html @@ -0,0 +1,64 @@ + +swim - UPGRADING WITH APT + + + +

+swim - chapter 10
+UPGRADING WITH APT + +

+ +usage: swim --apt +

+ +options: [-xyz] [--upgrade] [--dist_upgrade] +

+ +apt-get provides powerful methods to change an +installion. When these methods are called using --apt, +swim will not allow you to proceed until you are +absolutely sure this is what you want to do. Before using these methods do +a ``swim --apt --update'' so that +apt-get knows the newest versions of available packages. +This major mode requires a combination of -x, +-xz or -xyz to be used along with either +--upgrade or --dist_upgrade. +-x used alone will simulate what would happen if +-xz or -xyz were used (also see -xyz above). + +

+ +--upgrade is somewhat similiar to doing ``swim +-qatxz'' except that it is a more intelligent method because +apt does some behind the scene calculations in regards to +package relationships, in fact the ``swim -qatxz'' +approach will provide totally different results, or maybe these were the +results you really wanted. ``swim --apt --upgrade -xz'' +is the prefered, proper, and built-in way provided by +apt-get to install the newest versions for all packages +installed on your system. This method will not install any newer versions +of packages which would change the install status of other packages. Note: +It is not recommended to combine the query option -a with +-xz or -xyz, but combining the query option +-a just with -x can be educational. + +

+ +--dist_upgrade combines an --upgrade +with the installation of packages which are not installed. This method +carefully examines dependencies, and resolves conflicts, and given these +factors it will upgrade the most important packages before considering the +installation of less important packages. Less important packages will be +installed only if there are not any conflicts. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch12.html b/swim.html/ch12.html new file mode 100644 index 0000000..96fe822 --- /dev/null +++ b/swim.html/ch12.html @@ -0,0 +1,29 @@ + +swim - FILES + + + +

+swim - chapter 12
+FILES + +

+ + Configuration files: +

+ +

+ swimz.list
+ swimrc
+
+
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
12 March 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch13.html b/swim.html/ch13.html new file mode 100644 index 0000000..3cc6a2d --- /dev/null +++ b/swim.html/ch13.html @@ -0,0 +1,29 @@ + +swim - FILES + + + +

+swim - chapter 13
+FILES + +

+ + Configuration files: +

+ +

+ swimz.list
+ swimrc
+
+
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch15.html b/swim.html/ch15.html new file mode 100644 index 0000000..1118d94 --- /dev/null +++ b/swim.html/ch15.html @@ -0,0 +1,20 @@ + +swim - BUGS + + +

+swim - chapter 15
+BUGS +

+Send directly to mttrader@access.mountain.net. +
+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; back. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/ch9.html b/swim.html/ch9.html new file mode 100644 index 0000000..85e92e9 --- /dev/null +++ b/swim.html/ch9.html @@ -0,0 +1,64 @@ + +swim - UPGRADING WITH APT + + + +

+swim - chapter 9
+UPGRADING WITH APT + +

+ +usage: swim --apt +

+ +options: [-xyz] [--upgrade] [--dist_upgrade] +

+ +apt-get provides powerful methods to change an +installion. When these methods are called using --apt, +swim will not allow you to proceed until you are +absolutely sure this is what you want to do. Before using these methods do +a ``swim --apt --update'' so that +apt-get knows the newest versions of available packages. +This major mode requires a combination of -x, +-xz or -xyz to be used along with either +--upgrade or --dist_upgrade. +-x used alone will simulate what would happen if +-xz or -xyz were used (also see -xyz above). + +

+ +--upgrade is somewhat similiar to doing ``swim +-qatxz'' except that it is a more intelligent method because +apt does some behind the scene calculations in regards to +package relationships, in fact the ``swim -qatxz'' +approach will provide totally different results, or maybe these were the +results you really wanted. ``swim --apt --upgrade -xz'' +is the prefered, proper, and built-in way provided by +apt-get to install the newest versions for all packages +installed on your system. This method will not install any newer versions +of packages which would change the install status of other packages. Note: +It is not recommended to combine the query option -a with +-xz or -xyz, but combining the query option +-a just with -x can be educational. + +

+ +--dist_upgrade combines an --upgrade +with the installation of packages which are not installed. This method +carefully examines dependencies, and resolves conflicts, and given these +factors it will upgrade the most important packages before considering the +installation of less important packages. Less important packages will be +installed only if there are not any conflicts. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
12 March 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.html/index.html b/swim.html/index.html new file mode 100644 index 0000000..0a627c9 --- /dev/null +++ b/swim.html/index.html @@ -0,0 +1,162 @@ + +swim + + +

swim

+ +

+0.1 Table of contents +

+ +

0.2 Copyright

+ + Copyright © 1999 Jonathan D. Rosenbaum +

+ + SWIM, including this manual, is free software; you + may 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 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 with the swim source as the file + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +


+swim +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents. +
+
15 June 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swim.pod b/swim.pod new file mode 100644 index 0000000..8e346a7 --- /dev/null +++ b/swim.pod @@ -0,0 +1,1365 @@ +=head1 NAME + +swim - package administration and research tool for Debian packages + +=head1 SYNOPSIS + +swim [options] + +=head1 DESCRIPTION + +B is a powerful I and I for +both an I, and/or I allowing querying of software packages with a +variety of package information options, and powerful searches. Virtual +options which include ftp, installation, and package removal capabilities +can be seamlessly combined with querying or searches. B can be used +on computer systems which either have, or do not have a Debian +distribution installed. + +=head1 COMMAND LINE OPTION SYNTAX + +When you press ``B >`` you will see a listing of command +line options in a particular syntax. This is to help you understand under +what context to use the options. When you enter the options on the command +line, the brackets, parentheses, braces, diamonds, and question marks are +not actually used. + +B + +All command line options for B always start with a +B, except for ``swim +`` which will show the whole listing of +options. A major mode option is surrounded in braces +B<{ major mode option }>. In the case of +{--search} there are the alternative major mode +options {--refinesearch} and +{--research}, but because --search needs +to be used first before either of these two options, +--refinesearch and --research are +surrounded in parentheses (). + +Note: Through the other chapters of this manual B<{}> is +assumed for the B in the +B section shown at the beginning of every chapter. + +Let's take a closer look at this situation: + + {--search ? (--research || --refinesearch) } + +`B<||>' or `B<|>' are used to indicate `B', `B' indicates +`B', indicates an B (a required argument - +see Arguments below), (parenthesis) means `if used, must be used after the +previous required option was used'. Note: for readability C<--research> +and C<--refinesearch> are not surrounded in C<{}>. + +B + +Options to the major mode options are enclosed in brackets B<[ option to +major mode ]>. C >; (assume enter from here on out), +for instance, will show all the command line options without using the +pager. The pager which swim uses can be set in I (see +I). ``C'' will provide brief explanations +of all of swim's options without using the pager. In this case the major +mode option B<{--help}>, and the option B<[-n]> were used. + +B + +Options which have a single dash can be combined with other single dashed +options B<(-qaint)>. Double dashed options need to be entered by +themselves B<(--help --nopager)>, many double dashed options have an +alternative single dash option B<(-n for --nopager)>. The meaning of +options is related to the major mode they are being used with. B<[-n]> +means no pager when called with B<{--help}>, but it's a reference to the +not-installed databases when used with B<{-q --query}>, fortunately most +options do not have double meanings. + +B + +Many options require an argument. Arguments are enclose in diamonds +>. An argument to an option may also be optional in which case +a question mark ``B'' will be placed between the option and the +argument. B<[-l ?> >B<]> illustrates such a situation. B<[-l]> +shows a file listings, and optionally the option B<[--df]> can be use with +B<[-l]> to show an expanded listing. + +B<[--dbpath> >B<]> requires an argument, this time the argument +would not be another option, but rather it is a directory. + +Rule: When an option is an argument to another option it can be written +anywhere, but when a non-option is an argument >; B<(notice no +brackets)> it has to be placed directly after the option. Sometimes, +there may be alternative arguments divided with ``B<|>''. +>; means use argument1 or argument2, but not both. + +Based on what we now know, let's compare this situation to the +B<{--search}> situation shown above: + + [--ftp ? --source | --source_only ? <[--diff]>] + +In this case B<--source> or alternatively +B<--source_only> can be optionally used along with +B<--ftp> because they aren't in parentheses +B<()> (also notice: | was used instead of ||, but means the +same thing ``or''). B<--diff> can optionally be provided as +an argument to either B<--source> or +B<--source_only>. For readability --source and --source_only +weren't enclosed in brackets. + +B + +A B can be typed anywhere on the command +line, and can be an option or text. If global arguments +exist they are placed last after the list of normal +options that can be used with a major mode +option. + +[targets | -S] and [targets|APT|DF] are +examples. {-q}, {--initndb}, and +{--rebuildndb} all use global arguments. + +B + +{-q --query} will generally use zero or more +minor mode options [-afpgn --dir], with +one exception (see QUERYING). + +=head1 VERSION + +usage: B + +This shows the version for the swim program. + +=head1 HISTORY + +usage: B + B + +options: B<[--arch> >B<] [--dists> >B<]> + B<[--n] [--dbpath> >B<] [--root> >B<]> + + + +This shows a shell-like history of searches and the most recent --stdin +edit. History is numbered with the most recent action being 1, and the +earlier actions being of a higher number until the maximum amount of lines +set in the HISTORY variable in swimrc(5). A separate history is kept for +each architecture-distribution. + +=head1 MAKING INSTALLED SYSTEM DATABASES + +=head2 Initial database making, and Rebuilding for an Installed system. + +usage: B + B + +Options: B<[--dbpath> >B<] [--root> >B<] [--lowmem]> + B<[--split_data> >B<]> + +An I is one in which packages are installed +using B or some front-end to B like B or B; +B supports installation through B. These major modes are for a +computer with an I and make the databases +which allow querying and searching capabilities for the installed +distribution. + +B<--initdb> is run when the databases do not exist yet, B<--rebuilddb> is +run if the databases have become corrupt, or you want to rebuild the +databases instead of updating them. + +B<--dbpath> can be specified as an alternative location for where the +databases will be made. The default location is "F". An +argument like "F" could be provided, and then the databases +would be made here instead. + +B<--root> allows a database to be made for a Debian distribution installed +on a different partition. If the distribution is mounted on +F, "F" would be the argument to root. The +databases would be made for the Debian distribution installed on the +"F" partition. + +B<--dbpath> and B<--root> can be used together. Given the previous two +examples, the databases would be made on "F", +assuming "F" actually existed. + +B<--lowmem> uses a method which uses a small amount of memory to make the +databases. By default B<--initdb> and B<--rebuilddb> use a method which +fully takes advantage of memory, this is a good thing, because it means +the databases are made in a quicker manner. On a computer with a K6-200 +CPU, 64MB of memory, and 1500 installed packages, the databases can be +made in 4.5 minutes using the default method, and 11 minutes using the low +memory method. The high memory method is the default because in general +the size of a distribution is related to how much resources a computer +has, and probably a large installation is unusual. If you get an "out of +memory" when you use the default method, or if your system is overloaded +to begin with, the B<--lowmem method> is the prefered way. + +B<--split_data> determines the size of the files in the temporary +directory used to contruct the database. The default is 25000 lines per +file. If you are using the B<--lowmem method> you may want to provide a +different argument to B<--split_data>, like "B<--split_data 10000>". This +is a subject of experimentation. + +=head2 UPDATING + +usage: B + +options: B<[--dbpath> >B<] [--root> >B<] [--check]> + +B<--db> allows you to update the databases by hand when packages have been +removed, added, or changed. swim will automatically run B<--db> under +certain conditions. + +B<--check> prints out the changes to STDERR, and the total to STDOUT +without proceeding with the update. + +See B<--initdb> for options B<--dbpath> and B<--root>. + +=head2 REBUILDING THE SEARCH + +usage: B + +options: B<[--dbpath> >B<] [--root> >B<]> + +swim makes the flat databases F and F for +doing I. Instead of rebuilding these databases everytime +B<--db> is run, new information is just appended to these databases, and +old information is kept. Generally, this is not a problem because only +files and directories which the other databases actually know something +about will be refered to. But in a situation where a file has changed +into a directory, the I may not work properly, because the +old file name remains in F, and the new directory name is +now in F directory. In general, it takes a lot of changes +to the installed system before it is really becomes necessary to rebuild +the flat databases. This process takes less than a minute on a K6-200 +with 1500 packages. + +See B<--initdb> for options B<--dbpath> and B<--root>. + + +=head2 FILES + +Databases which are made: + + packages.deb + fileindex.deb + statusindex.deb + groupindex.deb + searchindex.deb + dirindex.deb + +=head1 IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED DATABASES + +=head2 A. downloading the important databases with --ftp. + +usage: B + +options: B<--Contents> > + B<--Packages> > + B<[--dists> >B<] [--arch> >B<]> + B<[--onec] [--Release_only]> + + +=head2 OVERVIEW + +B provides a method so that all information about an existing Debian +distribution is quickly accessible through databases. Debian already +provides flat file databases for all its distributions. One database +called "F" provides a complete listing of all the +files associated with each package, the other much more important database +called "F" provides everything from the Package's description, +to all the dependencies for that package. The Packages database is a +crucial database for other important Debian administrative tools like +B and B. + + +=head2 DISTRIBUTION DEFINED + +Debian Distributions choose a name which reflect the development state of +that distribution. The distribution named "I" is where the +majority of the development processing occurs, after I has +reached a certain level of maturity, it's copied over to a new +distribution called "I" which is tested extensively before +becoming the new "I" distribution. The I +retains the I of the I, and +the I receives a new I. +Eventually, I becomes I, and at this point both I, +and the older I are removed. Code names are +associated with the I given for each of the +distributions. This is much better for mirroring Debian sites. + +B was designed to ignore these code names, and instead shows the +user the I associated with the distribution. Swim +users must always use the real distribution name, or swim will not work +properly. This is a nice feature because it allows user to make decisions +related to the management of their databases, and makes research much more +easier. + +The other Debian distribution which swim recognizes is I. +This distribution I, and +contains packages which are considered risky because of their development +level. + +=head2 SECTIONS + +Each Debian distribution has sections related to the relationship of each +of the packages to the I. In "I
" there are +packages which have a correct relationship with these Policies. Packages +in "I" comply with the I (I found in the I) but have various +limitations like requiring a package which is found in non-free, or is not +in the Debian archive. Packages in "I" do not comply with the +I but are electronically distributable across international borders. +The "I" section is found outside of the United States and exists +for packages which have export restrictions. + +=head2 ARCHITECTURES + +Distributions also have architecture specific sections since not all +packages compiled for one architecture can run on all other +archictectures, however, there are a large percentage of packages which do +run on all architectures. The architectures are I, I, +I, I, I, I, and more recently I +which represents packages for the hurd GNU kernel for the i386 +architecture. + +=head2 SWIMZ.LIST + +B<--ftp> uses a file called F which has the same type of +format (see format below) as the F which B uses. +There are some differences. The B mentioned above +requires that the distribution names never should be the code names for +the I. B, B only retrieves databases +specific to one archictecture, normally the one you are running B on. +With B though you can fetch databases for any, or every architecture +by adding the architecture to "deb" with a hyphen (deb-hurd-i386). If deb +has no architecture appended it is assumed that the architecture you want +is the same as the system you are running B on. B, at this +time B only supports the ftp method. B, you can change +F as often as you want without worrying about databases being +removed so that that the F and the downloaded databases match. +This would occur with B F if you removed a site. +B, databases are kept in a compressed state. B, because +the list is used for both Contents and Packages, more flexibility is +provided by only allowing the default distribution/archictecture or +distribution/architecture provided on the commandline to be downloaded. + +For B users: If you are using B, and B together it is a +good strategy to use the real distribution name in the F, +and to have an exact copy of the F ftp sites in the +F. Packages databases specific to the architecture B is +using can be retrieved using B (this also will keep +track of the Release version), and then B can be used to fetch the +architecture specific F as shown below. It should also +be of interest to note that Packages downloaded by either swim or apt can +be used interchangeably by using 'cp -a' and 'gzip -d' or 'gzip -9'. + +Here is a brief outline of the format required by F. + +B + +B - represents a standard Debian distribution. And is simply written +as deb or with the architecture appended (B or B). + +B - Universal Resource Identifier is exactly how you would enter an +address into a web browser. This address is the base of a Debian +distribution, generally this is right before the directory called +"F". So if F is found in F, and the +site is B then the uri would be +F. + +B - This can be I, I, I, +I. Distribution can also be a path which must end with a +slash like F. This is used when there is no section +as in the experimental distribution or in sites which do not have symlinks +to the non-us section. No section would be mentioned in this situation. + +B
- I
, I, I, I (write it this +way). + + +=head2 SWIMZ.LIST EXAMPLES + +Examples (each on one line): + +B + +This will fetch the alpha databases from somewhere.com for the unstable +distribution for the main, contrib and non-US sections. + +Note: In these next two examples you can not append any architecture to +deb with a hyphen. + +B + +This will fetch the experimental database, but there is +not a Contents-(architecture) database for this distribution. Notice that +it ends with a slash. + +B + +This will fetch the i386 databases for the stable distribution for non-us, + +=head2 FTP OR APT? + +How you use major mode B<--ftp> depends on your goals. Even if you are +using B, you may be interested in keeping tabs on different +architectures. In this case you would have to download the I specific to these architectures. If you are only interested in +the architecture which B is interested in, then you only need to use +B<--ftp> to fetch the I. But, because it isn't a +requirement to set up a virtual filesystem, you are not required to fetch +the Contents database. The B of fetching the Contents +database is determined by the method you choose to make the database (see +C<--initndb>). These advantages include the ability to I associated with a package, the ability to +I to find out which packages relate to them, +and the ability to perform a I on all the files and +directories to find the associated packages. + +=head2 OPTIONS + +B If you want to download a different +distribution/architecture other than the default specified in your +configuration file, you must specify this on the commandline. + +B<--Packages> determines where you want the Packages database as well as +the Release data put when they are downloaded. The B implies +that the databases will be put in your default directory (see swimrc(8)). +These databases can later be located by the major modes B<--initndb and +--rebuildndb> just by using B as an argument. Alternatively, these +databases can be put in any directory you choose by providing a +B. + +B<--Contents> determines where you want the F +database(s) put. (see --Packages). + +B<--onec> will download only one Contents-arch per +distribution/architecture specified on the commandline or by default. + +B<--Release_only> will download only the Release data for the +F or particular F mentioned on the command line. + +B<--dists> will only find the distribution which corresponds to the +argument provided this option. + +B<--arch> will only find the architecture which corresponds +to the argument provided this option. The different architecture needs to +be specified in swimz.list with a hyphen and the architecture appended to +deb (deb-(arch)). + +=head2 B. downloading the important databases with apt, and maintenance +options. + +usage: B + +options: B<[--update] [--clean] [--autoclean] [--check]> + +Please read "B" for +more information. + +B<--update> calls B to download the Packages databases. + +B<--clean> is a call to an B option to remove any packages stored in +B storage area for downloaded packages. The default for this +storage area is F + +B<--autoclean> will only clean out packages which are not +found in apt's cache. + + +B<--check> tests and updates apt's cache. + + +=head1 MAKING NOT-INSTALLED DATABASES + +usage: B + B + B + +options: B<[--Contents> >B<]> + B<[--main] [--contrib] [--non-free] [--non-us]> + B<[--arch> >B<]> B<[--dists> >B<]> + B<[--dbpath> >B<] [--root> >B<] [--alt]> + B<[--split_data> >B<] [-v] [--cron]> + B<[targets|APT|DF]> + +=head2 OVERVIEW + +The B provides swim with many capabilities like +the searching, and querying of packages which do not actually exist on the +live filesystem, as well as the ability to seamlessly install packages +while searching or quering, or the ability to fetch the packages source +code. The I is optional, but it is highly recommended. +These two major mode options set up these databases, after determining the +level of interaction which you want. + +Whenever B makes databases it thinks only in terms of one +distribution and one architecture. This keeps things logical. B +does have the ability to take Packages files with multiple architectures, +and distributions, and to extract information for one distribution and one +archictecture to make its databases. This could provide interesting +information from dumps from B (C). + +B<--initndb> creates the initial not-installed databases for a particular +architecture and distribution, and B<--rebuildndb> remakes the +not-installed databases for that same architecure and distribution. If not +otherwise specified B I it finds in F +to determine what architecture and distribution you want to use to make +B databases. Otherwise... + +=head2 OPTIONS + +B<--arch> allows an argument to override the B found in +F. + +B<--dists> allows an argument to override the B found in +F. + +B<--alt> is used for a distribution with a Debian archival +structure, but which has a different name. This allows for alternative +distributions. + +When B or B are provided as arguments (see below), by default the +F which pertain to the sections found in F will be +shown. If you only want certain sections you may specify them on the +command line. If you are not using B or B, it is a good idea to +make sure that either the sections found in F or the sections you +put on the command line match the F you a targetting because +this is much more effecient. + +B<--main> will override the sections found in F, and will use this +section. + +B<--contrib> will override the sections found in F, and will use +this section + +B<--non-free> will override the sections found in F, and will use +this section + +B<--non-us> will override the sections found in F, and will use +this section + +Global arguments B must be used with either of these two +major modes to find the F databases. targets can be a full path +to one or a set of F. B will use the F found in +F, and B will use the Packages found in the +default directory for B (see C<--ftp>). If you use either B or +B you will be given an B which allows you to choose one +F database for each section you would like to use from the +various sites. This B shows the B, B, B and +B for each F. + +B<--cron> allows you to override the B produced when B or +B is provided as an argument. This is useful if you want to automate +the database making process. B<--cron> will choose the newest +database(s), if cron notices that the Release version has changed, cron +will not proceed, but will provide a warning instead. This allows you to +make the appropriate changes and choices. + +B<--Contents> can be give one of four arguments: + +B<1).> If you have a F database in a target +location you know about you may provide a path to the location. The +F database can be compressed. + +B<2).> If you prepend the path with the letters B (meaning flat +database) when the databases for swim are made, instead of using the +Contents database to make: + + nfileindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + +only the F database will be made which +allows the ability to view file/dir listing for not-installed packages, +but does not provide the virtual file system or powersearch capabilities +which the other databases would have provided. + +B<3).> The argument B may be used if you have used B<--ftp> with the +B argument to the option B<--Contents> (see C<--ftp>). In this case +it is assumed you are also using global arguments B or B for the +Packages databases. This will give you an B (if --cron isn't +used) allowing you to choose one F database for the particular +distribution you want to make the databases for. + +B<4).> B does the same exact thing with B as it does with the +before mentioned B, and provides the B. + +B<-v> will only work if you have dpkg installed. It allows swim to verify +B own built-in version comparison function with B. This is good for debugging purposes, and produces a +report called F<.version_compare> in the same location that B +databases are made. + +B<--split_data> is only advantageous if B<--Contents> is being used. See +B<--initdb> for more information about the B<--split_data> option. + +See C<--initdb> for options C<--dbpath> and C<--root>. + +=head2 UPDATING + +B<--ndb> has the same options as --initndb and --rebuildndb except for +--split_data. It also has a new option B<--nue> which will never have to +be used unless the experimental distribution or non-us section are found +in Contents (which presently isn't the case). B<--check> prints out the +changes to STDERR, and the total to STDOUT without proceeding with the +update. B<--status_only> can be used after a new package has been +installed to update the status, after which -qni and -qi will correlate +properly. + +=head2 REBUILDING THE SEARCH + +B<--rebuildflatndb> serves the same purpose that --rebuildflatdb serves. + +=head2 FILES + +Databases and reports which are made (arch = architecture dists = +distribution): + + npackages-arch-dists.deb + nfileindex-arch-dists.deb requires --Contents + nstatusindex-arch-dists.deb + ngroupindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + ncontenstsindex-arch-dists.deb.gz requires --Contents + .packagesdiff-arch-dists.deb requires --Contents + +=head1 PREPARING YOUR INSTALLATION FOR APT + +usage: B + B + B + +If you are using B with B, and this is the first time you are +using it with your installation, check your live installation with this +major mode. This is a call to B, and will show any +packages which are not properly configured or installed. If you get any +output, make corrections. The goal is to get absolutely no output +whatsoever because it is under these conditions that apt will work +properly. See the B<--purge>, B<-r>, B<--remove> options for B<-q> to +remove the offending packages. You may have to remove the package by hand +under unusual situations like when it is not just dependencies (see C<-T>) +between packages keeping the package from being removed perhaps due to a +broken script (see C<--scripts>). In an extreme case you could manually +remove the entry for this package from the F +database, and hunt down and remove all the files associated with the +package with B option. When you are done if you still want +some of the packages you removed, use B to reinstall them with +B option. Also, B provides its own built-in method to +clean up your system, and will provide instructions, but you still may +have to do some of the cleaning yourself as discussed above. + + +=head1 QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES + +usage: B + B + B + +options: B<[--total -t] [-i] [-l ?> >B<] [-d] [-c]> + B<[--scripts] [--preinst] [--postinst] [--prerm]> + B<[--postrm] [-v] [--dbpath> >B<] [--menu -m]> + B<[--shlibs] [-T] [--pre_depends] [--depends> + B<[--recommends] [--suggests] [--conflicts]> + B<[--replaces] [--provides] [--md5sum]]> + B<[--copyright] [--changelog] [--allgroups]> + B<[--arch> >B<] [--dists> >B<]> + B<[--ftp ? --source | --source_only ?> >B<]> + B<[--stdin] [--extract> >B<]> + B<[-xyrz --remove> >B<] [--purge] [--apt2df]> + B<[--df2apt] [--root> >B<]> + +global arguments: B<[targets | -S ?> >B<]> + +Quering almost always involves using B<-q or --query> with zero or one or +a combination of the B (package specification +options), and one or more (only one for C<-g>) targets specific to the +minor mode, or the results of a search (C<-S>). [C<-S> can be provided a +numerical argument pertaining to the past history.] This can be combined +with one or more options. The one exception is "B". + +B<--query or -q> can be used by itself or with B<-n> to query known +package names or package names with versions. "B" would produce the output: + + test1_1.0-2 + test2_0.3-1 + + +=head2 MINOR MODES + +B<-n> is the minor mode option to access the I, it +can be combined with the minor mode options B<-a>, B<-g>, B<-f>, or it can +be used by itself. + +B<-a> allows I on an installed or not-installed (B<-n>) +system to be queried. "B" will show all the package names with +versions for the not-installed system + +B<-f> allows I to be queried, when used without any +options the package name with version is shown. B<--dir> will only query +directories, this is useful if you are not sure whether what you are +quering is a directory or a file. When a directory is queried, swim shows +all packages which exist below the queried directory. "B" is +exactly the same as "B". Hint: "B" and "B" are quite different, the first shows all packages which exist below +the current directory, and the second will show the package which each +file in the current directory comes from. + +B<-g> will query a I (also called a section, see C<-i>)) of +packages. Groups represent subjects which packages with similiar +characteristics are catagorized by. To view all the groups found in an +installed or not-installed system use "B" or "B". "B" or "B" +shows all the package names for the hamradio group. + +B<-p> is used to query a I, these packages are +distinguished by their "deb" ending, but swim can tell whether a file is a +debian package even without the ending. Called without any options the +package name with version will be shown. + + +=head2 SPECIFYING THE DATABASES TO USE + +B<--dists> will use the databases for the argument given, otherwise the +databases pertaining to the value found in swimrc will be used. + +B<--arch> will use the databases for the argument given, otherwise the +databases pertaining to the value found in swimrc will be used. + +Example: B + +Assuming these databases exist this will show all packages and their +versions for the unstable distribution and architecture hurd-i386 even if +the values in F are i386 and stable. + +see C<--ftp> and C<--initndb> for more information about the databases. + + +=head2 OPTIONS + +B<--total or -t> are I. The +output suppressor will not show output if a certain number of packages is +exceeded, instead it will show the number of packages you are querying. +This is useful for two reasons, first, knowing the number of packages you +are quering can be very informative, second, it gives you a chance to add +to the command line a pipe to a pager, ex: "B". You can +set the number that the output suppressor works at as high or low as you +want in the F file. By design the B<-t> option will have to be +used if the B<-i> option is used and more than one package is being +queried. This option can also be used to alter the output of the script +related options (see C<--script>). + +B<-i> provides I about each package being queried. The +format differs slightly for the installed packages versus the +not-installed packages. See FORMAT: + +B<-l> provides a listing of the files associated with a package. If the +option B<--df> is provided as an argument, all the directories associated +with package will be shown. It is important to remember that many +packages provide directories which become important to them after they are +installed, so the option B<--df> often provides necessary information +which B<-l> called by itself would have not. + +B<-d> shows the documentation which the package provides found in +F, F, F. Other documentation which +the package may provide in a non-standard location will not be shown. +B<-d> takes precedence over B<-l>, so if B<-l> is used on the command line +with B<-d>, only the output for B<-d> will be shown. + +B<-v> is a special option which works only with the minor mode B<-p>. It +can be used with B<-l>, B<--df>, B<-d>, to show the packages files and/or +directories in long format (C). + +B<-c> will show the configuration files packages use. If the package does +not have a configuration file then nothing will be shown. The output will +show the file and its path indented one space with the B. +This will not work with B<-n>. + +B<--scripts> shows all scripts associated with a package with the name of +the script presented before each script in this way +B<#####scriptname######>. If the scripts are called individually by using +the script options B<--preinst>, B<--postinst>, B<--prerm>, or B<--postrm> +no title is shown, this is nice for writing to a file. If B<-t> is used +with the individual script options a title will be shown, this makes sense +because normally only individual packages would be queried to write a +script to a file, and B<-t> wouldn't be used in this situation. Scripts +are the soul of Debianized packages allowing packages to be installed, +configured, and removed seamlessly and cleanly under all kinds of +conditions. These options do no work with B<-n>. + +B<--menu or -m> is used to view menufiles which belong to various +packages. If the package does not have a menufile nothing will be shown. +This option can be useful in troubleshooting a menu entry which does not +seem to work, or in finding out where the menu entry is. I is a centralized program which interacts +with all kinds of menus. I "B" which comes with the menu package to find out more. This will not +work with B<-n>. + +B<--shlibs> shows a list of shared libraries certain packages supply. The +I (packaging-manual) provides detailed +information about the format of a shlibs file. This will not work with +B<-n>. + +B<--copyright> does a case insensitive search for copy or license in the +F directory. This should show how the package +relates to I. + +B<--changelog> searches for any files in F which +look like changelogs. Debian packages always have a I +changelog for the package. There may be a separate changelog kept by the +author of the program. + +=head2 PACKAGE RELATIONSHIPS + +B<-T> shows all the package relationships of packages. Individual package +relationships can be viewed using B<--pre_depends>, B<--depends>, +B<--recommends>, B<--suggests>, B<--replaces>, B<--conflicts> or +B<--provides>. Package relationships are the spirit of Debian packages, +here is a quick overview briefly reiterating what can be found in the +I. I set these +relationships in control file fields of the same name. + +=head2 Dependencies + +I - means that the pre-depended package or packages must be +installed before the queried package can be installed. Most packages +which have pre-dependencies are usually essential and required packages. + +I - declares an absolute dependency to another package or +packages either I. The queried package cannot function +without this other package. + +I - declares a strong, but not absolute dependency to another +package or packages either I. You would usually find the +recommended package together with the queried package in a normal +installation. + +I - can be one or more packages either I which +would be useful to the queried package, but are not necessary. + +=head2 Alternative Packages + +I - is a package or packages either I +which would cause problems with the queried package, and would not be +allowed to be installed while the queried package was installed. + +=head2 Overwriting files and Replacing Packages + +I - allows the queried package to replace another package or +packages by overwriting their files, after which the previous package +would be considered to have disappeared. Essentially this allows the +queried package to take over the package or packages. In a situation +where there was a Conflict between the queried package and these packages +this field would help determine which packages should be removed. + +=head2 Virtual Packages + +I - declares a virtual package which may be mentioned in +I, I, I, or I. I allow one or more packages to share the same name of another +package, which means if the queried package has a reference to a virtual +package in one of the before mentioned package relationship fields, then +whatever packages provide the virtual package are also being listed. + +B<--md5sum> checks B. It can be used with B<-l>, B<-d>, +B<-c>, or B<-p>. If there are checksums available the md5sum result will +be either B, B, or B. B means that although +a checksum exists, the file can not be found. The result is put after the +file and its path and the B or the package name and version +and the B. + +=head2 FORMAT + +B<1). Installed system> + + Package: name Status: hold ok installed + Version: 1.1-1 Essential: no + Section: namers Priority: extra + Installed-Size: 10 Source: generatename (2.0-1) + Maintainer: name + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + +B<2) Not-installed system> + + Package: name Status: r> hold ok installed (1.1-1) + Version: 1.1-2 Essential: no + Section: names Priority: extra + Installed-Size: 11 Source: generatename (2.0-1) + Size: 43000 Architecture: i386 + Distribution: experimental + Maintainer: name + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + +There are several things to point out. The difference between the two +outputs relates to the addition of the Distribution, Size, and +Architecture fields for the not-installed query. Installed-Size is how +many kilobytes the package will occupy when it is unpacked, whereas Size +is the size in bytes of the package. + + +=head2 STATUS FIELD + +The Status field provides the installation status of the package, this +holds true for the not-installed query as well. In a sense, the +not-installed database isn't always not-installed. If the not-installed +package is actually already installed, and the version numbers are exactly +the same, then the status will be the same for either query. If the +not-installed package is not installed then the status will be +"not-installed". In cases where the not-installed package is already +installed, swim uses it's comparison function to figure out whether it is +a newer of older package which is installed. In the above example, swim +realizes the same package is installed, and only the debian-revision has +changed, hence the only difference is that the revision number is greater +"r>" for the not-installed package. When only the debian-revision has +changed it can safely be assumed that the author (creator, programmer) of +the same program has not made any changes to the same program, but the +Debian maintainer has made a change to an aspect of the package like a +change in the script the package uses to properly install. You may have +also noticed that the status field shows the version number of the +installed package enclosed in parenthesis. + +=head2 SOURCE FIELD + +The Source field is present in these examples, but the Source field will +not always be present for packages. In cases where the name of the source +package is the same as the the name found in the Package field, and the +version number of the source package is also the same as found in the +Version field, then there will be no Source field. In the above examples +there is a Source field. In this case name was probably one of many +packages generated from the source package called generatename. In this +particular example generatename also has its own unique version number +2.0-1 enclosed in parentheses, if no version number had been mentioned +then the source package would have the same version number as found in the +Version field. + +=head2 SECTION AND PRIORITY + +Section shows the subject which a package is categorized with (see C<-g>). +Priority shows how important the package is to have installed. In the +case of the not-installed databases the information for these fields is +almost always available from the Packages databases, but this is not +always the case for Debian packages. For packages which do no provide +this information swim will do its best to fill in the blanks from +information found in the installed and not-installed databases. If proper +information can not be found it will be indicated as "unavailable" or +"unknown." Unavailable would indicate that information about the package +exists, but it is from a different version (includes debian-revision), and +no information exists for this version. Unknown means no similiar package +exists, and there is absolutely no information about this package in the +databases. + +=head2 DEBIAN PACKAGE OUTPUT + +When a Debian package is queried using the B<-p> option you will get +output like the first example shows, the status field is also calculated. + +=head2 VIRTUAL OPTIONS + +=head2 FTP + +For ftp capabilities swim uses the F to determine which sites +it will check for the requested packages. The first site which fills the +request will be used, otherwise B will go through all the sites +avoiding repeats, and if no sites can fill the request, B will +either quit or proceed on to check for another request. + +B<--ftp> allows the queried package, its source package, or just the +source package diff to be downloaded while being queried. This is refered +to as virtual downloading because the quering and the downloading are +seamless as though the package already exists locally. This has to be +used with the option B<-n> because packages which which are not part of +the not-installed database are considered to already have been downloaded. +Packages which are already installed can be downloaded or their source +retrieved by setting up a database which corresponds to these packages; if +the installed packages belong to the stable distribution, set-up the +not-installed stable databases. + +Packages or source code are placed in an area below the default directory +mirroring the remote directory they were downloaded from after their size +and modification times are checked for correct values. This area is +called the B directory, and although this directory mirrors remote +directories, it is not an exact mirror, but specific to the requirements +of swim because code names for Release versions are not taken into +account. For real mirroring capabilities there exist many excellent +programs. If a package has a B, B<--md5sum> will +automatically be run and the value shown. Regardless of whether or not +the md5sum check is B or not, the package will still be put in the +B directory to allow the package to be looked at, so watch the output +from B<--ftp> to check for B. + +Packages or source code packages will not be downloaded again if they are +found in the B directory unless their I has changed +in the not-installed database, if the packages are not in the DF directory +and the remote I is different than the not-installed +I then the packages will not be downloaded until the +not-installed database is updated or rebuilt to reflect the version +change. Changes in the package's I indicates that the +author(s) of the program have made changes to the computer code for the +program contained in the package or the source code package. On the other +hand, swim will check for a I change at the remote site +if the package can not immediately be found. If the package's +I has changed and the package does not exist locally in +the B directory, it will be downloaded. This is a nice feature, +especially for the unstable distribution, because it tends to extend the +time needed before the not-installed database has to be updated or rebuilt +to match the changes at remote sites. + +B<--source> is used with B<--ftp> to download the source code package. +B<--source_only> will download the source code package without the deb +package. I. The I which ends in "dsc", the I which is a +compressed tar file, and the I showing the changes +necessary to make the original source into Debian source. The diff can be +downloaded by itself if B<--diff> is provided as an argument to B<--source +or --source_only>. + +For B users: B allows packages to be downloaded, but if more +than one package is required for the package relationships to be proper, +B will download all these packages. B<--ftp> allows specific +packages to be downloaded, packages from other architectures, and source +packages to be downloaded, here lies the advantage of this option over +using B<-xyz --nz> (see below). If a particular package has been +dowloaded into the B directory and it is needed by B for +installation, simply copy or move the package from the B directory to +F before running B, and the package will not +be downloaded by B again; future versions of B will have an +option to automatically accomplish this (see C<--df2apt>). + +=head2 APT + +apt-get(8) is a nice package relationship checker from the B package +which figures out what needs to be done to properly install a package or +packages when one or more package names are provided to it. B +will get all packages which are needed using a variety of methods, and +then B interacts with B in a way which allows for a +successful installation. + +B<-xyrz, --remove and --nz> can be used if B from the B +package is installed. These options allow for what is refered to as +virtual installation/removal. It is prudent to always test what will +happen by using the B<-x> option alone before actually proceeding with the +installation with the B<-z> option. B<-x> will actually simulate what +would happen in an installation, showing which and how many packages will +be changed, which and how many new packages will need to be installed, +which and how many packages will need to be removed, any conflicts, and +what needs to be configured. B<-y> will automatically answer yes to any +prompts B may produce allowing B to run +non-interactively. B<-z> as mentioned before actually proceeds with the +installation using B after the B gets the packages. You +can append a minus sign to a package name to cause it to be removed. +B<--nz> when used as an optional argument with B<-xz or -xyz> will only +download the packages into F or into whatever +directory you configured for holding archives for B. + +B: B makes it so easy to make changes to your +installation that it is highly recommended to do your research with swim +first. This can be done by checking package relationships, file/dir +listings, comparing the not-installed package to an installed package if +such exists, checking B<--md5sum> and B<-c> for the installed package, and +checking the Source field by running a B<--search> (see below) to check to +see how the source package has been split into binary packages for the +not-installed package versus an installed package if such exists. +Ofcourse, there are many other things you could look at, and you can +always do your research after the fact. Presently B<--db> is run only by +hand, so you can check the old state after an installation if you have not +already run B<--db>, yourself. + +=head2 REMOVING AN INSTALLED PACKAGE + +B<--purge> uses B to remove an installed package or packages and the +configuration files as shown with "B". + +B<-r or --remove> removes an installed package or packages with B, +but not the configuration files as shown with "B". +You may also append a plus sign to a package name to cause it to be +installed. This option is used with -x or -x(y)z. + +=head2 STDIN + +B<--stdin> works with either B<--ftp>, B<-x>, B<-xyz>, B<-xz>, B<--purge>, +B<-r>, or B<--remove>. + +B<--stdin> provides the I commonly found in shells +allowing you to edit what is on the command line. You can edit the command +line, press enter and then recall the history, and make more changes, or +I. To find +out more about what readline commands your shell supports please read the +man pages which apply to your shell. Information for the bash shell can +be found in bash(1) under the title "B". + +Example: "B" will list all the packages from +the not-installed hamradio group on the command line, this list can be +edited then submitted to B for a simulated installation. Another +instance of B can be run at the same time, perhaps "B" to help in making editing decisions for B<--stdin>. + +=head2 PACKAGE MANIPULATION + +B<--extract> only works with the B to extract parts or all +of a Debian package. If the B is provided then I below the current directory in the +exact directories found in the package. A particular I below the current directory by I as shown by "B" or "B" +as the argument. Alternativily, a I regardless of its proper location by I shown by "B" or "B". Notice the backslash +before the exclamation point, this is because shells consider ! a special +character, so it has to be backslashed so that the shell knows that it is +not such a special character. Example: "B" will extract the binary name +in the current directory from the name package, show information for the +name package, and show any scripts for the name package. + +=head2 DATABASE LOCATIONS + +B<--dbpath> can be specified as an alternative location for where the +databases would be found. The default location is "F". An +argument like "F" can be provided, and then the databases +would be found here instead. + +B<--root> allows a database to be found for a Debian distribution +installed on a different partition. If the distribution is mounted on +F, "F" would be the argument to root. The +databases would be found for the Debian distribution installed on the +"F" partition. + +B<--dbpath and --root> can be used together. Given the previous two +examples, the databases would be found on "F", +assuming "F" actually existed. + + + +=head1 UPGRADING WITH APT + +usage: B + +options: B<[-xyz] [--upgrade] [--dist_upgrade]> + +B provides powerful methods to change an installion. When these +methods are called using B<--apt>, B will not allow you to proceed +until you are absolutely sure this is what you want to do. Before using +these methods do a "B" so that B knows the +newest versions of available packages. This major mode requires a +combination of B<-x>, B<-xz> or B<-xyz> to be used along with either +B<--upgrade> or B<--dist_upgrade>. B<-x> used alone will simulate what +would happen if B<-xz or -xyz> were used (also see C<-xyz> above). + +B<--upgrade> is somewhat similiar to doing "B" except that it +is a more intelligent method because B does some behind the scene +calculations in regards to package relationships, in fact the "B" approach will provide totally different results, or maybe these +were the results you really wanted. "B" is the +prefered, proper, and built-in way provided by B to install the +newest versions for all packages installed on your system. This method +will not install any newer versions of packages which would change the +install status of other packages. Note: It is not recommended to combine +the query option B<-a> with B<-xz or -xyz>, but combining the query option +B<-a> just with B<-x> can be educational. + +B<--dist_upgrade> combines an B<--upgrade> with the installation of +packages which are not installed. This method carefully examines +dependencies, and resolves conflicts, and given these factors it will +upgrade the most important packages before considering the installation of +less important packages. Less important packages will be installed only +if there are not any conflicts. + +=head1 SEARCHING + +usage: B + B + B + > + +options: B<[-g] [-n] [--dbpath> >B<] [--root> >B<]> + B<[--arch> >B<] [--dists> >B<]> + B<[--ftp ? --source | --source_only --diff]> + B<[-xyrz --remove ?> >B<] [--stdin] [--apt2df]> + B<[--no] [--df2apt] [--purge] [>B<\d{1,}>B<]> + + B<[--dir]> and no B<[-g]> for B<--powersearch or --ps> + + +=head2 OVERVIEW + +B provides two major types of searches. A search with B<--search> +I, and a search with B<--powersearch or +--ps> I. + +The results of either of these searches can be I by running +a test search with B<--research> (this step can be skipped) and/or setting +the results in stone with B<--refinesearch>. B<--search> can be +I initially by specifying a particular I, and +B<--powersearch> can be I initially by specifying that +I be searched as well as files. Both searches can I which the major mode B<-q or --query> use. +Generally, it is preferable to run a search, and then to provide the +results of a search (B) as an argument to B<-q or --query>; this +allows the results of a search to be queried. Every time a search is run +the results are appended to the history, past searches can be refined or +researched by providing the numerical argument pertaining to the history. +\d{1,} is simply Perl notation meaning a number with one of more digits. + +I (see perlre(1p)) can be used to define the pattern +(string) provided as an argument to a search. Do not surround a pattern +in slashes, a slash is only used after all patterns and before the +I (swim supports these two modifiers). To search +for more than one pattern, patterns are separated with I. +Patterns may include I, also found in +egrep(1). + +If a search finds any packages which match the search, the package +information will be displayed as the package is found. The package will +only be shown once regardless of how many times it is found while the +search progresses. When the search is over the number of packages found is +shown. + +B<--search> provides a search of package information. This is similiar to +grepping "B" or "B", but it is significantly +faster. A search can be performed on a particular group by using B<-g> +with a group as an argument + +B<--powersearch> is somewhat similiar to "B" which searches +all files and directories on an installed system, but it combines +B<--search> with the file and/or directory search, and can also be +performed on a not-installed system. A I is significantly +faster than the search which B provides (even more so when "C" is used) and even more importantly provides a +logical output of the search (like "C"). By default +a search of all directories is not performed because usually this is +redundant except in rare cases. To enable a search of all directories use +the B<--dir> option. + +=head2 NARROWING A PREVIOUS SEARCH + +B<--research> allows the results of a previous search to be researched +without making the new results permanent. + +B<--refinesearch> allows the results of a previous search to be researched +while making the new results permanent. + +B<\d{1,}> is a numerical argument to refine or research a +past search from the history. + +=head2 MINOR MODES + +B<-n> allows the not-installed databases to be searched. These databases +will not exist if the not-installed databases were made with the FDB +argument (see C<--initndb>). + +B<-g> (see C<--search>) + +=head2 OTHER OPTIONS + +B<--no> prevents normal output from a search, but does show how many +packages were found. + +See the section "B" for options +B<--arch>, B<-dists>. + +See the section "B" for options B<--ftp>, +B<--source>, B<--source_only>, B<--diff>, B<-xyz>, B<--nz>, B<--stdin>, +B<--purge>, B<--remove>, B<-r>. + +See the section "B" for options B<--dbpath> +and B<--root>. + +=head2 EXAMPLES + +B + +will search the alpha architecture not-installed system databases in the +/test directory for all package information from the hamradio group using +the case insensitive pattern "radio network". + +B + +will search the not-installed system databases for all package information +and all files using the case sensitive pattern dpkg, after which apt-get +will run a simulation of what would happen if it got and installed these +packages. + + +=head1 RAMDISK + +usage: B + B + +options: B<[-n] [--searchfile] [--arch> >B<]> + B<[--dists> >B<] [--dbpath] [--root]> + + no options for B<--ramdiskoff> + + +=head2 OVERVIEW + +A ramdisk can be mounted below the default path or the specified path for +the databases in the dramdisk directory. The ramdisk is used to speed up +powersearchs and/or file/dir listings for packages from the not-installed +system. Also, this is useful if a computer system is heavily loaded with +other processes using the memory, and the ramdisk tends to persist even +after being unmounted. Modern kernels usually are built with support for +ramdisks. If these options do not work the kernel will need to be compiled +to support ramdisks by answering yes to RAM disk support. Perhaps the +best F showing how to configure and compile a kernel comes with +the F in the main directory. + +B<--ramdiskon> allows a ramdisk to be created and mounted. If called with +B<-n> (not-installed databases) F will +automatically be written to the mounted ramdisk. This provides faster +file/dir listing capabilities when using B<-l>, B<--df>, or B<-d> when +querying the not-installed system. Faster powersearch capabilities are +available through the option B<--searchfile>. If the search databases are +not already compressed, they will now be compressed, this usually only +needs to be done once or until the databases are updated or rebuilt again. +The search databases will then be written to the mounted ramdisk. An +installed system only writes the search databases to the mounted ramdisk, +so always use --searchfile when specifying installed system databases. + +B<--ramdiskoff> is used to unmount the ramdisk. The not-installed +databases and the installed databases can not be simultaneously provided +by a mounted ramdisk, use B<--ramdiskoff> first, then B<--ramdiskon> to +install the other databases of choice. This also pertains to different +distributions and/or architectures. + +See the section "B" for options +B<--arch>, B<-dists>. + +See the section "B" for options B<--dbpath> +and B<--root>. + +=head1 FILES + + Configuration files: + + swimz.list + swimrc + +=head1 SEE ALSO + +swimrc(5), apt-get(8), sources.list(5), dpkg(8) + +=head1 BUGS + +Send directly to mttrader@access.mountain.net + +=head1 AUTHOR + +Jonathan D. Rosenbaum + +=head1 COPYRIGHT + +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +=cut diff --git a/swim.sgml b/swim.sgml new file mode 100644 index 0000000..eb19610 --- /dev/null +++ b/swim.sgml @@ -0,0 +1,2036 @@ + + + + + + + + + swim + + + Jonathan D. Rosenbaum + mttrader@access.mountain.net + + + + + + + + Copyright © 1999 Jonathan D. Rosenbaum + + +

+ SWIM, including this manual, is free software; you + may 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 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 with the swim source as the file + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +

+ +
+ +
+ + + +DESCRIPTION + +

+ +swim is a powerful package administration +and research tool for both an installed Debian +distribution, and/or not-installed virtual Debian +distribution(s) allowing querying of software packages with a variety +of package information options, and powerful searches. Virtual options +which include ftp, installation, and package removal capabilities can be +seamlessly combined with querying or searches. swim can +be used on computer systems which either have, or do not have a Debian +distribution installed. + +COMMAND LINE OPTION SYNTAX + +

When you press ``swim +<enter>`` you will see a listing of command line +options in a particular syntax. This is to help you understand under what +context to use the options. When you enter the options on the command +line, the brackets, parentheses, braces, diamonds, and question marks are +not actually used. + +

+ +Major Mode Option + +

+ +All command line options for swim always start with a +major mode option, except for ``swim <enter>`` +which will show the whole listing of options. A major mode option is +surrounded in braces { major mode option }. In the case +of {--search} there are the alternative major mode options +{--refinesearch} and {--research}, but because --search needs to be used +first before either of these two options, --refinesearch and --research +are surrounded in parentheses (). + +

+ +Note: Through the other chapters of this manual {} is +assumed for the major modes in the +usage: section shown at the beginning of every chapter. + +

+ +Let's take a closer look at this situation: + + +

+ +{--search ? (--research || --refinesearch)<pattern(s)>} + +

`||' or `|' are used to indicate +`or', `?' indicates +`optional', <diamond> indicates an +argument (a required argument - see Arguments below), +(parenthesis) means `if used, must be used after the +previous required option was used'. Note: for readability +--research and --refinesearch are not surrounded in +{}. + +

+ +Normal Options + +

+ +Options to the major mode options are enclosed in brackets [ +option to major mode ]. swim [-n] +<enter> (assume enter from here on out), for instance, +will show all the command line options without using the pager. The pager +which swim uses can be set in swimrc (see swimrc(8)). +``swim {--help} [-n]'' will provide brief explanations of all of +swim's options without using the pager. In this case the major mode option +{--help}, and the option [-n] were used. + +

+ +Dashes + +

+ +Options which have a single dash can be combined with other single dashed +options (-qaint). Double dashed options need to be +entered by themselves (--help --nopager), many double +dashed options have an alternative single dash option (-n for +--nopager). The meaning of options is related to the major +mode they are being used with. [-n] means no pager +when called with {--help}, but it's a reference to the +not-installed databases when used with {-q --query}, +fortunately most options do not have double meanings. + +

+ +Arguments + +

+ +Many options require an argument. Arguments are enclose in diamonds < +argument >. An argument to an option may also be +optional in which case a question mark ``?'' will be +placed between the option and the argument. [-l ? +<[--df]>] illustrates such a situation. +[-l] shows a file listings, and optionally the option +[--df] can be use with [-l] to show an +expanded listing. + +

+ +[--dbpath <dir>] requires an +argument, this time the argument would not be another option, but rather +it is a directory. + +

+ +Rule: When an option is an argument to another option it can be written +anywhere, but when a non-option is an argument +<dir> (notice no brackets) it has +to be placed directly after the option. Sometimes, there may be +alternative arguments divided with ``|''. +<argument1|argument2> means use argument1 or +argument2, but not both. + +

+ +Based on what we now know, let's compare this situation to the +{--search} situation shown above: + +

+ +[--ftp ? --source | --source_only ? <[--diff]>] + +

+ +In this case --source or alternatively +--source_only can be optionally used along with +--ftp because they aren't in parentheses +() (also notice: | was used instead of ||, but means the +same thing ``or''). --diff can optionally be provided as +an argument to either --source or +--source_only. For readability --source and --source_only +weren't enclosed in brackets. + +

+ +Global Arguments + +

+ +A global argument can be typed anywhere on the command +line, and can be an option or text. If global arguments +exist they are placed last after the list of normal +options that can be used with a major mode +option. + +

+ +[targets | -S] and [targets|APT|DF] are +examples. {-q}, {--initndb}, and +{--rebuildndb} all use global arguments. + +

+ +Minor Mode Options + +

+ +{-q --query} will generally use zero or more +minor mode options [-afpgn --dir], with +one exception (see ). + +VERSION + +

+usage: swim --version + +

+ +This shows the version for the swim program. + + +HISTORY + +

+ + + +usage: swim --history + swim -h + +options: [--arch <architecture>] [--dists <distribution>] + [--n] [--dbpath <dir>] [--root <dir>] + + + +

+ +This shows a shell-like history of searches and the most recent --stdin +edit. History is numbered with the most recent action being 1, and the +earlier actions being of a higher number until the maximum amount of lines +set in the HISTORY variable in swimrc(5). A separate history is +kept for each architecture-distribution. + + +MAKING INSTALLED SYSTEM DATABASES + +

+ +Initial database making, and Rebuilding for an +Installed system. + +

+ + + +usage: swim --initdb + swim --rebuilddb + +options: [--dbpath <dir>] [--root <dir>] [--lowmem] + [--split_data <lines>] + + + + +

+ +An installed Debian distribution is one in which packages are +installed using dpkg or some front-end to +dpkg like apt or +dselect; swim supports installation +through apt. These major modes are for a computer with an +installed Debian distribution and make the databases which allow +querying and searching capabilities for the installed distribution. + +

+ +--initdb is run when the databases do not exist yet, +--rebuilddb is run if the databases have become corrupt, +or you want to rebuild the databases instead of updating them. + + +

+ +--dbpath can be specified as an alternative location for +where the databases will be made. The default location is +``/var/lib/dpkg''. An argument like ``/otherstuff'' +could be provided, and then the databases would be made here instead. + + +

+ +--root allows a database to be made for a Debian distribution installed on a +different partition. If the distribution is mounted on +/New_Debian, ``/New_Debian'' would be the argument to root. The databases would be made for the +Debian distribution installed on the ``/New_Debian'' partition. + + +

+ +--dbpath and --root can be used +together. Given the previous two examples, the databases would be made on +``/New_Debian/otherstuff'', assuming +``/New_Debian/otherstuff'' actually existed. + + +

+ +--lowmem uses a method which uses a small amount of +memory to make the databases. By default --initdb and +--rebuilddb use a method which fully takes advantage of +memory, this is a good thing, because it means the databases are made in a +quicker manner. On a computer with a K6-200 CPU, 64MB of memory, and 1500 +installed packages, the databases can be made in 4.5 minutes using the +default method, and 11 minutes using the low memory method. The high +memory method is the default because in general the size of a distribution +is related to how much resources a computer has, and probably a large +installation is unusual. If you get an ``out of memory'' when you use the +default method, or if your system is overloaded to begin with, the +--lowmem method is the prefered way. + + +

+ +--split_data determines the size of the files in the +temporary directory used to contruct the database. The default is 25000 +lines per file. If you are using the --lowmem method you +may want to provide a different argument to --split_data, +like ``--split_data 10000''. This is a subject of +experimentation. + +

+ +UPDATING + +

+usage: swim --db + + + + +

+ +options: [--dbpath <dir>] +[--root <dir>] [--check] + + +

+ +--db allows you to update the databases by hand when +packages have been removed, added, or changed. swim will automatically run +--db under certain conditions. + +

--check prints out the changes to STDERR, and the +total to STDOUT without proceeding with the update. + +

+ +See for options --dbpath and +--root. + + +

+ +REBUILDING THE SEARCH + + +

+ +usage: swim --rebuildflatdb + + + + +

+ +options: [--dbpath <dir>] +[--root <dir>] + + +

+ +swim makes the flat databases searchindex.deb and +dirindex.deb for doing powersearches. Instead of +rebuilding these databases everytime --db is run, new +information is just appended to these databases, and old information is +kept. Generally, this is not a problem because only files and directories +which the other databases actually know something about will be refered +to. But in a situation where a file has changed into a directory, the +powersearch may not work properly, because the old file name +remains in searchindex.deb, and the new directory name is now in +dirindex.deb directory. In general, it takes a lot of changes to +the installed system before it is really becomes necessary to rebuild the +flat databases. This process takes less than a minute on a K6-200 with +1500 packages. + + +

+ +See for options --dbpath and +--root. + +FILES + +

+ +Databases which are made: + +

+ + + packages.deb + fileindex.deb + statusindex.deb + groupindex.deb + searchindex.deb + dirindex.deb + + +IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED +DATABASES + +

+A. downloading the important databases with --ftp. + +

+ + +usage: swim --ftp + +options: --Contents <DF|directory> + --Packages <DF|directory> + [--dists <distribution>] [--arch <architecture>] + [--onec] [--Release_only] + + +OVERVIEW + +

swim provides a method so that all information about +an existing Debian distribution is quickly accessible through databases. +Debian already provides flat file databases for all its distributions. One +database called ``Contents-(architecture)'' provides a complete +listing of all the files associated with each package, the other much more +important database called ``Packages'' provides everything from +the Package's description, to all the dependencies for that package. The +Packages database is a crucial database for other important Debian +administrative tools like dpkg and apt. + +DISTRIBUTION DEFINED + +

+Debian Distributions choose a name which reflect the development state of +that distribution. The distribution named ``unstable'' is where +the majority of the development processing occurs, after unstable +has reached a certain level of maturity, it's copied over to a new +distribution called ``frozen'' which is tested extensively before +becoming the new ``stable'' distribution. The frozen +distribution retains the Release version number of the +unstable distribution, and the unstable distribution +receives a new Release version number. Eventually, +frozen becomes stable, and at this point both +frozen, and the older stable distribution are removed. +Code names are associated with the Release Version number given +for each of the distributions. This is much better for mirroring Debian +sites. + + +

+ +swim was designed to ignore these code names, and instead +shows the user the Release version number associated with the +distribution. Swim users must always use the real distribution name, or +swim will not work properly. This is a nice feature because it allows user +to make decisions related to the management of their databases, and makes +research much more easier. + + +

+ +The other Debian distribution which swim recognizes is +experimental. This distribution does not have any Release +version number, and contains packages which are considered risky +because of their development level. + + + +

+SECTIONS + +

Each Debian distribution has sections related to the relationship of +each of the packages to the Debian's Policy Manual. In +``main'' there are packages which have a correct relationship +with these Policies. Packages in ``contrib'' comply with the +DFSG (Debian Free Software Guidelines found in the +Debian Policy Manual) but have various limitations like requiring +a package which is found in non-free, or is not in the Debian archive. +Packages in ``non-free'' do not comply with the DFSG but +are electronically distributable across international borders. The +``non-us'' section is found outside of the United States and +exists for packages which have export restrictions. + + + +

+ARCHITECTURES + +

Distributions also have architecture specific sections since not all +packages compiled for one architecture can run on all other +archictectures, however, there are a large percentage of packages which do +run on all architectures. The architectures are alpha, +arm, i386, m68k, powerpc, +sparc, and more recently hurd-i386 which represents +packages for the hurd GNU kernel for the i386 architecture. + + +

+SWIMZ.LIST + +

--ftp uses a file called swimz.list which +has the same type of format (see format below) as the +sources.list(5) which apt uses. There are some +differences. The first difference mentioned above (see +) requires that the distribution names never should be the +code names for the Release version. Secondly, +apt only retrieves databases specific to one +archictecture, normally the one you are running apt on. +With swim though you can fetch databases for any, or +every architecture by adding the architecture to ``deb'' with a hyphen +(deb-hurd-i386). If deb has no architecture appended it is assumed that +the architecture you want is the same as the system you are running +swim on. Thirdly, at this time +swim only supports the ftp method. +Fourthly, you can change swimz.list as often as +you want without worrying about databases being removed so that that the +swimz.list and the downloaded databases match. This would occur +with apt's sources.list(5) if you removed a +site. Fifthly, databases are kept in a compressed state. +Sixthly because the list is used for both Contents and +Packages, more flexibility is provided by only allowing the default +distribution/archictecture or distribution/architecture provided on the +commandline to be downloaded. + +

+ + +For apt users: If you are using apt, and +swim together it is a good strategy to use the real +distribution name in the sources list(8), and to have an exact +copy of the sources.list(5) ftp sites in the swimz.list. +Packages databases specific to the architecture apt is +using can be retrieved using swim --apt --update (this +also will keep track of the Release version), and then +swim can be used to fetch the architecture specific +Contents database as shown below. It should also be of interest +to note that Packages downloaded by either swim or apt can be used +interchangeably by using 'cp -a' and 'gzip -d' or 'gzip -9'. + +

+ +Here is a brief outline of the format required by swimz.list. + + +

+ +deb uri distribution [section ... ] + +

+ +deb - represents a standard Debian distribution. And is +simply written as deb or with the architecture appended +(deb or deb-alpha). + + +

+ +uri - Universal Resource Identifier is exactly how you +would enter an address into a web browser. This address is the base of a +Debian distribution, generally this is right before the directory called +``dists''. So if dists is found in +/stuff/pub/debian/dists, and the site is +somewhere.com then the uri would be +ftp://somewhere.com/stuff/pub/debian. + +

+ +distribution - This can be unstable, +frozen, stable, experimental. Distribution can +also be a path which must end with a slash like +unstable/binary-i386/. This is used when there is no section as +in the experimental distribution or in sites which do not have symlinks to +the non-us section. No section would be mentioned in this situation. + +

+section - main, contrib, +non-free, non-US (write it this way). + + +

+ +SWIMZ.LIST EXAMPLES + +

+Examples (each on one line): + + +

+ +deb-alpha ftp://somewhere.com/stuff/pub/debian unstable main contrib non-US + +

+ +This will fetch the alpha databases from somewhere.com for the unstable +distribution for the main, contrib and non-US sections. + + +

+ +Note: In these next two examples you can not append any architecture to deb +with a hyphen. + +

+ +deb ftp://somewhere.com/stuff/pub/debian project/experimental/ + + +

+ +This will fetch the experimental database, but there is not a +Contents-(architecture) database for this distribution. Notice that it ends +with a slash. + + +

+ +deb ftp://somewhere.com/stuff/pub/debian-non-US stable/binary-i386/ + +

+ +This will fetch the i386 databases for the stable distribution for non-us, + + +FTP OR APT? + +

How you use major mode --ftp depends on your goals. +Even if you are using apt, you may be interested in +keeping tabs on different architectures. In this case you would have to +download the Packages databases specific to these architectures. +If you are only interested in the architecture which apt +is interested in, then you only need to use --ftp to +fetch the Contents database(s). But, because it isn't a +requirement to set up a virtual filesystem, you are not required to fetch +the Contents database. The advantages of fetching the +Contents database is determined by the method you choose to make the +database (see ). These advantages include the +ability to view a listing of the files and directories associated +with a package, the ability to query files and directories to +find out which packages relate to them, and the ability to perform a +powersearch on all the files and directories to find the +associated packages. + +

+OPTIONS + +

Remember: If you want to download a different +distribution/architecture other than the default specified in your +configuration file, you must specify this on the commandline. + +

--Packages determines where you want the Packages +database as well as the Release data put when they are downloaded. The +DF argument implies that the databases will be put in +your default directory (see swimrc(5)). These databases can later +be located by the major modes --initndb and --rebuildndb +just by using DF as an argument. Alternatively, these +databases can be put in any directory you choose by providing a +directory as an argument. + +

+ +--Contents determines where you want the +Content-(architecture) database(s) put. (see +--Packages). + +

+ +--onec will download only one Contents-arch per +distribution/architecture specified on the commandline or by default. + +

+ +--Release_only will download only the Release data for +the swimz.list or particular Package(s) mentioned on the +command line. + +

+ +--dists will only find the distribution which corresponds +to the argument provided this option. + +

+ +--arch will only find the architecture which corresponds +to the argument provided this option. The different architecture needs to +be specified in swimz.list with a hyphen and the architecture appended to +deb (deb-(arch)). + +B. downloading the important databases with apt, and maintenance +options. + +

+usage: swim --apt + +

+ +options: [--update] [--clean] [--autoclean] [--check] + + +

+ +Please read for more information. + +

+ +--update calls apt to download the +Packages databases. + +

+ +--clean is a call to an apt option to +remove any packages stored in apt's storage area for +downloaded packages. The default for this storage area is +/var/cache/apt/arhives + +

+ +--autoclean will only clean out packages which are not +found in apt's cache. + +

+ +--check tests and updates apt's cache. + +MAKING NOT-INSTALLED DATABASES + +

+ + + +usage: swim --initndb + swim --ndb + swim --rebuildndb + +options: [--Contents <target|FDBtarget|DF|FDBDF>] + [--main] [--contrib] [--non-free] [--non-us] + [--arch <architecture>] [--dists <distribution>] + [--dbpath <dir>] [--root <dir>] [--alt] + [--split_data <lines>] [-v] [--cron] + [targets|APT|DF] + + + +

+OVERVIEW + +

+The not-installed database provides swim with many capabilities like the searching, and querying of +packages which do not actually exist on the live filesystem, as well as the +ability to seamlessly install packages while searching or quering, or the +ability to fetch the packages source code. The virtual filesystem is optional, but it is highly recommended. These two major mode options set +up these databases, after determining the level of interaction which you +want. + +

+ +Whenever swim makes databases it thinks only in terms of +one distribution and one architecture. This keeps things logical. +swim does have the ability to take Packages files with +multiple architectures, and distributions, and to extract information for +one distribution and one archictecture to make its databases. This could +provide interesting information from dumps from apt +(apt-cache dumpavail). + +

+ +--initndb creates the initial not-installed databases for +a particular architecture and distribution, and +--rebuildndb remakes the not-installed databases for that +same architecure and distribution. If not otherwise specified +swim will use the values it finds in +swimrc to determine what architecture and distribution you want +to use to make swim's databases. Otherwise... + + +OPTIONS + +

--arch allows an argument to override the +architecture found in swimrc. + + +

+ +--dists allows an argument to override the +distribution found in swimrc. + +

+ +--alt is used for a distribution with a Debian archival +structure, but which has a different name. This allows for alternative +distributions. + +

+ +When APT or DF are provided as arguments +(see below), by default the Packages which pertain to the +sections found in swimrc will be shown. If you only want certain +sections you may specify them on the command line. If you are not using +APT or DF, it is a good idea to make +sure that either the sections found in swimrc or the sections you +put on the command line match the Packages you a targetting +because this is much more effecient. + +

+ +--main will override the sections found in +swimrc, and will use this section. + +

+ +--contrib will override the sections found in +swimrc, and will use this section + +

+ +--non-free will override the sections found in +swimrc, and will use this section + +

+ +--non-us will override the sections found in +swimrc, and will use this section + +

+ +Global arguments targets|APT|DF must be used with either +of these two major modes to find the Packages databases. targets +can be a full path to one or a set of Packages. +APT will use the Packages found in +/var/state/apt/lists, and DF will use the +Packages found in the default directory for swim (see +--ftp). If you use either APT or +DF you will be given an interface which +allows you to choose one Packages database for each section you +would like to use from the various sites. This interface +shows the site, date, +size and Release version for each +Packages. + +

+ +--cron allows you to override the +interface produced when APT or +DF is provided as an argument. This is useful if you want +to automate the database making process. --cron will +choose the newest database(s), if cron notices that the Release +version has changed, cron will not proceed, but will provide a warning +instead. This allows you to make the appropriate changes and choices. + +

+ +--Contents can be give one of four arguments: + +

+ +1). If you have a Contents-(architecture) +database in a target location you know about you may provide a path to the +location. The Contents database can be compressed. + +

+ +2). If you prepend the path with the letters +FDB (meaning flat database) when the databases for swim +are made, instead of using the Contents database to make: + + + nfileindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + + +

+ +Only the ncontentsindex-arch-dists.deb.gz database will be made +which allows the ability to view file/dir listing for not-installed +packages, but does not provide the virtual file system or powersearch +capabilities which the other databases would have provided. + +

+ +3). The argument DF may be used if you +have used --ftp with the DF argument to +the option --Contents (see --ftp). In this case +it is assumed you are also using global arguments DF or +APT for the Packages databases. This will give you an +interface (if --cron isn't used) allowing you to choose +one Contents database for the particular distribution you want to +make the databases for. + +

+ +4). FDB does the same exact thing with +DF as it does with the before mentioned +FDBtarget, and provides the interface. + +

+ +-v will only work if you have dpkg installed. It allows +swim to verify swim's own built-in version comparison +function with dpkg's version comparison function. This is +good for debugging purposes, and produces a report called +.version_compare in the same location that +swim's databases are made. + +

+ +--split_data is only advantageous if +--Contents is being used. See --initdb +for more information about the --split_data option. + +

+ +See for options --dbpath and --root. + +UPDATING + +

+ +--ndb has the same options as --initndb and --rebuildndb except +for --split_data. It also has a new option --nue which will +never have to be used unless the experimental distribution or non-us +section are found in Contents (which presently isn't the case). +--check prints out the changes to STDERR, and the total to STDOUT +without proceeding with the update. --status_only can be used +after a new package has been installed to update the status, after which +-qni and -qi will correlate properly. + +REBUILDING THE SEARCH + +

+--rebuildflatndb serves the same purpose as --rebuildflatdb. See + + +FILES + +

+Databases and reports which are made (arch = architecture dists = +distribution): + +

+ + + npackages-arch-dists.deb + nfileindex-arch-dists.deb requires <--Contents> + nstatusindex-arch-dists.deb + ngroupindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + .packagesdiff-arch-dists.deb requires <--Contents> + + +

+ +PREPARING YOUR INSTALLATION FOR APT + +

+ + +usage: swim --audit + swim --status + swim -C + + +

+ +If you are using apt with swim, and this +is the first time you are using it with your installation, check your live +installation with this major mode. This is a call to dpkg -C +(--audit), and will show any packages which are not properly +configured or installed. If you get any output, make corrections. The goal +is to get absolutely no output whatsoever because it is under these +conditions that apt will work properly. See the with +-q to remove the offending packages. You may have to +remove the package by hand under unusual situations like when it is not +just dependencies (see -T) between packages keeping the package +from being removed perhaps due to a broken script (see +--scripts). In an extreme case you could manually remove the +entry for this package from the /var/lib/dpkg/status database, +and hunt down and remove all the files associated with the package with +swim's -l option. When you are done if you still want +some of the packages you removed, use apt to reinstall +them with swim's -xyz option. Also, apt +provides its own built-in method to clean up your system, and will provide +instructions, but you still may have to do some of the cleaning yourself +as discussed above. + + +QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES + +

+ +usage: swim -q [-fpgn --dir] [targets | -S] + swim --query [-fpgn --dir] [targets | -S] + swim -qa || swim --query -a + + +

+ + +options: [--total -t] [-i] [-l ? <[--df]>] [-d] [-c] + [--scripts] [--preinst] [--postinst] [--prerm] + [--postrm] [-v] [--dbpath <dir>] [--menu -m] + [--shlibs] [-T] [--pre_depends] [--depends] + [--recommends] [--suggests] [--conflicts] + [--replaces] [--provides] [--md5sum] [--root <dir>] + [--copyright] [--changelog] [--allgroups] + [--arch <architecture>] [--dists <distribution>] + [--ftp ? --source | --source_only ? <[--diff]>] + [--stdin] [--extract] <ALL|archive|PWD!archive>] + [-xyrz --remove ? <[--nz]>] [--purge] [--apt2df] + [--df2apt] + +

+ +global arguments: [targets | -S ? <\d{1,}>] + +

+ +Quering almost always involves using -q or --query with +zero or one or a combination of the minor mode options +(package specification options), and one or more (only one for +-g) targets specific to the minor mode, or the results of a +search (-S). [-S can be provided a numerical argument +pertaining to the past history.] This can be combined with one or more +options. The one exception is ``swim -q --allgroups''. + + +

+ +--query or -q can be used by itself or with +-n to query known package names or package names with +versions. ``swim -q test1 test2_0.3-1'' would produce the +output: + + +

+ + +test1_1.0-2 +test2_0.3-1 + + +MINOR MODES + +

-n is the minor mode option to access the +not-installed system, it can be combined with the minor mode +options -a, -g, -f, or +it can be used by itself. + + +

+ +-a allows every package on an installed or +not-installed (-n) system to be queried. ``swim +-qan'' will show all the package names with versions for the +not-installed system + + +

+ +-f allows files or directories to be queried, +when used without any options the package name with version is shown. +--dir will only query directories, this is useful if you +are not sure whether what you are quering is a directory or a file. When a +directory is queried, swim shows all packages which exist below the +queried directory. ``swim -qf /'' is exactly the same as +``swim -qa''. Hint: ``swim -qf .'' and +``swim -qf *'' are quite different, the first shows all +packages which exist below the current directory, and the second will show +the package which each file in the current directory comes from. + +

+ +-g will query a group (also called a section, +see )) of packages. Groups represent subjects which +packages with similiar characteristics are catagorized by. To view all the +groups found in an installed or not-installed system use ``swim -q +--allgroups'' or ``swim -qn --allgroups''. +``swim -qg hamradio'' or ``swim -qng +hamradio'' shows all the package names for the hamradio group. + +

+ +-p is used to query a Debian package, these +packages are distinguished by their ``deb'' ending, but swim can +tell whether a file is a debian package even without the ending. Called +without any options the package name with version will be shown. + +SPECIFYING THE DATABASES TO USE + +

--dists will use the databases for the argument +given, otherwise the databases pertaining to the value found in swimrc +will be used. + + +

+ +--arch will use the databases for the argument given, +otherwise the databases pertaining to the value found in swimrc will be +used. + + +

+ +Example: swim -qat --arch hurd-i386 --dists unstable + + +

+ +Assuming these databases exist this will show all packages and their +versions for the unstable distribution and architecture hurd-i386 even if +the values in swimrc are i386 and stable. + + +

+ +see and for more +information about the databases. + + +OPTIONS + +

--total or -t are used to override the output +suppressor. The output suppressor will not show output if a certain +number of packages is exceeded, instead it will show the number of +packages you are querying. This is useful for two reasons, first, knowing +the number of packages you are quering can be very informative, second, it +gives you a chance to add to the command line a pipe to a pager, ex: +``swim -qat | less''. You can set the number that the +output suppressor works at as high or low as you want in the +swimrc(8) file. By design the -t option will +have to be used if the -i option is used and more than +one package is being queried. This option can also be used to alter the +output of the various script options (--scripts, --preinst, --postinst, +--prerm, and --postrm). + + +

+ +-i provides information about each package being +queried. The format differs slightly for the installed packages versus the +not-installed packages. see : + + +

+ +-l provides a listing of the files associated with a +package. If the option --df is provided as an argument, +all the directories associated with package will be shown. It is important +to remember that many packages provide directories which become important +to them after they are installed, so the option --df +often provides necessary information which -l called by +itself would have not. + + +

+ +-d shows the documentation which the package provides +found in /usr/doc/*, /usr/man/*, /usr/info/*. +Other documentation which the package may provide in a non-standard +location will not be shown. -d takes precedence over +-l, so if -l is used on the command line +with -d, only the output for -d will be +shown. + + +

+ +-v is a special option which works only with the minor +mode -p. It can be used with -l, +--df, -d, to show the packages files +and/or directories in long format (ls - +l). + + +

+ +-c will show the configuration files packages use. If the +package does not have a configuration file then nothing will be shown. The +output will show the file and its path indented one space with the +MD5 checksum. This will not work with +-n. + + +

+ +--scripts shows all scripts associated with a package +with the name of the script presented before each script in this way +#####scriptname######. If the scripts are called +individually by using the script options --preinst, +--postinst, --prerm, or +--postrm no title is shown, this is nice for writing to a +file. If -t is used with the individual script options a +title will be shown, this makes sense because normally only individual +packages would be queried to write a script to a file, and +-t wouldn't be used in this situation. Scripts are the +soul of Debianized packages allowing packages to be installed, configured, +and removed seamlessly and cleanly under all kinds of conditions. These +options do no work with -n. + + +

+ +--menu or -m is used to view menufiles which belong to +various packages. If the package does not have a menufile nothing will be +shown. This option can be useful in troubleshooting a menu entry which +does not seem to work, or in finding out where the menu entry is. +Joost Witteveen's Debian menu system is a centralized program +which interacts with all kinds of menus. Please read the +documentation ``swim -qd menu'' which comes with the +menu package to find out more. This will not work with +-n. + + +

+ +--shlibs shows a list of shared libraries certain +packages supply. The Debian Packaging Manual (packaging-manual) +provides detailed information about the format of a shlibs file. This will +not work with -n. + +

+ +--md5sum checks MD5 checksums. It can be +used with -l, -d, -c, +or -p. If there are checksums available the md5sum result +will be either OK, FAILED, or +MISSING. MISSING means that although a +checksum exists, the file can not be found. The result is put after the +file and its path and the MD5 checksum or the package +name and version and the MD5 checksum. + + +

+ +--copyright does a case insensitive search for copy or +license in the /usr/doc/packagename directory. This should show +how the package relates to Debian's Policy Manual. + + +

+ +--changelog searches for any files in +/usr/doc/packagename which look like changelogs. Debian packages +always have a Maintainer's changelog for the package. There may +be a separate changelog kept by the author of the program. + +PACKAGE RELATIONSHIPS + +

+ +-T shows all the package relationships of packages. +Individual package relationships can be viewed using +--pre_depends, --depends, +--recommends, --suggests, +--replaces, --conflicts or +--provides. Package relationships are the spirit of +Debian packages, here is a quick overview briefly reiterating what can be +found in the Debian Packaging Manual. Package +Maintainers set these relationships in control file fields of the +same name. + +

+ +Dependencies + + Pre-depends - means that the pre-depended package or packages +must be installed before the queried package can be installed. Most +packages which have pre-dependencies are usually essential and required +packages. + + +

+ +Depends - declares an absolute dependency to another package or +packages either real or virtual. The queried package cannot +function without this other package. + + +

+ +Recommends - declares a strong, but not absolute dependency to +another package or packages either real or virtual. You would +usually find the recommended package together with the queried package in +a normal installation. + + +

+ +Suggests - can be one or more packages either real or +virtual which would be useful to the queried package, but are not +necessary. + + +Alternative Packages + +

+ +Conflicts - is a package or packages either real or +virtual which would cause problems with the queried package, and +would not be allowed to be installed while the queried package was +installed. + +

+ +Overwriting files and Replacing Packages + +

+ +Replaces - allows the queried package to replace another package +or packages by overwriting their files, after which the previous package +would be considered to have disappeared. Essentially this allows the +queried package to take over the package or packages. In a situation where +there was a Conflict between the queried package and these packages this +field would help determine which packages should be removed. + +

+ +Virtual Packages + +

+ +Provides - declares a virtual package which may be mentioned in +Depends, Recommends, Suggests, or +Conflicts. Virtual packages allow one or more packages +to share the same name of another package, which means if the queried +package has a reference to a virtual package in one of the before +mentioned package relationship fields, then whatever packages provide the +virtual package are also being listed. + +FORMAT + +

+ +1). Installed system + + +

+ + + Package: name Status: hold ok installed + Version: 1.1-1 Essential: no + Section: namers Priority: extra + Installed-Size: 10 Source: generatename (2.0-1) + Maintainer: name <name@name.org> + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + + +

+ +2) Not-installed system + + + + +

+ + + Package: name Status: r> hold ok installed (1.1-1) + Version: 1.1-2 Essential: no + Section: names Priority: extra + Installed-Size: 11 Source: generatename (2.0-1) + Size: 43000 Architecture: i386 + Distribution: experimental + Maintainer: name <name@name.org> + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + + +

+ +There are several things to point out. The difference between the two +outputs relates to the addition of the Distribution, Size, and +Architecture fields for the not-installed query. Installed-Size is how +many kilobytes the package will occupy when it is unpacked, whereas Size +is the size in bytes of the package. + +STATUS FIELD + +

+ +The Status field provides the installation status of the package, this +holds true for the not-installed query as well. In a sense, the +not-installed database isn't always not-installed. If the not-installed +package is actually already installed, and the version numbers are exactly +the same, then the status will be the same for either query. If the +not-installed package is not installed then the status will be +``not-installed''. In cases where the not-installed package is already +installed, swim uses it's comparison function to figure out whether it is +a newer of older package which is installed. In the above example, swim +realizes the same package is installed, and only the debian-revision has +changed, hence the only difference is that the revision number is greater +``r>'' for the not-installed package. When only the debian-revision has +changed it can safely be assumed that the author (creator, programmer) of +the same program has not made any changes to the same program, but the +Debian maintainer has made a change to an aspect of the package like a +change in the script the package uses to properly install. You may have +also noticed that the status field shows the version number of the +installed package enclosed in parenthesis. + +SOURCE FIELD + +

+ +The Source field is present in these examples, but the Source field will +not always be present for packages. In cases where the name of the source +package is the same as the the name found in the Package field, and the +version number of the source package is also the same as found in the +Version field, then there will be no Source field. In the above examples +there is a Source field. In this case name was probably one of many +packages generated from the source package called generatename. In this +particular example generatename also has its own unique version number +2.0-1 enclosed in parentheses, if no version number had been mentioned +then the source package would have the same version number as found in the +Version field. + +SECTION AND PRIORITY + +

+ +Section shows the subject which a package is categorized with (see +-g). Priority shows how important the package is to have +installed. In the case of the not-installed databases the information for +these fields is almost always available from the Packages databases, but +this is not always the case for Debian packages. For packages which do no +provide this information swim will do its best to fill in the blanks from +information found in the installed and not-installed databases. If proper +information can not be found it will be indicated as ``unavailable'' or +``unknown.'' Unavailable would indicate that information about the package +exists, but it is from a different version (includes debian-revision), and +no information exists for this version. Unknown means no similiar package +exists, and there is absolutely no information about this package in the +databases. + +

+ +When a Debian package is queried using the -p +option you will get output like the first example shows, the status field +is also calculated. + +FTP - VIRTUAL OPTIONS + +

+ +For ftp capabilities swim uses the swimz.list to determine which +sites it will check for the requested packages. The first site which fills +the request will be used, otherwise swim will go through +all the sites avoiding repeats, and if no sites can fill the request, +swim will either quit or proceed on to check for another +request. + +

+ +--ftp allows the queried package, its source package, or +just the source package diff to be downloaded while being queried. This is +refered to as virtual downloading because the quering and the downloading +are seamless as though the package already exists locally. This has to be +used with the option -n because packages which which are +not part of the not-installed database are considered to already have been +downloaded. Packages which are already installed can be downloaded or +their source retrieved by setting up a database which corresponds to these +packages; if the installed packages belong to the stable distribution, +set-up the not-installed stable databases. + +

+ +Packages or source code are placed in an area below the default directory +mirroring the remote directory they were downloaded from after their size +and modification times are checked for correct values. This area is called +the DF directory, and although this directory mirrors +remote directories, it is not an exact mirror, but specific to the +requirements of swim because code names for Release versions are not taken +into account. For real mirroring capabilities there exist many excellent +programs. If a package has a MD5 checksum, +--md5sum will automatically be run and the value shown. +Regardless of whether or not the md5sum check is OK or +not, the package will still be put in the DF directory to +allow the package to be looked at, so watch the output from +--ftp to check for FAILED md5sums. + + +

+ +Packages or source code packages will not be downloaded again if they are +found in the DF directory unless their +upstream-version has changed in the not-installed database, if +the packages are not in the DF directory and the remote +upstream-version is different than the not-installed +upstream-version then the packages will not be downloaded until +the not-installed database is updated or rebuilt to reflect the version +change. Changes in the package's upstream-version indicates that +the author(s) of the program have made changes to the computer +code for the program contained in the package or the source code package. +On the other hand, swim will check for a debian-revision change +at the remote site if the package can not immediately be found. If the +package's debian-revision has changed and the package does not +exist locally in the DF directory, it will be downloaded. +This is a nice feature, especially for the unstable distribution, because +it tends to extend the time needed before the not-installed database has +to be updated or rebuilt to match the changes at remote sites. + + +

+ +--source is used with --ftp to download +the source code package. --source_only will download the +source code package without the deb package. Source packages consist +of three files. The source control file which ends in +``dsc'', the original source archive which is a compressed tar +file, and the unified context diff showing the changes necessary +to make the original source into Debian source. The diff can be downloaded +by itself if --diff is provided as an argument to +--source or --source_only. + + +

+ +For apt users: apt allows packages to be +downloaded, but if more than one package is required for the package +relationships to be proper, apt will download all these +packages. --ftp allows specific packages to be +downloaded, packages from other architectures, and source packages to be +downloaded, here lies the advantage of this option over using -xyz +--nz (see below). If a particular package has been dowloaded into +the DF directory and it is needed by apt +for installation, simply copy or move the package from the +DF directory to /var/cache/apt/archives before +running apt, and the package will not be downloaded by +apt again; future versions of swim will +have an option to automatically accomplish this (see --df2apt). + +APT - VIRTUAL OPTIONS + +

+ +apt-get(8) is a nice package relationship checker from the +apt package which figures out what needs to be done to +properly install a package or packages when one or more package names are +provided to it. apt-get will get all packages which are +needed using a variety of methods, and then apt-get +interacts with dpkg in a way which allows for a +successful installation. + + +

+ +-xyrz, --remove, and --nz can be used if +apt-get from the apt package is +installed. These options allow for what is refered to as virtual +installation/removal. It is prudent to always test what will happen by +using the -x option alone before actually proceeding with +the installation with the -z option. -x +will actually simulate what would happen in an installation, showing which +and how many packages will be changed, which and how many new packages +will need to be installed, which and how many packages will need to be +removed, any conflicts, and what needs to be configured. +-y will automatically answer yes to any prompts +apt-get may produce allowing apt-get to +run non-interactively. -z as mentioned before actually +proceeds with the installation using dpkg after the +apt-get gets the packages. You can append a minus sign +to a package name to cause it to be removed. --nz when +used as an optional argument with -xz or -xyz will only +download the packages into /var/cache/apt/archives or into +whatever directory you configured for holding archives for +apt. + +

+ +IMPORTANT: apt makes it so easy to make +changes to your installation that it is highly recommended to do your +research with swim first. This can be done by checking package +relationships, file/dir listings, comparing the not-installed package to +an installed package if such exists, checking --md5sum +and -c for the installed package, and checking the Source +field by running a --search (see ) to +check to see how the source package has been split into binary packages +for the not-installed package versus an installed package if such exists. +Ofcourse, there are many other things you could look at, and you can +always do your research after the fact. Presently --db is +run only by hand, so you can check the old state after an installation if +you have not already run --db, yourself. + +REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS + +

+ +--purge uses dpkg to remove an installed +package or packages and the configuration files as shown with +``swim -qc packagename''. + +

+ +-r or --remove removes an installed package or packages +with apt, but not the configuration files as shown with +``swim -qc packagename''. You may also append a plus +sign to a package name to cause it to be installed. This option is used +with -x or -x(y)z. + +STDIN - VIRTUAL OPTIONS + +

+ +--stdin works with either --ftp, +-x, -xyz, -xz, +--purge, -r, or +--remove. + +

+ +--stdin provides the readline capabilities +commonly found in shells allowing you to edit what is on the command line. +You can edit the command line, press enter and then recall the history, +and make more changes, or type in exit to process the changed or +unchanged command line. To find out more about what readline commands +your shell supports please read the man pages which apply to your shell. +Information for the bash shell can be found in bash(1) under the +title ``Readline Command Names''. + +

+ +Example: ``swim -qgnx --stdin hamradio'' will list all +the packages from the not-installed hamradio group on the command line, +this list can be edited then submitted to apt-get for a +simulated installation. Another instance of swim can be +run at the same time, perhaps ``swim -qinTg hamradio'' to +help in making editing decisions for --stdin. + +PACKAGE MANIPULATION - VIRTUAL OPTIONS + +

+ +--extract only works with the minor mode +-p to extract parts or all of a Debian package. If the +argument ALL is provided then everything found in the +package will be extracted below the current directory in the exact +directories found in the package. A particular file may be extracted +in its exact location below the current directory by entering the +exact path for the file as shown by ``swim -qpl'' or +``swim -qpd'' as the argument. Alternativily, a file +may be extracted in the current directory regardless of its proper +location by prepending PWD\! before the path shown by +``swim -qpl'' or ``swim -qpd''. Notice +the backslash before the exclamation point, this is because shells +consider ! a special character, so it has to be backslashed so that the +shell knows that it is not such a special character. Example: +``swim -qpi --extract PWD\!usr/bin/name --scripts +name_1.1-2.deb'' will extract the binary name in the current +directory from the name package, show information for the name package, +and show any scripts for the name package. + +DATABASE LOCATIONS + +

+ +--dbpath can be specified as an alternative location for +where the databases would be found. The default location is +``/var/lib/dpkg''. An argument like ``/otherstuff'' can +be provided, and then the databases would be found here instead. + + +

+ +--root allows a database to be found for a Debian +distribution installed on a different partition. If the distribution is +mounted on /New_Debian, ``/New_Debian'' would be the +argument to root. The databases would be found for the Debian distribution +installed on the ``/New_Debian'' partition. + +

+ +--dbpath and --root can be used together. Given the +previous two examples, the databases would be found on +``/New_Debian/otherstuff'', assuming +``/New_Debian/otherstuff'' actually existed. + +UPGRADING WITH APT + +

+ +usage: swim --apt + +

+ +options: [-xyz] [--upgrade] [--dist_upgrade] + +

+ +apt-get provides powerful methods to change an +installion. When these methods are called using --apt, +swim will not allow you to proceed until you are +absolutely sure this is what you want to do. Before using these methods do +a ``swim --apt --update'' so that +apt-get knows the newest versions of available packages. +This major mode requires a combination of -x, +-xz or -xyz to be used along with either +--upgrade or --dist_upgrade. +-x used alone will simulate what would happen if +-xz or -xyz were used (also see -xyz above). + + +

+ +--upgrade is somewhat similiar to doing ``swim +-qatxz'' except that it is a more intelligent method because +apt does some behind the scene calculations in regards to +package relationships, in fact the ``swim -qatxz'' +approach will provide totally different results, or maybe these were the +results you really wanted. ``swim --apt --upgrade -xz'' +is the prefered, proper, and built-in way provided by +apt-get to install the newest versions for all packages +installed on your system. This method will not install any newer versions +of packages which would change the install status of other packages. Note: +It is not recommended to combine the query option -a with +-xz or -xyz, but combining the query option +-a just with -x can be educational. + + +

+ +--dist_upgrade combines an --upgrade +with the installation of packages which are not installed. This method +carefully examines dependencies, and resolves conflicts, and given these +factors it will upgrade the most important packages before considering the +installation of less important packages. Less important packages will be +installed only if there are not any conflicts. + +SEARCHING + +

+ + +usage: swim --search ? (--research || --refinesearch) <pattern(s)> + swim --powersearch ? (--research || --refinesearch) <pattern(s)> + swim --ps ? (--research || --refinesearch) <pattern(s)> + +options: [-g] [-n] [--dbpath <dir>] [--root <dir>] [--no] + [--arch <architecture>] [--dists <distribution> + [--ftp ? --source | --source_only <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--no] [--df2apt] [--purge] [<\d{1,}>] + + [--dir] and no [-g]for --powersearch or --ps + + + + +

+ +OVERVIEW + +

+ +swim provides two major types of searches. A search with +--search searches package information (see ), and a search with --powersearch or --ps +searches package information, and all files and/or directories +associated with each package. + +

+ +The results of either of these searches can be narrowed down by +running a test search with --research (this step can be +skipped) and/or setting the results in stone with +--refinesearch. --search can be +narrowed down initially by specifying a particular +group, and --powersearch can be +expanded initially by specifying that directories be +searched as well as files. Both searches can use the same virtual +options which the major mode -q or --query use. +Generally, it is preferable to run a search, and then to provide the +results of a search (using -S) as an argument to +-q or --query; this allows the results of a search to be +queried. Every time a search is run the results are appended to the +history, past searches can be refined or researched by providing the +numerical argument pertaining to the history. \d{1,} is simply Perl +notation meaning a number with one of more digits. + + +

+ +Perl regexps (see perlre(1p)) can be used to define the +pattern (string) provided as an argument to a search. Do not surround a +pattern in slashes, a slash is only used after all patterns and before the +modifiers i and/or m (swim supports these two modifiers). To +search for more than one pattern, patterns are separated with bars +(|). Patterns may include quatifiers, and metacharacters, +also found in egrep(1). + +

+ +If a search finds any packages which match the search, the package +information will be displayed as the package is found. The package will +only be shown once regardless of how many times it is found while the +search progresses. When the search is over the number of packages found is +shown. + +

+ +--search provides a search of package information. This +is similiar to grepping ``swim -qait'' or ``swim +-qaint'', but it is significantly faster. A search can be +performed on a particular group by using -g with a group +as an argument + +

+ +--powersearch is somewhat similiar to ``dpkg +--search'' which searches all files and directories on an +installed system, but it combines --search with the file +and/or directory search, and can also be performed on a not-installed +system. A powersearch is significantly faster than the search +which dpkg provides (even more so when ``swim +--ramdiskon --searchfile'' is used) and even more importantly +provides a logical output of the search (like ``swim -qi +packagename''). By default a search of all directories is not +performed because usually this is redundant except in rare cases. To +enable a search of all directories use the --dir option. + +NARROWING A PREVIOUS SEARCH + +

+ +--research allows the results of a previous search to be +researched without making the new results permanent. + +

+ +--refinesearch allows the results of a previous search to +be researched while making the +new results permanent. + +

+ +\d{1,} is a numerical argument to refine or research a +past search from the history. + +MINOR MODES + +

+ +-n allows the not-installed databases to be searched. +These databases will not exist if the not-installed databases were made +with the FDB argument (see --initndb). + +

+ +-g (see -g above and ). + +OTHER OPTIONS + +

+ +--no prevents normal output from a search, but does show +how many packages were found. + +

+ +See the section ``'' for options +--arch, -dists. + +

+ +See the section ``'' for +--ftp, --source, +--source_only, --diff, + +

+ +See the section ``'' for +-xyz, --nz, --stdin, + +

+ +See the section ``'' for +--purge, --remove, -r. + + +

+ +See the section ``'' for options +--dbpath and --root. + + +EXAMPLES + +

+ +swim -gn hamradio --search "radio network/i" --dbpath +/test --arch alpha + +

+ +will search the alpha architecture not-installed system databases in the +/test directory for all package information from the hamradio group using +the case insensitive pattern ``radio network''. + +

+ +swim --powersearch dpkg -xn + +

+ +will search the not-installed system databases for all package information +and all files using the case sensitive pattern dpkg, after which apt-get +will run a simulation of what would happen if it got and installed these +packages. + +RAMDISK + +

+ + +usage: swim --ramdiskon + swim --ramdiskoff + +options: [-n] [--searchfile] [--arch <architecture>] + [--dists <distribution>] [--dbpath] [--root] + + no options for --ramdiskoff + + + +

+ +OVERVIEW + +

+ +A ramdisk can be mounted below the default path or the specified path for +the databases in the dramdisk directory. The ramdisk is used to speed up +powersearchs and/or file/dir listings for packages from the not-installed +system. Also, this is useful if a computer system is heavily loaded with +other processes using the memory, and the ramdisk tends to persist even +after being unmounted. Modern kernels usually are built with support for +ramdisks. If these options do not work the kernel will need to be compiled +to support ramdisks by answering yes to RAM disk support. Perhaps the best +README showing how to configure and compile a kernel comes with +the kernel sources in the main directory. + +

+ +--ramdiskon allows a ramdisk to be created and mounted. +If called with -n (not-installed databases) +ncontents-arch-dists.deb.gz will automatically be written to the +mounted ramdisk. This provides faster file/dir listing capabilities when +using -l, --df, or -d +when querying the not-installed system. Faster powersearch capabilities +are available through the option --searchfile. If the +search databases are not already compressed, they will now be compressed, +this usually only needs to be done once or until the databases are updated +or rebuilt again. The search databases will then be written to the mounted +ramdisk. An installed system only writes the search databases to the +mounted ramdisk, so always use --searchfile when specifying installed +system databases. + +

+ +--ramdiskoff is used to unmount the ramdisk. The +not-installed databases and the installed databases can not be +simultaneously provided by a mounted ramdisk, use +--ramdiskoff first, then --ramdiskon to +install the other databases of choice. This also pertains to different +distributions and/or architectures. + +

+ + +See the section ``'' for +options --arch, -dists. + +

+ +See the section ``'' for options +--dbpath and --root. + + +FILES + +

+ + Configuration files: + +

+ + + + swimz.list + swimrc + + + +SEE ALSO + +

+ +swimrc(5), apt-get(8), sources.list(5), dpkg(8) + +BUGS +

Send directly to mttrader@access.mountain.net. + + + + diff --git a/swim.text b/swim.text new file mode 100644 index 0000000..bfe5644 --- /dev/null +++ b/swim.text @@ -0,0 +1,1622 @@ + + swim + ---- + Jonathan D. Rosenbaum + 15 June 1999 + +0.1 Contents +------------ + + 1. DESCRIPTION + + 2. COMMAND LINE OPTION SYNTAX + + 3. VERSION + + 4. HISTORY + + 5. MAKING INSTALLED SYSTEM DATABASES + 5.1. Initial database making, and Rebuilding for an Installed + system. + 5.2. UPDATING + 5.3. REBUILDING THE SEARCH + 5.4. FILES + + 6. IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED DATABASES + 6.1. A. downloading the important databases with --ftp. + 6.2. OVERVIEW + 6.3. DISTRIBUTION DEFINED + 6.4. SECTIONS + 6.5. ARCHITECTURES + 6.6. SWIMZ.LIST + 6.7. SWIMZ.LIST EXAMPLES + 6.8. FTP OR APT? + 6.9. OPTIONS + 6.10. B. downloading the important databases with apt, and + maintenance options. + + 7. MAKING NOT-INSTALLED DATABASES + 7.1. OVERVIEW + 7.2. OPTIONS + 7.3. UPDATING + 7.4. REBUILDING THE SEARCH + 7.5. FILES + + 8. PREPARING YOUR INSTALLATION FOR APT + + 9. QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES + 9.1. MINOR MODES + 9.2. SPECIFYING THE DATABASES TO USE + 9.3. OPTIONS + 9.4. PACKAGE RELATIONSHIPS + 9.5. FORMAT + 9.6. FTP - VIRTUAL OPTIONS + 9.7. APT - VIRTUAL OPTIONS + 9.8. REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS + 9.9. STDIN - VIRTUAL OPTIONS + 9.10. PACKAGE MANIPULATION - VIRTUAL OPTIONS + 9.11. DATABASE LOCATIONS + + 10. UPGRADING WITH APT + + 11. SEARCHING + 11.1. OVERVIEW + 11.2. NARROWING A PREVIOUS SEARCH + 11.3. MINOR MODES + 11.4. OTHER OPTIONS + 11.5. EXAMPLES + + 12. RAMDISK + 12.1. OVERVIEW + + 13. FILES + + 14. SEE ALSO + + 15. BUGS + +0.2 Copyright Notice +-------------------- + + Copyright © 1999 Jonathan D. Rosenbaum + + SWIM, including this manual, is free software; you may 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 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 with + the swim source as the file `COPYING'. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +------------------------------------------------------------------------------- + + +1. DESCRIPTION +--------------- + + *swim* is a powerful *package administration* and *research tool* for + both an *installed Debian distribution*, and/or *not-installed virtual + Debian distribution(s)* allowing querying of software packages with a + variety of package information options, and powerful searches. Virtual + options which include ftp, installation, and package removal + capabilities can be seamlessly combined with querying or searches. + *swim* can be used on computer systems which either have, or do not + have a Debian distribution installed. + + +------------------------------------------------------------------------------- + + +2. COMMAND LINE OPTION SYNTAX +------------------------------ + + When you press ``*swim* <*enter*>`` you will see a listing of command + line options in a particular syntax. This is to help you understand + under what context to use the options. When you enter the options on + the command line, the brackets, parentheses, braces, diamonds, and + question marks are not actually used. + + *Major Mode Option* + + All command line options for *swim* always start with a *major mode + option*, except for ``swim `` which will show the whole listing + of options. A major mode option is surrounded in braces *{ major mode + option }*. In the case of {--search} there are the alternative major + mode options {--refinesearch} and {--research}, but because --search + needs to be used first before either of these two options, + --refinesearch and --research are surrounded in parentheses (). + + Note: Through the other chapters of this manual *{}* is assumed for + the *major modes* in the *usage:* section shown at the beginning of + every chapter. + + Let's take a closer look at this situation: + + `{--search ? (--research || --refinesearch)}' + + `*||*' or `*|*' are used to indicate `*or*', `*?*' indicates + `*optional*', indicates an *argument* (a required argument - + see Arguments below), (parenthesis) means `if used, must be used after + the previous required option was used'. Note: for readability + `--research' and -`-refinesearch' are not surrounded in `{}'. + + *Normal Options* + + Options to the major mode options are enclosed in brackets *[ option + to major mode ]*. `swim [-n]' <`enter'> (assume enter from here on + out), for instance, will show all the command line options without + using the pager. The pager which swim uses can be set in *swimrc* (see + *swimrc(8)*). ```swim {--help} [-n]''' will provide brief explanations + of all of swim's options without using the pager. In this case the + major mode option *{--help}*, and the option *[-n]* were used. + + *Dashes* + + Options which have a single dash can be combined with other single + dashed options *(-qaint)*. Double dashed options need to be entered by + themselves *(--help --nopager)*, many double dashed options have an + alternative single dash option *(-n for --nopager)*. The meaning of + options is related to the major mode they are being used with. *[-n]* + means no pager when called with *{--help}*, but it's a reference to + the not-installed databases when used with *{-q --query}*, fortunately + most options do not have double meanings. + + *Arguments* + + Many options require an argument. Arguments are enclose in diamonds < + *argument* >. An argument to an option may also be optional in which + case a question mark ``*?*'' will be placed between the option and the + argument. *[-l ? <[--df]>]* illustrates such a situation. *[-l]* shows + a file listings, and optionally the option *[--df]* can be use with + *[-l]* to show an expanded listing. + + *[--dbpath* <*dir>]* requires an argument, this time the argument + would not be another option, but rather it is a directory. + + Rule: When an option is an argument to another option it can be + written anywhere, but when a non-option is an argument <*dir*> + *(notice no brackets)* it has to be placed directly after the option. + Sometimes, there may be alternative arguments divided with ``*|*''. + <*argument1|argument2*> means use argument1 or argument2, but not + both. + + Based on what we now know, let's compare this situation to the + *{--search}* situation shown above: + + `[--ftp ? --source | --source_only ? <[--diff]>]' + + In this case *--source* or alternatively *--source_only* can be + optionally used along with *--ftp* because they aren't in parentheses + *()* (also notice: | was used instead of ||, but means the same thing + ``or''). *--diff* can optionally be provided as an argument to either + *--source* or *--source_only*. For readability --source and + --source_only weren't enclosed in brackets. + + *Global Arguments* + + A *global argument* can be typed anywhere on the command line, and can + be an option or text. If global arguments exist they are placed last + after the list of normal options that can be used with a major mode + option. + + [targets | -S] and [targets|APT|DF] are examples. {-q}, {--initndb}, + and {--rebuildndb} all use global arguments. + + *Minor Mode Options* + + {-q --query} will generally use zero or more minor mode options + [-afpgn --dir], with one exception (see chapter 9, `QUERYING THE + INSTALLED AND NOT-INSTALLED DATABASES '). + + +------------------------------------------------------------------------------- + + +3. VERSION +----------- + + usage: *swim --version* + + This shows the version for the swim program. + + +------------------------------------------------------------------------------- + + +4. HISTORY +----------- + + usage: swim --history + swim -h + + options: [--arch ] [--dists ] + [--n] [--dbpath

] [--root ] + + This shows a shell-like history of searches and the most recent + --stdin edit. History is numbered with the most recent action being 1, + and the earlier actions being of a higher number until the maximum + amount of lines set in the HISTORY variable in `swimrc(5)'. A separate + history is kept for each architecture-distribution. + + +------------------------------------------------------------------------------- + + +5. MAKING INSTALLED SYSTEM DATABASES +------------------------------------- + + + +5.1. Initial database making, and Rebuilding for an Installed system. +---------------------------------------------------------------------- + + usage: swim --initdb + swim --rebuilddb + + options: [--dbpath ] [--root ] [--lowmem] + [--split_data ] + + An *installed Debian distribution* is one in which packages are + installed using *dpkg* or some front-end to *dpkg* like *apt* or + *dselect*; *swim* supports installation through *apt*. These major + modes are for a computer with an *installed Debian distribution* and + make the databases which allow querying and searching capabilities for + the installed distribution. + + *--initdb* is run when the databases do not exist yet, *--rebuilddb* + is run if the databases have become corrupt, or you want to rebuild + the databases instead of updating them. + + *--dbpath* can be specified as an alternative location for where the + databases will be made. The default location is ``*/var/lib/dpkg*''. + An argument like ``*/otherstuff*'' could be provided, and then the + databases would be made here instead. + + *--root* allows a database to be made for a Debian distribution + installed on a different partition. If the distribution is mounted on + */New_Debian*, ``*/New_Debian*'' would be the argument to root. The + databases would be made for the Debian distribution installed on the + ``*/New_Debian*'' partition. + + *--dbpath* and *--root* can be used together. Given the previous two + examples, the databases would be made on ``*/New_Debian/otherstuff*'', + assuming ``*/New_Debian/otherstuff*'' actually existed. + + *--lowmem* uses a method which uses a small amount of memory to make + the databases. By default *--initdb* and *--rebuilddb* use a method + which fully takes advantage of memory, this is a good thing, because + it means the databases are made in a quicker manner. On a computer + with a K6-200 CPU, 64MB of memory, and 1500 installed packages, the + databases can be made in 4.5 minutes using the default method, and 11 + minutes using the low memory method. The high memory method is the + default because in general the size of a distribution is related to + how much resources a computer has, and probably a large installation + is unusual. If you get an ``out of memory'' when you use the default + method, or if your system is overloaded to begin with, the *--lowmem + method* is the prefered way. + + *--split_data* determines the size of the files in the temporary + directory used to contruct the database. The default is 25000 lines + per file. If you are using the *--lowmem method* you may want to + provide a different argument to *--split_data*, like ``*--split_data + 10000*''. This is a subject of experimentation. + + + +5.2. UPDATING +-------------- + + usage: *swim --db* + + options: *[--dbpath* <*dir*>*] [--root* <*dir*>*] [--check]* + + *--db* allows you to update the databases by hand when packages have + been removed, added, or changed. swim will automatically run *--db* + under certain conditions. + + *--check* prints out the changes to STDERR, and the total to STDOUT + without proceeding with the update. + + See section 5.1, `Initial database making, and Rebuilding for an + Installed system. ' for options *--dbpath* and *--root*. + + + +5.3. REBUILDING THE SEARCH +--------------------------- + + usage: *swim --rebuildflatdb* + + options: *[--dbpath* <*dir*>*] [--root* <*dir*>*]* + + swim makes the flat databases *searchindex.deb* and *dirindex.deb* for + doing *powersearches*. Instead of rebuilding these databases everytime + *--db* is run, new information is just appended to these databases, + and old information is kept. Generally, this is not a problem because + only files and directories which the other databases actually know + something about will be refered to. But in a situation where a file + has changed into a directory, the *powersearch* may not work properly, + because the old file name remains in *searchindex.deb*, and the new + directory name is now in *dirindex.deb* directory. In general, it + takes a lot of changes to the installed system before it is really + becomes necessary to rebuild the flat databases. This process takes + less than a minute on a K6-200 with 1500 packages. + + See section 5.1, `Initial database making, and Rebuilding for an + Installed system. ' for options *--dbpath* and *--root*. + + +5.4. FILES +----------- + + Databases which are made: + + packages.deb + fileindex.deb + statusindex.deb + groupindex.deb + searchindex.deb + dirindex.deb + + +------------------------------------------------------------------------------- + + +6. IMPORTANT DEBIAN DATABASES FOR NOT-INSTALLED DATABASES +---------------------------------------------------------- + + + +6.1. A. downloading the important databases with --ftp. +-------------------------------------------------------- + + usage: swim --ftp + + options: --Contents + --Packages + [--dists ] [--arch ] + [--onec] [--Release_only] + + +6.2. OVERVIEW +-------------- + + *swim* provides a method so that all information about an existing + Debian distribution is quickly accessible through databases. Debian + already provides flat file databases for all its distributions. One + database called ``*Contents-(architecture)*'' provides a complete + listing of all the files associated with each package, the other much + more important database called ``*Packages*'' provides everything from + the Package's description, to all the dependencies for that package. + The Packages database is a crucial database for other important Debian + administrative tools like *dpkg* and *apt*. + + +6.3. DISTRIBUTION DEFINED +-------------------------- + + Debian Distributions choose a name which reflect the development state + of that distribution. The distribution named ``*unstable*'' is where + the majority of the development processing occurs, after *unstable* + has reached a certain level of maturity, it's copied over to a new + distribution called ``*frozen*'' which is tested extensively before + becoming the new ``*stable*'' distribution. The *frozen distribution* + retains the *Release version number* of the *unstable distribution*, + and the *unstable distribution* receives a new *Release version + number*. Eventually, *frozen* becomes *stable*, and at this point both + *frozen*, and the older *stable distribution* are removed. Code names + are associated with the *Release Version number* given for each of the + distributions. This is much better for mirroring Debian sites. + + *swim* was designed to ignore these code names, and instead shows the + user the *Release version number* associated with the distribution. + Swim users must always use the real distribution name, or swim will + not work properly. This is a nice feature because it allows user to + make decisions related to the management of their databases, and makes + research much more easier. + + The other Debian distribution which swim recognizes is *experimental*. + This distribution *does not have any Release version number*, and + contains packages which are considered risky because of their + development level. + + + +6.4. SECTIONS +-------------- + + Each Debian distribution has sections related to the relationship of + each of the packages to the *Debian's Policy Manual*. In ``*main*'' + there are packages which have a correct relationship with these + Policies. Packages in ``*contrib*'' comply with the *DFSG* (*Debian + Free Software Guidelines* found in the *Debian Policy Manual*) but + have various limitations like requiring a package which is found in + non-free, or is not in the Debian archive. Packages in ``*non-free*'' + do not comply with the *DFSG* but are electronically distributable + across international borders. The ``*non-us*'' section is found + outside of the United States and exists for packages which have export + restrictions. + + + +6.5. ARCHITECTURES +------------------- + + Distributions also have architecture specific sections since not all + packages compiled for one architecture can run on all other + archictectures, however, there are a large percentage of packages + which do run on all architectures. The architectures are *alpha*, + *arm*, *i386*, *m68k*, *powerpc*, *sparc*, and more recently + *hurd-i386* which represents packages for the hurd GNU kernel for the + i386 architecture. + + + +6.6. SWIMZ.LIST +---------------- + + *--ftp* uses a file called *swimz.list* which has the same type of + format (see format below) as the *sources.list(5)* which *apt* uses. + There are some differences. The *first difference* mentioned above + (see section 6.3, `DISTRIBUTION DEFINED ') requires that the + distribution names never should be the code names for the *Release + version*. *Secondly*, *apt* only retrieves databases specific to one + archictecture, normally the one you are running *apt* on. With *swim* + though you can fetch databases for any, or every architecture by + adding the architecture to ``deb'' with a hyphen (deb-hurd-i386). If + deb has no architecture appended it is assumed that the architecture + you want is the same as the system you are running *swim* on. + *Thirdly*, at this time *swim* only supports the ftp method. + *Fourthly*, you can change *swimz.list* as often as you want without + worrying about databases being removed so that that the *swimz.list* + and the downloaded databases match. This would occur with *apt's* + *sources.list(5)* if you removed a site. *Fifthly*, databases are kept + in a compressed state. *Sixthly* because the list is used for both + Contents and Packages, more flexibility is provided by only allowing + the default distribution/archictecture or distribution/architecture + provided on the commandline to be downloaded. + + For *apt* users: If you are using *apt*, and *swim* together it is a + good strategy to use the real distribution name in the *sources + list(8)*, and to have an exact copy of the *sources.list(5)* ftp sites + in the *swimz.list*. Packages databases specific to the architecture + *apt* is using can be retrieved using *swim --apt --update* (this also + will keep track of the Release version), and then *swim* can be used + to fetch the architecture specific *Contents database* as shown below. + It should also be of interest to note that Packages downloaded by + either swim or apt can be used interchangeably by using 'cp -a' and + 'gzip -d' or 'gzip -9'. + + Here is a brief outline of the format required by *swimz.list*. + + *deb uri distribution [section ... ]* + + *deb* - represents a standard Debian distribution. And is simply + written as deb or with the architecture appended (*deb* or + *deb-alpha*). + + *uri* - Universal Resource Identifier is exactly how you would enter + an address into a web browser. This address is the base of a Debian + distribution, generally this is right before the directory called + ``*dists*''. So if *dists* is found in */stuff/pub/debian/dists*, and + the site is *somewhere.com* then the uri would be + *ftp://somewhere.com/stuff/pub/debian*. + + *distribution* - This can be *unstable*, *frozen*, *stable*, + *experimental*. Distribution can also be a path which must end with a + slash like *unstable/binary-i386/*. This is used when there is no + section as in the experimental distribution or in sites which do not + have symlinks to the non-us section. No section would be mentioned in + this situation. + + *section* - *main*, *contrib*, *non-free*, *non-US* (write it this + way). + + + +6.7. SWIMZ.LIST EXAMPLES +------------------------- + + Examples (each on one line): + + *deb-alpha ftp://somewhere.com/stuff/pub/debian unstable main contrib + non-US* + + This will fetch the alpha databases from somewhere.com for the + unstable distribution for the main, contrib and non-US sections. + + Note: In these next two examples you can not append any architecture + to deb with a hyphen. + + *deb ftp://somewhere.com/stuff/pub/debian project/experimental/* + + This will fetch the experimental database, but there is not a + Contents-(architecture) database for this distribution. Notice that it + ends with a slash. + + *deb ftp://somewhere.com/stuff/pub/debian-non-US stable/binary-i386/* + + This will fetch the i386 databases for the stable distribution for + non-us, + + +6.8. FTP OR APT? +----------------- + + How you use major mode *--ftp* depends on your goals. Even if you are + using *apt*, you may be interested in keeping tabs on different + architectures. In this case you would have to download the *Packages + databases* specific to these architectures. If you are only interested + in the architecture which *apt* is interested in, then you only need + to use *--ftp* to fetch the *Contents database(s)*. But, because it + isn't a requirement to set up a virtual filesystem, you are not + required to fetch the Contents database. The *advantages* of fetching + the Contents database is determined by the method you choose to make + the database (see chapter 7, `MAKING NOT-INSTALLED DATABASES '). These + advantages include the ability to *view a listing of the files and + directories* associated with a package, the ability to *query files + and directories* to find out which packages relate to them, and the + ability to perform a *powersearch* on all the files and directories to + find the associated packages. + + + +6.9. OPTIONS +------------- + + *Remember:* If you want to download a different + distribution/architecture other than the default specified in your + configuration file, you must specify this on the commandline. + + *--Packages* determines where you want the Packages database as well + as the Release data put when they are downloaded. The *DF argument* + implies that the databases will be put in your default directory (see + `swimrc(5)).' These databases can later be located by the major modes + *--initndb and --rebuildndb* just by using *DF* as an argument. + Alternatively, these databases can be put in any directory you choose + by providing a *directory as an argument*. + + *--Contents* determines where you want the *Content-(architecture)* + `database(s)' put. (see --Packages). + + *--onec* will download only one Contents-arch per + distribution/architecture specified on the commandline or by default. + + *--Release_only* will download only the Release data for the + *swimz.list* or particular *Package(s)* mentioned on the command line. + + *--dists* will only find the distribution which corresponds to the + argument provided this option. + + *--arch* will only find the architecture which corresponds to the + argument provided this option. The different architecture needs to be + specified in swimz.list with a hyphen and the architecture appended to + deb (deb-(arch)). + + +6.10. B. downloading the important databases with apt, and maintenance +options. +---------------------------------------------------------------------------- + + usage: *swim --apt* + + options: *[--update] [--clean] [--autoclean] [--check]* + + Please read section 6.1, `A. downloading the important databases with + --ftp. ' for more information. + + *--update* calls *apt* to download the Packages databases. + + *--clean* is a call to an *apt* option to remove any packages stored + in *apt's* storage area for downloaded packages. The default for this + storage area is */var/cache/apt/arhives* + + *--autoclean* will only clean out packages which are not found in + apt's cache. + + *--check* tests and updates apt's cache. + + +------------------------------------------------------------------------------- + + +7. MAKING NOT-INSTALLED DATABASES +---------------------------------- + + usage: swim --initndb + swim --ndb + swim --rebuildndb + + options: [--Contents ] + [--main] [--contrib] [--non-free] [--non-us] + [--arch ] [--dists ] + [--dbpath ] [--root ] [--alt] + [--split_data ] [-v] [--cron] + [targets|APT|DF] + + + +7.1. OVERVIEW +-------------- + + The *not-installed database* provides swim with many capabilities like + the searching, and querying of packages which do not actually exist on + the live filesystem, as well as the ability to seamlessly install + packages while searching or quering, or the ability to fetch the + packages source code. The *virtual filesystem* is optional, but it is + highly recommended. These two major mode options set up these + databases, after determining the level of interaction which you want. + + Whenever *swim* makes databases it thinks only in terms of one + distribution and one architecture. This keeps things logical. *swim* + does have the ability to take Packages files with multiple + architectures, and distributions, and to extract information for one + distribution and one archictecture to make its databases. This could + provide interesting information from dumps from *apt* (`apt-cache + dumpavail'). + + *--initndb* creates the initial not-installed databases for a + particular architecture and distribution, and *--rebuildndb* remakes + the not-installed databases for that same architecure and + distribution. If not otherwise specified *swim* *will use the values* + it finds in *swimrc* to determine what architecture and distribution + you want to use to make *swim's* databases. Otherwise... + + +7.2. OPTIONS +------------- + + *--arch* allows an argument to override the *architecture* found in + *swimrc*. + + *--dists* allows an argument to override the *distribution* found in + *swimrc*. + + *--alt* is used for a distribution with a Debian archival structure, + but which has a different name. This allows for alternative + distributions. + + When *APT* or *DF* are provided as arguments (see below), by default + the *Packages* which pertain to the sections found in *swimrc* will be + shown. If you only want certain sections you may specify them on the + command line. If you are not using *APT* or *DF*, it is a good idea to + make sure that either the sections found in *swimrc* or the sections + you put on the command line match the *Packages* you a targetting + because this is much more effecient. + + *--main* will override the sections found in *swimrc*, and will use + this section. + + *--contrib* will override the sections found in *swimrc*, and will use + this section + + *--non-free* will override the sections found in *swimrc*, and will + use this section + + *--non-us* will override the sections found in *swimrc*, and will use + this section + + Global arguments *targets|APT|DF* must be used with either of these + two major modes to find the *Packages* databases. targets can be a + full path to one or a set of *Packages*. *APT* will use the *Packages* + found in */var/state/apt/lists*, and *DF* will use the Packages found + in the default directory for *swim* (see `--ftp'). If you use either + *APT* or *DF* you will be given an *interface* which allows you to + choose one *Packages* database for each section you would like to use + from the various sites. This *interface* shows the *site*, *date*, + *size* and *Release version* for each *Packages*. + + *--cron* allows you to override the *interface* produced when *APT* or + *DF* is provided as an argument. This is useful if you want to + automate the database making process. *--cron* will choose the newest + `database(s),' if cron notices that the Release version has changed, + cron will not proceed, but will provide a warning instead. This allows + you to make the appropriate changes and choices. + + *--Contents* can be give one of four arguments: + + *1).* If you have a *Contents-(architecture)* database in a target + location you know about you may provide a path to the location. The + *Contents* database can be compressed. + + *2).* If you prepend the path with the letters *FDB* (meaning flat + database) when the databases for swim are made, instead of using the + Contents database to make: + nfileindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + + Only the *ncontentsindex-arch-dists.deb.gz* database will be made + which allows the ability to view file/dir listing for not-installed + packages, but does not provide the virtual file system or powersearch + capabilities which the other databases would have provided. + + *3).* The argument *DF* may be used if you have used *--ftp* with the + *DF* argument to the option *--Contents* (see `--ftp'). In this case + it is assumed you are also using global arguments *DF* or *APT* for + the Packages databases. This will give you an *interface* (if --cron + isn't used) allowing you to choose one *Contents* database for the + particular distribution you want to make the databases for. + + *4).* *FDB* does the same exact thing with *DF* as it does with the + before mentioned *FDBtarget*, and provides the *interface*. + + *-v* will only work if you have dpkg installed. It allows swim to + verify *swim's* own built-in version comparison function with *dpkg's + version comparison function*. This is good for debugging purposes, and + produces a report called *.version_compare* in the same location that + *swim's* databases are made. + + *--split_data* is only advantageous if *--Contents* is being used. See + *--initdb* for more information about the *--split_data* option. + + See section 5.1, `Initial database making, and Rebuilding for an + Installed system. ' for options `--dbpath' and `--root'. + + +7.3. UPDATING +-------------- + + `--ndb' has the same options as --initndb and --rebuildndb except for + --split_data. It also has a new option `--nue' which will never have + to be used unless the experimental distribution or non-us section are + found in Contents (which presently isn't the case). `--check' prints + out the changes to STDERR, and the total to STDOUT without proceeding + with the update. `--status_only' can be used after a new package has + been installed to update the status, after which -qni and -qi will + correlate properly. + + +7.4. REBUILDING THE SEARCH +--------------------------- + + `--rebuildflatndb' serves the same purpose as --rebuildflatdb. See + section 5.3, `REBUILDING THE SEARCH ' + + +7.5. FILES +----------- + + Databases and reports which are made (arch = architecture dists = + distribution): + + npackages-arch-dists.deb + nfileindex-arch-dists.deb requires <--Contents> + nstatusindex-arch-dists.deb + ngroupindex-arch-dists.deb + nsearchindex-arch-dists.deb + ndirindex-arch-dists.deb + .packagesdiff-arch-dists.deb requires <--Contents> + + + +------------------------------------------------------------------------------- + + +8. PREPARING YOUR INSTALLATION FOR APT +--------------------------------------- + + usage: swim --audit + swim --status + swim -C + + If you are using *apt* with *swim*, and this is the first time you are + using it with your installation, check your live installation with + this major mode. This is a call to *dpkg -C (--audit)*, and will show + any packages which are not properly configured or installed. If you + get any output, make corrections. The goal is to get absolutely no + output whatsoever because it is under these conditions that apt will + work properly. See the section 9.8, `REMOVING AN INSTALLED PACKAGE - + VIRTUAL OPTIONS ' with *-q* to remove the offending packages. You may + have to remove the package by hand under unusual situations like when + it is not just dependencies (see `-T') between packages keeping the + package from being removed perhaps due to a broken script (see + `--scripts'). In an extreme case you could manually remove the entry + for this package from the */var/lib/dpkg/status* database, and hunt + down and remove all the files associated with the package with *swim's + -l* option. When you are done if you still want some of the packages + you removed, use *apt* to reinstall them with *swim's -xyz* option. + Also, *apt* provides its own built-in method to clean up your system, + and will provide instructions, but you still may have to do some of + the cleaning yourself as discussed above. + + +------------------------------------------------------------------------------- + + +9. QUERYING THE INSTALLED AND NOT-INSTALLED DATABASES +------------------------------------------------------ + + usage: swim -q [-fpgn --dir] [targets | -S] + swim --query [-fpgn --dir] [targets | -S] + swim -qa || swim --query -a + + options: [--total -t] [-i] [-l ? <[--df]>] [-d] [-c] + [--scripts] [--preinst] [--postinst] [--prerm] + [--postrm] [-v] [--dbpath ] [--menu -m] + [--shlibs] [-T] [--pre_depends] [--depends] + [--recommends] [--suggests] [--conflicts] + [--replaces] [--provides] [--md5sum] [--root ] + [--copyright] [--changelog] [--allgroups] + [--arch ] [--dists ] + [--ftp ? --source | --source_only ? <[--diff]>] + [--stdin] [--extract] ] + [-xyrz --remove ? <[--nz]>] [--purge] [--apt2df] + [--df2apt] + + global arguments: *[targets | -S ? <\d{1,}>]* + + Quering almost always involves using *-q or --query* with zero or one + or a combination of the *minor mode options* (package specification + options), and one or more (only one for `-g') targets specific to the + minor mode, or the results of a search (`-S'). [`-S' can be provided a + numerical argument pertaining to the past history.] This can be + combined with one or more options. The one exception is ``*swim -q + --allgroups*''. + + *--query or -q* can be used by itself or with *-n* to query known + package names or package names with versions. ``*swim -q test1 + test2_0.3-1*'' would produce the output: + + test1_1.0-2 + test2_0.3-1 + + +9.1. MINOR MODES +----------------- + + *-n* is the minor mode option to access the *not-installed system*, it + can be combined with the minor mode options *-a*, *-g*, *-f*, or it + can be used by itself. + + *-a* allows *every package* on an installed or not-installed (*-n*) + system to be queried. ``*swim -qan*'' will show all the package names + with versions for the not-installed system + + *-f* allows *files or directories* to be queried, when used without + any options the package name with version is shown. *--dir* will only + query directories, this is useful if you are not sure whether what you + are quering is a directory or a file. When a directory is queried, + swim shows all packages which exist below the queried directory. + ``*swim -qf /*'' is exactly the same as ``*swim -qa*''. Hint: ``*swim + -qf .*'' and ``*swim -qf **'' are quite different, the first shows all + packages which exist below the current directory, and the second will + show the package which each file in the current directory comes from. + + *-g* will query a *group* (also called a section, see subsection + 9.5.3, `SECTION AND PRIORITY ')) of packages. Groups represent + subjects which packages with similiar characteristics are catagorized + by. To view all the groups found in an installed or not-installed + system use ``*swim -q --allgroups*'' or ``*swim -qn --allgroups*''. + ``*swim -qg hamradio*'' or ``*swim -qng hamradio*'' shows all the + package names for the hamradio group. + + *-p* is used to query a *Debian package*, these packages are + distinguished by their ``deb'' ending, but swim can tell whether a + file is a debian package even without the ending. Called without any + options the package name with version will be shown. + + +9.2. SPECIFYING THE DATABASES TO USE +------------------------------------- + + *--dists* will use the databases for the argument given, otherwise the + databases pertaining to the value found in swimrc will be used. + + *--arch* will use the databases for the argument given, otherwise the + databases pertaining to the value found in swimrc will be used. + + Example: *swim -qat --arch hurd-i386 --dists unstable* + + Assuming these databases exist this will show all packages and their + versions for the unstable distribution and architecture hurd-i386 even + if the values in *swimrc* are i386 and stable. + + see section 6.1, `A. downloading the important databases with --ftp. ' + and chapter 7, `MAKING NOT-INSTALLED DATABASES ' for more information + about the databases. + + +9.3. OPTIONS +------------- + + *--total or -t* are *used to override the output suppressor*. The + output suppressor will not show output if a certain number of packages + is exceeded, instead it will show the number of packages you are + querying. This is useful for two reasons, first, knowing the number of + packages you are quering can be very informative, second, it gives you + a chance to add to the command line a pipe to a pager, ex: ``*swim + -qat | less*''. You can set the number that the output suppressor + works at as high or low as you want in the *swimrc(8)* file. By design + the *-t* option will have to be used if the *-i* option is used and + more than one package is being queried. This option can also be used + to alter the output of the various script options (--scripts, + --preinst, --postinst, --prerm, and --postrm). + + *-i* provides *information* about each package being queried. The + format differs slightly for the installed packages versus the + not-installed packages. see section 9.5, `FORMAT ': + + *-l* provides a listing of the files associated with a package. If the + option *--df* is provided as an argument, all the directories + associated with package will be shown. It is important to remember + that many packages provide directories which become important to them + after they are installed, so the option *--df* often provides + necessary information which *-l* called by itself would have not. + + *-d* shows the documentation which the package provides found in + */usr/doc/**, */usr/man/**, */usr/info/**. Other documentation which + the package may provide in a non-standard location will not be shown. + *-d* takes precedence over *-l*, so if *-l* is used on the command + line with *-d*, only the output for *-d* will be shown. + + *-v* is a special option which works only with the minor mode *-p*. It + can be used with *-l*, *--df*, *-d*, to show the packages files and/or + directories in long format (`ls - l'). + + *-c* will show the configuration files packages use. If the package + does not have a configuration file then nothing will be shown. The + output will show the file and its path indented one space with the + *MD5 checksum*. This will not work with *-n*. + + *--scripts* shows all scripts associated with a package with the name + of the script presented before each script in this way + *#####scriptname######*. If the scripts are called individually by + using the script options *--preinst*, *--postinst*, *--prerm*, or + *--postrm* no title is shown, this is nice for writing to a file. If + *-t* is used with the individual script options a title will be shown, + this makes sense because normally only individual packages would be + queried to write a script to a file, and *-t* wouldn't be used in this + situation. Scripts are the soul of Debianized packages allowing + packages to be installed, configured, and removed seamlessly and + cleanly under all kinds of conditions. These options do no work with + *-n*. + + *--menu or -m* is used to view menufiles which belong to various + packages. If the package does not have a menufile nothing will be + shown. This option can be useful in troubleshooting a menu entry which + does not seem to work, or in finding out where the menu entry is. + *Joost Witteveen's Debian menu system* is a centralized program which + interacts with all kinds of menus. *Please read the documentation* + ``*swim -qd menu*'' which comes with the menu package to find out + more. This will not work with *-n*. + + *--shlibs* shows a list of shared libraries certain packages supply. + The *Debian Packaging Manual* (packaging-manual) provides detailed + information about the format of a shlibs file. This will not work with + *-n*. + + *--md5sum* checks *MD5 checksums*. It can be used with *-l*, *-d*, + *-c*, or *-p*. If there are checksums available the md5sum result will + be either *OK*, *FAILED*, or *MISSING*. *MISSING* means that although + a checksum exists, the file can not be found. The result is put after + the file and its path and the *MD5 checksum* or the package name and + version and the *MD5 checksum*. + + *--copyright* does a case insensitive search for copy or license in + the */usr/doc/packagename* directory. This should show how the package + relates to *Debian's Policy Manual*. + + *--changelog* searches for any files in */usr/doc/packagename* which + look like changelogs. Debian packages always have a *Maintainer's* + changelog for the package. There may be a separate changelog kept by + the author of the program. + + +9.4. PACKAGE RELATIONSHIPS +--------------------------- + + *-T* shows all the package relationships of packages. Individual + package relationships can be viewed using *--pre_depends*, + *--depends*, *--recommends*, *--suggests*, *--replaces*, *--conflicts* + or *--provides*. Package relationships are the spirit of Debian + packages, here is a quick overview briefly reiterating what can be + found in the *Debian Packaging Manual*. *Package Maintainers* set + these relationships in control file fields of the same name. + + *Dependencies* *Pre-depends* - means that the pre-depended package or + packages must be installed before the queried package can be + installed. Most packages which have pre-dependencies are usually + essential and required packages. + + *Depends* - declares an absolute dependency to another package or + packages either *real or virtual*. The queried package cannot function + without this other package. + + *Recommends* - declares a strong, but not absolute dependency to + another package or packages either *real or virtual*. You would + usually find the recommended package together with the queried package + in a normal installation. + + *Suggests* - can be one or more packages either *real or virtual* + which would be useful to the queried package, but are not necessary. + *Alternative Packages* + + *Conflicts* - is a package or packages either *real or virtual* which + would cause problems with the queried package, and would not be + allowed to be installed while the queried package was installed. + + *Overwriting files and Replacing Packages* + + *Replaces* - allows the queried package to replace another package or + packages by overwriting their files, after which the previous package + would be considered to have disappeared. Essentially this allows the + queried package to take over the package or packages. In a situation + where there was a Conflict between the queried package and these + packages this field would help determine which packages should be + removed. + + *Virtual Packages* + + *Provides* - declares a virtual package which may be mentioned in + *Depends*, *Recommends*, *Suggests*, or *Conflicts*. *Virtual + packages* allow one or more packages to share the same name of another + package, which means if the queried package has a reference to a + virtual package in one of the before mentioned package relationship + fields, then whatever packages provide the virtual package are also + being listed. + + +9.5. FORMAT +------------ + + *1). Installed system* + + Package: name Status: hold ok installed + Version: 1.1-1 Essential: no + Section: namers Priority: extra + Installed-Size: 10 Source: generatename (2.0-1) + Maintainer: name + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + + *2) Not-installed system* + + Package: name Status: r> hold ok installed (1.1-1) + Version: 1.1-2 Essential: no + Section: names Priority: extra + Installed-Size: 11 Source: generatename (2.0-1) + Size: 43000 Architecture: i386 + Distribution: experimental + Maintainer: name + Description: hostname maker + A nice way to figure out a hostname nobody + else has. + + There are several things to point out. The difference between the two + outputs relates to the addition of the Distribution, Size, and + Architecture fields for the not-installed query. Installed-Size is how + many kilobytes the package will occupy when it is unpacked, whereas + Size is the size in bytes of the package. + +9.5.1. STATUS FIELD +-------------------- + + The Status field provides the installation status of the package, this + holds true for the not-installed query as well. In a sense, the + not-installed database isn't always not-installed. If the + not-installed package is actually already installed, and the version + numbers are exactly the same, then the status will be the same for + either query. If the not-installed package is not installed then the + status will be ``not-installed''. In cases where the not-installed + package is already installed, swim uses it's comparison function to + figure out whether it is a newer of older package which is installed. + In the above example, swim realizes the same package is installed, and + only the debian-revision has changed, hence the only difference is + that the revision number is greater ``r>'' for the not-installed + package. When only the debian-revision has changed it can safely be + assumed that the author (creator, programmer) of the same program has + not made any changes to the same program, but the Debian maintainer + has made a change to an aspect of the package like a change in the + script the package uses to properly install. You may have also noticed + that the status field shows the version number of the installed + package enclosed in parenthesis. + +9.5.2. SOURCE FIELD +-------------------- + + The Source field is present in these examples, but the Source field + will not always be present for packages. In cases where the name of + the source package is the same as the the name found in the Package + field, and the version number of the source package is also the same + as found in the Version field, then there will be no Source field. In + the above examples there is a Source field. In this case name was + probably one of many packages generated from the source package called + generatename. In this particular example generatename also has its own + unique version number 2.0-1 enclosed in parentheses, if no version + number had been mentioned then the source package would have the same + version number as found in the Version field. + +9.5.3. SECTION AND PRIORITY +---------------------------- + + Section shows the subject which a package is categorized with (see + `-g'). Priority shows how important the package is to have installed. + In the case of the not-installed databases the information for these + fields is almost always available from the Packages databases, but + this is not always the case for Debian packages. For packages which do + no provide this information swim will do its best to fill in the + blanks from information found in the installed and not-installed + databases. If proper information can not be found it will be indicated + as ``unavailable'' or ``unknown.'' Unavailable would indicate that + information about the package exists, but it is from a different + version (includes debian-revision), and no information exists for this + version. Unknown means no similiar package exists, and there is + absolutely no information about this package in the databases. + + When a Debian package is queried using the *-p* option you will get + output like the first example shows, the status field is also + calculated. + + +9.6. FTP - VIRTUAL OPTIONS +--------------------------- + + For ftp capabilities swim uses the *swimz.list* to determine which + sites it will check for the requested packages. The first site which + fills the request will be used, otherwise *swim* will go through all + the sites avoiding repeats, and if no sites can fill the request, + *swim* will either quit or proceed on to check for another request. + + *--ftp* allows the queried package, its source package, or just the + source package diff to be downloaded while being queried. This is + refered to as virtual downloading because the quering and the + downloading are seamless as though the package already exists locally. + This has to be used with the option *-n* because packages which which + are not part of the not-installed database are considered to already + have been downloaded. Packages which are already installed can be + downloaded or their source retrieved by setting up a database which + corresponds to these packages; if the installed packages belong to the + stable distribution, set-up the not-installed stable databases. + + Packages or source code are placed in an area below the default + directory mirroring the remote directory they were downloaded from + after their size and modification times are checked for correct + values. This area is called the *DF* directory, and although this + directory mirrors remote directories, it is not an exact mirror, but + specific to the requirements of swim because code names for Release + versions are not taken into account. For real mirroring capabilities + there exist many excellent programs. If a package has a *MD5 + checksum*, *--md5sum* will automatically be run and the value shown. + Regardless of whether or not the md5sum check is *OK* or not, the + package will still be put in the *DF* directory to allow the package + to be looked at, so watch the output from *--ftp* to check for *FAILED + md5sums*. + + Packages or source code packages will not be downloaded again if they + are found in the *DF* directory unless their *upstream-version* has + changed in the not-installed database, if the packages are not in the + DF directory and the remote *upstream-version* is different than the + not-installed *upstream-version* then the packages will not be + downloaded until the not-installed database is updated or rebuilt to + reflect the version change. Changes in the package's + *upstream-version* indicates that the `author(s)' of the program have + made changes to the computer code for the program contained in the + package or the source code package. On the other hand, swim will check + for a *debian-revision* change at the remote site if the package can + not immediately be found. If the package's *debian-revision* has + changed and the package does not exist locally in the *DF* directory, + it will be downloaded. This is a nice feature, especially for the + unstable distribution, because it tends to extend the time needed + before the not-installed database has to be updated or rebuilt to + match the changes at remote sites. + + *--source* is used with *--ftp* to download the source code package. + *--source_only* will download the source code package without the deb + package. *Source packages consist of three files*. The *source control + file* which ends in ``dsc'', the *original source archive* which is a + compressed tar file, and the *unified context diff* showing the + changes necessary to make the original source into Debian source. The + diff can be downloaded by itself if *--diff* is provided as an + argument to *--source or --source_only*. + + For *apt* users: *apt* allows packages to be downloaded, but if more + than one package is required for the package relationships to be + proper, *apt* will download all these packages. *--ftp* allows + specific packages to be downloaded, packages from other architectures, + and source packages to be downloaded, here lies the advantage of this + option over using *-xyz --nz* (see below). If a particular package has + been dowloaded into the *DF* directory and it is needed by *apt* for + installation, simply copy or move the package from the *DF* directory + to */var/cache/apt/archives* before running *apt*, and the package + will not be downloaded by *apt* again; future versions of *swim* will + have an option to automatically accomplish this (see `--df2apt'). + + +9.7. APT - VIRTUAL OPTIONS +--------------------------- + + apt-get(8) is a nice package relationship checker from the *apt* + package which figures out what needs to be done to properly install a + package or packages when one or more package names are provided to it. + *apt-get* will get all packages which are needed using a variety of + methods, and then *apt-get* interacts with *dpkg* in a way which + allows for a successful installation. + + *-xyrz, --remove, and --nz* can be used if *apt-get* from the *apt* + package is installed. These options allow for what is refered to as + virtual installation/removal. It is prudent to always test what will + happen by using the *-x* option alone before actually proceeding with + the installation with the *-z* option. *-x* will actually simulate + what would happen in an installation, showing which and how many + packages will be changed, which and how many new packages will need to + be installed, which and how many packages will need to be removed, any + conflicts, and what needs to be configured. *-y* will automatically + answer yes to any prompts *apt-get* may produce allowing *apt-get* to + run non-interactively. *-z* as mentioned before actually proceeds with + the installation using *dpkg* after the *apt-get* gets the packages. + You can append a minus sign to a package name to cause it to be + removed. *--nz* when used as an optional argument with *-xz or -xyz* + will only download the packages into */var/cache/apt/archives* or into + whatever directory you configured for holding archives for *apt*. + + *IMPORTANT*: *apt* makes it so easy to make changes to your + installation that it is highly recommended to do your research with + swim first. This can be done by checking package relationships, + file/dir listings, comparing the not-installed package to an installed + package if such exists, checking *--md5sum* and *-c* for the installed + package, and checking the Source field by running a *--search* (see + chapter 11, `SEARCHING ') to check to see how the source package has + been split into binary packages for the not-installed package versus + an installed package if such exists. Ofcourse, there are many other + things you could look at, and you can always do your research after + the fact. Presently *--db* is run only by hand, so you can check the + old state after an installation if you have not already run *--db*, + yourself. + + +9.8. REMOVING AN INSTALLED PACKAGE - VIRTUAL OPTIONS +----------------------------------------------------- + + *--purge* uses *dpkg* to remove an installed package or packages and + the configuration files as shown with ``*swim -qc packagename*''. + + *-r or --remove* removes an installed package or packages with *apt*, + but not the configuration files as shown with ``*swim -qc + packagename*''. You may also append a plus sign to a package name to + cause it to be installed. This option is used with -x or -x(y)z. + + +9.9. STDIN - VIRTUAL OPTIONS +----------------------------- + + *--stdin* works with either *--ftp*, *-x*, *-xyz*, *-xz*, *--purge*, + *-r*, or *--remove*. + + *--stdin* provides the *readline capabilities* commonly found in + shells allowing you to edit what is on the command line. You can edit + the command line, press enter and then recall the history, and make + more changes, or *type in exit to process the changed or unchanged + command line*. To find out more about what readline commands your + shell supports please read the man pages which apply to your shell. + Information for the bash shell can be found in `bash(1)' under the + title ``*Readline Command Names*''. + + Example: ``*swim -qgnx --stdin hamradio*'' will list all the packages + from the not-installed hamradio group on the command line, this list + can be edited then submitted to *apt-get* for a simulated + installation. Another instance of *swim* can be run at the same time, + perhaps ``*swim -qinTg hamradio*'' to help in making editing decisions + for *--stdin*. + + +9.10. PACKAGE MANIPULATION - VIRTUAL OPTIONS +--------------------------------------------- + + *--extract* only works with the *minor mode -p* to extract parts or + all of a Debian package. If the *argument ALL* is provided then + *everything found in the package will be extracted* below the current + directory in the exact directories found in the package. A particular + *file may be extracted in its exact location* below the current + directory by *entering the exact path for the file* as shown by + ``*swim -qpl*'' or ``*swim -qpd*'' as the argument. Alternativily, a + *file may be extracted in the current directory* regardless of its + proper location by *prepending PWD\! before the path* shown by ``*swim + -qpl*'' or ``*swim -qpd*''. Notice the backslash before the + exclamation point, this is because shells consider ! a special + character, so it has to be backslashed so that the shell knows that it + is not such a special character. Example: ``*swim -qpi --extract + PWD\!usr/bin/name --scripts name_1.1-2.deb*'' will extract the binary + name in the current directory from the name package, show information + for the name package, and show any scripts for the name package. + + +9.11. DATABASE LOCATIONS +------------------------- + + *--dbpath* can be specified as an alternative location for where the + databases would be found. The default location is ``*/var/lib/dpkg*''. + An argument like ``*/otherstuff*'' can be provided, and then the + databases would be found here instead. + + *--root* allows a database to be found for a Debian distribution + installed on a different partition. If the distribution is mounted on + */New_Debian*, ``*/New_Debian*'' would be the argument to root. The + databases would be found for the Debian distribution installed on the + ``*/New_Debian*'' partition. + + *--dbpath and --root* can be used together. Given the previous two + examples, the databases would be found on + ``*/New_Debian/otherstuff*'', assuming ``*/New_Debian/otherstuff*'' + actually existed. + + +------------------------------------------------------------------------------- + + +10. UPGRADING WITH APT +----------------------- + + usage: *swim --apt* + + options: *[-xyz] [--upgrade] [--dist_upgrade]* + + *apt-get* provides powerful methods to change an installion. When + these methods are called using *--apt*, *swim* will not allow you to + proceed until you are absolutely sure this is what you want to do. + Before using these methods do a ``*swim --apt --update*'' so that + *apt-get* knows the newest versions of available packages. This major + mode requires a combination of *-x*, *-xz* or *-xyz* to be used along + with either *--upgrade* or *--dist_upgrade*. *-x* used alone will + simulate what would happen if *-xz or -xyz* were used (also see `-xyz' + above). + + *--upgrade* is somewhat similiar to doing ``*swim -qatxz*'' except + that it is a more intelligent method because *apt* does some behind + the scene calculations in regards to package relationships, in fact + the ``*swim -qatxz*'' approach will provide totally different results, + or maybe these were the results you really wanted. ``*swim --apt + --upgrade -xz*'' is the prefered, proper, and built-in way provided by + *apt-get* to install the newest versions for all packages installed on + your system. This method will not install any newer versions of + packages which would change the install status of other packages. + Note: It is not recommended to combine the query option *-a* with *-xz + or -xyz*, but combining the query option *-a* just with *-x* can be + educational. + + *--dist_upgrade* combines an *--upgrade* with the installation of + packages which are not installed. This method carefully examines + dependencies, and resolves conflicts, and given these factors it will + upgrade the most important packages before considering the + installation of less important packages. Less important packages will + be installed only if there are not any conflicts. + + +------------------------------------------------------------------------------- + + +11. SEARCHING +-------------- + +usage: swim --search ? (--research || --refinesearch) + swim --powersearch ? (--research || --refinesearch) + swim --ps ? (--research || --refinesearch) + +options: [-g] [-n] [--dbpath ] [--root ] [--no] + [--arch ] [--dists + [--ftp ? --source | --source_only <[--diff]>] + [-xyrz --remove ? <[--nz]>] [--stdin] [--apt2df] + [--no] [--df2apt] [--purge] [<\d{1,}>] + + [--dir] and no [-g]for --powersearch or --ps + + + +11.1. OVERVIEW +--------------- + + *swim* provides two major types of searches. A search with *--search* + *searches package information* (see section 9.5, `FORMAT '), and a + search with *--powersearch or --ps* *searches package information, and + all files and/or directories associated with each package*. + + The results of either of these searches can be *narrowed down* by + running a test search with *--research* (this step can be skipped) + and/or setting the results in stone with *--refinesearch*. *--search* + can be *narrowed down* initially by specifying a particular *group*, + and *--powersearch* can be *expanded* initially by specifying that + *directories* be searched as well as files. Both searches can *use the + same virtual options* which the major mode *-q or --query* use. + Generally, it is preferable to run a search, and then to provide the + results of a search (*using -S*) as an argument to *-q or --query*; + this allows the results of a search to be queried. Every time a search + is run the results are appended to the history, past searches can be + refined or researched by providing the numerical argument pertaining + to the history. \d{1,} is simply Perl notation meaning a number with + one of more digits. + + *Perl regexps* (see `perlre(1p))' can be used to define the pattern + (string) provided as an argument to a search. Do not surround a + pattern in slashes, a slash is only used after all patterns and before + the *modifiers i and/or m* (swim supports these two modifiers). To + search for more than one pattern, patterns are separated with *bars + (|)*. Patterns may include *quatifiers, and metacharacters*, also + found in `egrep(1).' + + If a search finds any packages which match the search, the package + information will be displayed as the package is found. The package + will only be shown once regardless of how many times it is found while + the search progresses. When the search is over the number of packages + found is shown. + + *--search* provides a search of package information. This is similiar + to grepping ``*swim -qait*'' or ``*swim -qaint*'', but it is + significantly faster. A search can be performed on a particular group + by using *-g* with a group as an argument + + *--powersearch* is somewhat similiar to ``*dpkg --search*'' which + searches all files and directories on an installed system, but it + combines *--search* with the file and/or directory search, and can + also be performed on a not-installed system. A *powersearch* is + significantly faster than the search which *dpkg* provides (even more + so when ```swim --ramdiskon --searchfile''' is used) and even more + importantly provides a logical output of the search (like ```swim -qi + packagename'''). By default a search of all directories is not + performed because usually this is redundant except in rare cases. To + enable a search of all directories use the *--dir* option. + + +11.2. NARROWING A PREVIOUS SEARCH +---------------------------------- + + *--research* allows the results of a previous search to be researched + without making the new results permanent. + + *--refinesearch* allows the results of a previous search to be + researched while making the new results permanent. + + *\d{1,}* is a numerical argument to refine or research a past search + from the history. + + +11.3. MINOR MODES +------------------ + + *-n* allows the not-installed databases to be searched. These + databases will not exist if the not-installed databases were made with + the FDB argument (see `--initndb'). + + *-g* (see -g above and section 9.1, `MINOR MODES '). + + +11.4. OTHER OPTIONS +-------------------- + + *--no* prevents normal output from a search, but does show how many + packages were found. + + See the section ``section 9.2, `SPECIFYING THE DATABASES TO USE ''' + for options *--arch*, *-dists*. + + See the section ``section 9.6, `FTP - VIRTUAL OPTIONS ''' for *--ftp*, + *--source*, *--source_only*, *--diff*, + + See the section ``section 9.7, `APT - VIRTUAL OPTIONS ''' for *-xyz*, + *--nz*, *--stdin*, + + See the section ``section 9.8, `REMOVING AN INSTALLED PACKAGE - + VIRTUAL OPTIONS ''' for *--purge*, *--remove*, *-r*. + + See the section ``section 9.11, `DATABASE LOCATIONS ''' for options + *--dbpath* and *--root*. + + +11.5. EXAMPLES +--------------- + + *swim -gn hamradio --search "radio network/i" --dbpath /test --arch + alpha* + + will search the alpha architecture not-installed system databases in + the /test directory for all package information from the hamradio + group using the case insensitive pattern ``radio network''. + + *swim --powersearch dpkg -xn* + + will search the not-installed system databases for all package + information and all files using the case sensitive pattern dpkg, after + which apt-get will run a simulation of what would happen if it got and + installed these packages. + + +------------------------------------------------------------------------------- + + +12. RAMDISK +------------ + + usage: swim --ramdiskon + swim --ramdiskoff + + options: [-n] [--searchfile] [--arch ] + [--dists ] [--dbpath] [--root] + + no options for --ramdiskoff + + + +12.1. OVERVIEW +--------------- + + A ramdisk can be mounted below the default path or the specified path + for the databases in the dramdisk directory. The ramdisk is used to + speed up powersearchs and/or file/dir listings for packages from the + not-installed system. Also, this is useful if a computer system is + heavily loaded with other processes using the memory, and the ramdisk + tends to persist even after being unmounted. Modern kernels usually + are built with support for ramdisks. If these options do not work the + kernel will need to be compiled to support ramdisks by answering yes + to RAM disk support. Perhaps the best *README* showing how to + configure and compile a kernel comes with the *kernel sources* in the + main directory. + + *--ramdiskon* allows a ramdisk to be created and mounted. If called + with *-n* (not-installed databases) *ncontents-arch-dists.deb.gz* will + automatically be written to the mounted ramdisk. This provides faster + file/dir listing capabilities when using *-l*, *--df*, or *-d* when + querying the not-installed system. Faster powersearch capabilities are + available through the option *--searchfile*. If the search databases + are not already compressed, they will now be compressed, this usually + only needs to be done once or until the databases are updated or + rebuilt again. The search databases will then be written to the + mounted ramdisk. An installed system only writes the search databases + to the mounted ramdisk, so always use --searchfile when specifying + installed system databases. + + *--ramdiskoff* is used to unmount the ramdisk. The not-installed + databases and the installed databases can not be simultaneously + provided by a mounted ramdisk, use *--ramdiskoff* first, then + *--ramdiskon* to install the other databases of choice. This also + pertains to different distributions and/or architectures. + + See the section ``section 9.2, `SPECIFYING THE DATABASES TO USE ''' + for options *--arch*, *-dists*. + + See the section ``section 9.11, `DATABASE LOCATIONS ''' for options + *--dbpath* and *--root*. + + +------------------------------------------------------------------------------- + + +13. FILES +---------- + + Configuration files: + + swimz.list + swimrc + + +------------------------------------------------------------------------------- + + +14. SEE ALSO +------------- + + `swimrc(5),' apt-get(8), sources.list(5), `dpkg(8)' + + +------------------------------------------------------------------------------- + + +15. BUGS +-------- + + Send directly to mttrader@access.mountain.net. + + +------------------------------------------------------------------------------- + + + swim + Jonathan D. Rosenbaum 15 June 1999 + diff --git a/swim_by_example.html b/swim_by_example.html new file mode 100644 index 0000000..01f2330 --- /dev/null +++ b/swim_by_example.html @@ -0,0 +1,755 @@ + +swim by example + +

+ +
+

The Swift, Wise, and Intuitive package Manager.

+
+

+We run a search for case-insensitive matches for the word "quake." +Because we don't know how many matches the search will find, the +descriptions of all packages found are supressed with "--no." Note: "-n" +pertains to the not-installed (uninstalled) distribution. + +

+linuxalive:/home/swim/SWIMANIA$ swim -n --search quake/i --no
+swim: found 17 package(s)
+
+ +

swim keeps a history for all searches. + +

+linuxalive:/home/swim/SWIMANIA$ swim -hn
+    5  dpsclient-demos dgs dgs-dev freefont gs-aladdin gs-aladdin-manual
+gs-aladdin-manual-de gsfonts-other xpacman abc2ps efax ghostview gnome-gv
+gs gsfonts gsfonts-x11 gv hatman libroxen-tex pacman ppd-gs pstotext
+python-imaging svgalib1-altdev svgalibg1-dev tex4ht type1inst yorick
+    4  lsof-2.2
+    3  libwine-dev
+    2  libwine libwine-dev libwings-dev
+    1  gtkpak pak qstat quake-lib quake2 quake2-bin quake2-ctf quake2-dm
+xqf quake-3dfx quake-ggi quake-gl quake-lib-stub quake-sdl quake-server
+quake-svga quake-x11
+
+ +

+We can access any part of the history which we want. The first command looks at the +information pertaining to the package. The second command shows a listing of the packages +found for "quake." Note: When no numbers are specified for "-S", the number 1 is assumed. + +

+linuxalive:/home/swim/SWIMANIA$ swim -qnSi 3
+Package: libwine-dev                 Status: install ok installed
+Version: 0.0.20000109-1              Essential: no
+Section: otherosfs                   Priority: optional
+Installed-Size: 3680                 Source: wine
+Size: 729818                         Architecture: i386
+Distribution: unstable
+Maintainer: Andrew D. Lenharth <andrewl@debian.org>
+Description: Windows Emulator (Development files)
+ This is an ALPHA release of Wine, the MS-Windows emulator.  This is
+ still a developers release and many applications may still not work.
+ .
+ This package consists of the C header files.
+ .
+ Wine is often updated.
+
+linuxalive:/home/swim/SWIMANIA$ swim -qnS  
+gtkpak_0.2-1
+pak_0.2-1
+qstat_2.3e-1
+quake-lib_1.06-9
+quake2_3.20-5
+quake2-bin_3.20-1
+quake2-ctf_1.50-1
+quake2-dm_3.13-1
+xqf_0.8.99-1
+quake-3dfx_0.0.9-1
+quake-ggi_0.0.9-1
+quake-gl_0.0.9-1
+quake-lib-stub_1.9-1
+quake-sdl_0.0.9-1
+quake-server_0.0.9-1
+quake-svga_0.0.9-1
+quake-x11_0.0.9-1
+
+ +

+After looking at the descriptions for the packages found through the "quake" search we decide +to narrow down the search to "tools." Notes: We could have done this for any part of the +history by specifying a number. "--research" will not write the changes to the history, +"--refinesearch" will write the changes to the history. The qstat package is installed, but +there is a newer version. + +

+linuxalive:/home/swim/SWIMANIA$ swim -n --research tool
+Package: gtkpak                      Status: not-installed
+Version: 0.2-1                       Essential: no
+Section: games                       Priority: optional
+Installed-Size: 105                  Source: pak
+Size: 32182                          Architecture: i386
+Distribution: unstable
+Maintainer: Joseph Carter <knghtbrd@debian.org>
+Description: GTK program for manipulating pak archives
+ gtkpak is a nifty GTK tool for manipulating the pak archives used by Quake,
+ Quake 2, and QuakeWorld.  It can view, extract, create, and append pak
+ archives.  pak contains basic command-line utilities that can do much of
+ what gtkpak does without X or GTK, but gtkpak is easier to work with by
+ far.  Installing both won't hurt anything.
+
+Package: pak                         Status: not-installed
+Version: 0.2-1                       Essential: no
+Section: games                       Priority: optional
+Installed-Size: 110
+Size: 37412                          Architecture: i386
+Distribution: unstable
+Maintainer: Joseph Carter <knghtbrd@debian.org>
+Description: command-line tools for pak archives
+ This package contains pakx and pakc, a couple of tools for working with the
+ pak archives used by Quake, Quake 2, and QuakeWorld.  pakc can create and
+ add files to archives, pakx can list and extract files from them.  gtkpak
+ is a bit fancier but then again it requires X and GTK.
+
+Package: qstat                       Status: > hold ok installed (2.0b-1)
+Version: 2.3e-1                      Essential: no
+Section: games                       Priority: optional
+Installed-Size: 236
+Size: 68652                          Architecture: i386
+Distribution: unstable
+Maintainer: Michael Alan Dorman <mdorman@debian.org>
+Description: Command-line tool for querying quake (and other) servers
+ Qstat provides a simple interface for querying servers for a number
+ of games, including but not limited to quake, quakeworld, quake2,
+ quake3arena, unreal tournament, kingpin and others.
+
+swim: found 3 package(s)
+linuxalive:/home/swim/SWIMANIA$ swim -n --refinesearch tool --no
+swim: found 3 package(s)
+
+ +

This is what 1 now looks like in the history: +

+    1  gtkpak pak qstat
+
+ +

If apt is installed it is possible to find out how other packages will +be installed. + +

+linuxalive:/home/swim/SWIMANIA$ swim -qxnS
+gtkpak_0.2-1
+pak_0.2-1
+qstat_2.3e-1
+Reading Package Lists...
+Building Dependency Tree...
+The following packages will be REMOVED:
+  xqf 
+The following NEW packages will be installed:
+  gtkpak pak 
+The following held packages will be changed:
+  qstat xqf 
+1 packages upgraded, 2 newly installed, 1 to remove and 1065 not upgraded.
+Inst gtkpak
+Remv xqf
+Inst qstat
+Inst pak
+Conf gtkpak
+Conf qstat
+Conf pak
+
+ +

+Oh no, xqf is going to be removed! Let's make sure that this isn't a +package we want removed, but since we noticed a newer version of this +package is included in the unstable distribution, let's find out what's +going on here! + +

+linuxalive:/home/swim/SWIMANIA$ swim -qnxi xqf
+Package: xqf                         Status: > hold ok installed (0.5-1)
+Version: 0.8.99-1                    Essential: no
+Section: games                       Priority: optional
+Installed-Size: 182
+Size: 80426                          Architecture: i386
+Distribution: unstable
+Maintainer: Michael Alan Dorman <mdorman@debian.org>
+Description: X-based Quake Server Browser
+ XQF allows one to browse and choose quake servers to play on.
+Reading Package Lists...
+Building Dependency Tree...
+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:
+
+Sorry, but the following packages have unmet dependencies:
+  xqf: Conflicts: qstat (< 2.1z-2.1a-0.1) but 2.0b-1 is to be installed
+E: Sorry, broken packages
+linuxalive:/home/swim/SWIMANIA$ swim -qnT qstat
+qstat_2.3e-1
+Depends: libc6 (>= 2.1.2)
+Conflicts: xqf (<< 0.9.2-1)
+
+ +

As seen above, the reason why xqf has to be removed is due to a +dependency in qstat which the packager (Michael Alan Dorman +<mdorman@debian.org>) will have to resolve by uploading a newer version of +xqf to the distribution. Sometimes necessary packages are still in +Debian's Incoming directory at the ftp site, and not in the distribution, +so we may want to check there first. If this isn't the case we will send +a bug report to Debian's Bug Tracking System pointing out that there needs +to be a newer version of xqf. In the meantime we have decided that we +only want gtkpak and pak. We will use swim's editing capabilities to take +gstat off the list. Notes: Another possibility for the bug shown above +is that apt's cache needs to be updated to reflect the changes in Debain's +distribution by using "swim --apt --update." When the history is edited +with "--stdin" the history makes a new entry reflecting the change. The +full history is accessible from "--stdin." Anybody can send a bug to +Debian's Bug Tracking System. + +

+linuxalive:/home/swim/SWIMANIA$ swim -qxznS --stdin 
+swim: type exit to finish --stdin
+swim: gtkpak pak      
+swim: exit
+Reading Package Lists... Done
+Building Dependency Tree... Done
+The following NEW packages will be installed:
+  gtkpak pak 
+0 packages upgraded, 2 newly installed, 0 to remove and 1067 not upgraded.
+Need to get 69.6kB of archives. After unpacking 220kB will be used.
+Get:1 ftp://ftp.debian.org unstable/main gtkpak 0.2-1 [32.2kB]
+Get:2 ftp://ftp.debian.org unstable/main pak 0.2-1 [37.4kB]                    
+Fetched 69.6kB in 1m15s (922B/s)                                               
+Selecting previously deselected package gtkpak.
+(Reading database ... 106015 files and directories currently installed.)
+Unpacking gtkpak (from .../archives/gtkpak_0.2-1_i386.deb) ...
+Selecting previously deselected package pak.
+Unpacking pak (from .../archives/pak_0.2-1_i386.deb) ...
+Setting up gtkpak (0.2-1) ...
+
+Setting up pak (0.2-1) ...
+gtkpak_0.2-1
+pak_0.2-1
+
+ +

+If we don't have apt we can still download these packages, and their sources. Here is another +way to do the same thing we did above without using apt. Notes: This time we saved some +typing by doing "--stdin" with "--research." We specified "--source" with "--ftp" to get the +sources as well as the packages, or we could have just gotten the sources by themselves by +specifying "--source_only" with "--ftp." Changes made while in "--stdin" are written to the +history. + +

+linuxalive:/home/swim/SWIMANIA$ swim -n --search quake/i --no
+swim: found 17 package(s)
+linuxalive:/home/swim/SWIMANIA$ swim -n --research tool --no --stdin --ftp --source
+swim: found 3 package(s)
+swim: type exit to finish --stdin
+swim: gtkpak pak      
+swim: exit
+swim: connected to ftp.debian.org
+swim: logged in to ftp.debian.org
+swim: downloading gtkpak_0.2-1.deb (32182 bytes)
+gtkpak_0.2-1  49823b28c9599dbf94e290e28e695bc2  OK
+swim: successful retrieval of gtkpak_0.2-1.deb
+swim: downloading pak_0.2-1.diff.gz (2623 bytes)
+swim: successful retrieval of pak_0.2-1.diff.gz
+swim: downloading pak_0.2-1.dsc (825 bytes)
+swim: successful retrieval of pak_0.2-1.dsc
+swim: downloading pak_0.2.orig.tar.gz (26972 bytes)
+swim: successful retrieval of pak_0.2.orig.tar.gz
+swim: downloading pak_0.2-1.deb (37412 bytes)
+pak_0.2-1  55842f97f80c5c37415a93a7f0709171  OK
+swim: successful retrieval of pak_0.2-1.deb
+swim: pak_0.2-1.diff.gz already exists
+swim: pak_0.2-1.dsc already exists
+swim: pak_0.2.orig.tar.gz already exists
+swim: logged out
+
+ +

+We notice that the sources only had to be downloaded once. Looking at the packages' +information we notice both packages share the same sources as indicated in the "Source" field. +The field is absent for the pak package because the source name is exactly the same as the +package's name, but for the gtkpak package this isn't the case, so the "Source" field is +present. + +

+We can find the packages and the sources in their proper location on our local archive mirror. + +

+linuxalive:/home/swim/SWIMANIA$ ls ~/.swim/pub/debian/dists/unstable/main/source/games
+pak_0.2-1.diff.gz  pak_0.2-1.dsc  pak_0.2.orig.tar.gz
+linuxalive:/home/swim/SWIMANIA$ ls ~/.swim/pub/debian/dists/unstable/main/binary-i386/games/
+gtkpak_0.2-1.deb  pak_0.2-1.deb
+
+ +

+We can go examine the packages. It is useful to check out the changelog and the copyright. +This is the initial release for this program. Note: "-v" will show the files in long format +(ls -l), "--df" show the directories as well as the files. + +

+linuxalive:/home/swim/SWIMANIA$ cd ~/.swim/pub/debian/dists/unstable/main/binary-i386/games/
+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ swim -qpl --copyright --changelog gtkpak_0.2-1.deb 
+#####copyright for gtkpak_0.2-1.deb#####
+
+taken from the README:
+
+(c) Michael Vance, 1999
+    briareos@lokigames.com
+    mkv102@psu.edu
+
+0. Intro
+
+gtkpak is a PAK file viewer for Gtk+. What are PAK files? A PAK file is used
+in id software games such as Quake and Quake 2, and their spin-offs. Just
+imagine collapsing an entire directory scheme into a big wad of files, and
+there you have a PAK file.
+
+The three binaries are built around the interface provided in pakfile.h,
+which is a C++ class that allows access to the contents of a PAKFile, including
+searching and extracting from an already existing PAK file, to add files and
+then writing a new PAK file. The three binaries are then just front-ends
+to this functionality, in one way or another.
+
+While it's tempting to make the classes provided in pakfile.h into a shared
+library, it's probably unnecessary. But it does make one tingly, eh?
+
+And all this is GPL'ed, of course. See the file COPYING for license details.
+
+
+#####changelog.Debian.gz for gtkpak_0.2-1.deb#####
+
+pak (0.2-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Joseph Carter   Thu,  8 Jul 1999 17:35:38 -0700
+
+Local variables:
+mode: debian-changelog
+End:
+
+usr/bin/gtkpak
+usr/share/man/man6/gtkpak.6.gz
+usr/doc/gtkpak/README
+usr/doc/gtkpak/copyright
+usr/doc/gtkpak/examples/pak0.pak
+usr/doc/gtkpak/changelog.Debian.gz
+usr/lib/menu/gtkpak
+
+ +

Let's see if there is a menu entry, and check the MD5 checksum. + +

+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ swim -qpm gtkpak_0.2-1.deb --md5sum
+#####menu for gtkpak_0.2-1.deb(gtkpak)#####
+?package(gtkpak):needs=X11 section=Games/Adventure\
+  title="GtkPak" hints=Quake command="/usr/bin/gtkpak"
+
+gtkpak_0.2-1  49823b28c9599dbf94e290e28e695bc2  OK
+
+ +

It would be interesting to look at the man page for gtkpak. + +

+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ swim -qpd gtkpak_0.2-1.deb 
+gtkpak_0.2-1
+
+usr/share/man/man6/gtkpak.6.gz
+usr/doc/gtkpak/README
+usr/doc/gtkpak/copyright
+usr/doc/gtkpak/examples/pak0.pak
+usr/doc/gtkpak/changelog.Debian.gz
+
+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ swim -qp gtkpak_0.2-1.deb --extract PWD\!usr/share/man/man6/gtkpak.6.gz
+gtkpak_0.2-1
+
+
+swim: gtkpak.6.gz has been extracted
+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ ls
+gtkpak.6.gz  gtkpak_0.2-1.deb  pak_0.2-1.deb
+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games$ zcat gtkpak.6.gz | nroff -man | less
+"man page for gtkpak will be visible"
+
+ +

+We could also extract the whole archive onto our system. Note: First, we checked to make +sure we wouldn't copy over any files from other installed packages. + +

+linuxalive:~/.swim/pub/debian/dists/unstable/main/binary-i386/games/test$ cd /
+linuxalive:/$ swim -qp ~/.swim/pub/debian/dists/unstable/main/binary-i386/games/gtkpak_0.2-1.deb --extract ALL
+gtkpak_0.2-1
+
+
+swim: gtkpak_0.2-1.deb has been extracted
+
+ +

+If we have installed the packages with apt, we can check to see what kind of changes have been +made to our system. + +

+linuxalive:/home/swim/SWIMANIA$ swim --db --check
+checking for new, changed, and removed packages
+NEW gtkpak
+NEW pak
+
+       TOTAL
+       -----
+NEW 2
+GONE 0
+CHANGED 0
+CHANGED STATUS 0
+
+ +

At this point the database for our installation hasn't been updated. + +

+linuxalive:/home/swim/SWIMANIA$ swim -q pak 
+package pak is not installed
+linuxalive:/home/swim/SWIMANIA$ 
+
+To update the database we will issue "--db" without "--check."
+
+linuxalive:/home/swim/SWIMANIA$ swim --db        
+checking for new, changed, and removed packages
+NEW gtkpak
+NEW pak
+
+       TOTAL
+       -----
+NEW 2
+GONE 0
+CHANGED 0
+CHANGED STATUS 0
+
+
+N|C|CS 2
+#2 N|C pak.list
+linuxalive:/home/swim/SWIMANIA$ swim -q pak
+pak_0.2-1
+
+ +

+We can check to see if the uninstalled distribution had any changes. Notes: The results below +indicate the changes found in the new Package databases that have been downloaded by updating +apt; if we don't have apt then swim's major mode "--ftp" can be used with "DF." With "--ndb" +use APT to indicate apt sources, or DF to indicate Package databases gotten directly through +swim's "--ftp". If we originally made the uninstalled distribution with an uninstalled +filesystem by using "--Contents DF" then to update the uninstalled distribution "--Contents +DF" should be used again; this isn't necessary when running a check. To rebuild +(--rebuildndb), update (--ndb), or check a distribution other than the default one, use +"--dists stable", "--dists frozen" or "--dists unstable." The newest Packages can +automatically be picked by using "--cron." + +

+A little blurb: Although not Debian approved or sanctioned, we find the unstable distribution +acceptably stable in relation to certain well-known commercial distributions despite +infrequent packaging bugs like the one shown in the xqf example above. The Debian +distribution adheres to a self-imposed level of quality found in no other distribution in the +world. Usually, unstable undergoes many changes so there isn't a time advantage over updating +DF versus rebuilding DF, but this process is easier on system resources. On the other hand, +updating FDBDF (no uninstalled filesystem) is faster. + + +

+linuxalive:/home/swim/SWIMANIA$ swim --apt --update; swim --ftp --Contents DF --onec;
+"output not shown"
+linuxalive:/home/swim/SWIMANIA$ swim --ndb --check APT 2> changes-today
+###         Site                     Date              Size (bytes)  Release
+
+                                     CONTRIB
+  1     ftp.debian.org       Mon Jan 17 17:57:57 2000    112774        2.2
+
+                                     NON-FREE
+  1     ftp.debian.org       Sun Jan 16 17:26:23 2000    279821        2.2
+
+                                       MAIN
+  1     ftp.debian.org       Mon Jan 17 17:57:12 2000    3048732       2.2
+
+swim: for CONTRIB, which ### do you want?: 1
+swim: for NON-FREE, which ### do you want?: 1
+swim: for MAIN, which ### do you want?: 1
+checking for new, changed, and removed packages
+
+       TOTAL
+       -----
+NEW 12
+GONE 16
+CHANGED 54
+CHANGED REVISION 162
+
+ +

+We can view all the changes because we stored them in a file. We can use swim to look at all +the changed packages except for the new ones which will be visible once we rebuild or update. +By looking at this file we are provided a view of the inner workings of Debian development. + +

+linuxalive:/home/swim/SWIMANIA$ cat changed-today | less
+CHANGED-REVISION gnujsp
+CHANGED iraf
+CHANGED iraf-common
+CHANGED iraf-ibin
+CHANGED iraf-noaobin
+CHANGED-REVISION jserv
+CHANGED-REVISION mailcrypt
+CHANGED plugger
+CHANGED-REVISION sarien
+NEW webrt
+"part of output not shown"
+GONE tinytable-zope
+GONE tip
+
+ +

We decide to update with "--ndb" rather than to rebuild with +"--rebuildndb." + +

+linuxalive:/home/swim/SWIMANIA$ swim --ndb APT --Contents DF --cron 2> changed-today
+checking for new, changed, and removed packages
+
+       TOTAL
+       -----
+NEW 12
+GONE 16
+CHANGED 54
+CHANGED REVISION 162
+G|C|CR 232
+#232 VIRTUAL G|C|CR zicq.list                                        
+Copying new Contents
+Compressing Contents
+N|C|CR 228
+#228 VIRTUAL N|C|CR zicq.list                                         
+#22 NO-C zope-siteaccess.list                        
+Appending search databases
+Updating status
+
+Sun Jan 23 14:59:04 2000  to  Sun Jan 23 16:39:23 2000
+
+ +

+We were wondering whether it was time to update gv, but we found out that there was only a +debian-revision change "r>" which means that the source code hasn't changed. There is no need +to update right now. + +

+linuxalive:/usr/lib/perl5/SWIM$ which gv
+/usr/X11R6/bin/gv
+linuxalive:/usr/lib/perl5/SWIM$ cd /usr/X11R6/bin
+linuxalive:/usr/X11R6/bin$ swim -qf gv
+gv_1:3.5.8-7
+linuxalive:/usr/X11R6/bin$ swim -qfni gv
+Package: gv                          Status: r> hold ok installed (1:3.5.8-7)
+Version: 1:3.5.8-15                  Essential: no
+Section: text                        Priority: optional
+Installed-Size: 477
+Size: 224778                         Architecture: i386
+Distribution: unstable
+Maintainer: Marco Pistore <pistore@debian.org>
+Description: A PostScript and PDF viewer for X using 3d Athena Widgets
+ `gv' is a comfortable viewer of PostScript and PDF files for the X
+ Window System.
+ .
+ It uses the `ghostscript' PostScript(tm) interpreter and is based
+ on the classic X front-end for `gs', `ghostview'. It is more
+ comfortable and more powerful than `ghostview'.
+ .
+ Some features as e.g. PDF files or anti-aliasing are only supported
+ if a recent ghostscript (4.0 or later) is installed.  With
+ anti-aliasing turned on, the text is very crisp and readable, with no
+ `stepping' on the slants at all.
+
+ +

+While we were in this directory we decided to do a little research. It is interesting to note +that for the installed system there are 14 files which don't belong to any packages. There +could be a variety of reasons for this (maybe we are slobs); this is good stuff to know. +Notes: To see the total list just add "-t" to the existing command-line options. There is a +big difference in using "." and "*", "." is the same as saying "./" but it only lists the +same package once, whereas "*" would look at all the files in the immediate directory and if +two files belong to the same package, that package will be shown twice for each file, it also +reports if a file doesn't belong to a package. + +

+linuxalive:/usr/X11R6/bin$ swim -qf .
+use --total or -t to see all 202 packages
+linuxalive:/usr/X11R6/bin$ swim -qfn .
+use --total or -t to see all 420 packages
+linuxalive:/usr/X11R6/bin$ swim -qft * | grep "not owned" | wc -l
+     14
+linuxalive:/usr/X11R6/bin$ swim -qfnt * | grep "not owned" | wc -l
+    162
+
+ +

+We notice a file in the lib directory, and we wonder what it belongs to. + +

+linuxalive:/lib$ swim -qf libthread_db-1.0.so --shlibs
+libc6_2.1.2-11
+Shlibs:
+ld-linux 2 libc6 (>= 2.1.2)
+libBrokenLocale 1 libc6 (>= 2.1.2)
+.. everything not shown ..
+libthread_db 1 libc6 (>= 2.1.2)
+libutil 1 libc6 (>= 2.1.2)
+
+ +

+We want to find out what dependencies apt has. + +

+linuxalive:/lib$ swim -qfnT /usr/bin/apt-get
+apt_0.3.16
+Depends: libc6, libc6 (>= 2.1), libc6 (>= 2.1.2), libstdc++2.10
+Suggests: dpkg-dev
+Provides: libapt-pkg2.6
+Replaces: deity, libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)
+Conflicts: deity
+
+ +

+We need a header file called w32skrnl.h. We are in luck it's already on our system. Notes: +We could have done "locate w32skrnl.h" and then done a "swim -qf", but we haven't updated our +locatedb in months. The package installation will be tested by apt if it exists. + +

+linuxalive:/usr/include/wine$ swim -xn --ps w32skrnl\.h
+Package: libwine-dev                 Status: install ok installed
+Version: 0.0.20000109-1              Essential: no
+Section: otherosfs                   Priority: optional
+Installed-Size: 3680                 Source: wine
+Size: 729818                         Architecture: i386
+Distribution: unstable
+Maintainer: Andrew D. Lenharth <andrewl@debian.org>
+Description: Windows Emulator (Development files)
+ This is an ALPHA release of Wine, the MS-Windows emulator.  This is
+ still a developers release and many applications may still not work.
+ .
+ This package consists of the C header files.
+ .
+ Wine is often updated.
+
+swim: found 1 package(s)
+Reading Package Lists...
+Building Dependency Tree...
+Sorry, libwine-dev is already the newest version
+0 packages upgraded, 0 newly installed, 0 to remove and 1067 not upgraded.
+
+ +

+Sometimes it is nice to know the total of what we have installed. + +

+linuxalive:/usr/X11R6/bin$ swim -qa
+use --total or -t to see all 1449 packages
+linuxalive:/usr/X11R6/bin$ swim -qf /
+use --total or -t to see all 1449 packages
+linuxalive:/home/swim/SWIMANIA$ swim -qan   
+use --total or -t to see all 4525 packages
+
+ +

+We can check the MD5 checksum for all the configuation files on the system. Notes: MD5 +checksum can be performed on "-l", "-d", "-c", or "-p." This can only be performed on the +installed system. + +

+linuxalive:/home/swim/SWIMANIA$ swim -qact --md5sum
+a2ps_4.10.2-4
+ /etc/a2ps.cfg  eb909349a1bb2d1f4b4adc7ab1f75e56  OK
+
+acct_6.3.2-4
+ /etc/cron.daily/acct  d5e16c7f601c3a43d88fc8ede714c6e2  OK
+ /etc/cron.monthly/acct  9ca2c358e430f94c9ae00a1ce54e6e96  OK
+ /etc/init.d/acct  2f978d8517077c77e3262d7a6096fe2f  OK
+
+autolog_0.34-5
+ /etc/autolog.conf  b6ae10782ce13c45cbe72f9308b4caa1  OK
+ /etc/cron.d/autolog  805d268ea44c645299defc1c14495282  MISSING
+
+cfengine_1.4.9-2
+ /etc/cfengine/cfengine.conf  fd79d9462e92f88aa6c563f39e3e10d5  OK
+ /etc/cron.daily/cfengine  ac6a42f3be907b50e52834ae9d41fdbd  FAILED
+ /etc/cron.weekly/cfengine  fbdd90ecf2e68a4ced6a6abbffd32f62  OK
+"rest of output not shown"
+
+ +

We check to see what groups exist. + +

+linuxalive:/usr/lib/perl5/SWIM$ swim -q --allgroups
+"output not shown"
+linuxalive:/usr/lib/perl5/SWIM$ swim -qn --allgroups
+admin                     base                      comm
+contrib/admin             contrib/devel             contrib/doc
+contrib/games             contrib/graphics          contrib/interpreters
+contrib/libs              contrib/mail              contrib/math
+contrib/misc              contrib/net               contrib/news
+"rest of output not shown"
+
+ +

+We happen to be hamradio enthusiasts. Let's see what packages exist in the hamradio group. + +

+linuxalive:/usr/lib/perl5/SWIM$ swim -qng hamradio
+acfax_981011-3
+ax25-apps_0.0.4-1
+ax25-tools_0.0.5-1
+colrconv_0.99.2-4
+dgipip_0.1-2
+gc_1.07-3
+hamsoft_0.1.1-1
+"rest of the output not shown"
+
+ +

+We edit the hamradio group package list with "--stdin." Notes: "--stdin" needs to be +called with either "--ftp", "-x", "-xyz", "-xz", "--purge", "-r", or "--remove" to work. This +is a readline interface. If we are in emacs mode (see man bash) here are some commands we can +use to make the process easier. + +

+Note: The key bindings may be different on your system. +
Ctrl-a = move to the beginning of the line +
Ctrl-e = move to the end of the line +
Ctrl-w = erase (kill) one word backward +
Esc-d = kill one word forward +
Esc-b = move one word backward +
Esc-f = move one word forward +
Ctrl-k = kill forward to the end of the line +
Ctrl-y = retrieve (yank) last item killed +
Ctrl-r = search backward +
Esc-< = move to the beginning of the history +
Esc-> = move to the end of the history + +

+linuxalive:/usr/lib/perl5/SWIM$ swim -qng hamradio --stdin --ftp  
+swim: type exit to finish --stdin
+swim: acfax ax25-apps ax25-tools colrconv dgipip gc hamsoft icom jiffy jiffy-per
+l-tk libax25 libax25-dev logconv morse nec node p10cfgd pileup predict rspfd sccw twclock twcw
+twlog unixcw wwl wxd xconvers xnecview z8530-utils z8530-utils2
+
+ +

+We are finding new ways to swim everyday; we often solve problems in minutes which used +to take an hour or more to solve. If you find a novel use for swim, please tell us, and we +will add it to these examples. + + + + diff --git a/swimrc b/swimrc new file mode 100644 index 0000000..252de94 --- /dev/null +++ b/swimrc @@ -0,0 +1,29 @@ +# Read QUICKSTART in /usr/doc/swim for important information and to +# quickly prepare the swimrc, then read the swimrc(5) manpage for more +# enlightenment and configuration options like "Do you want to use apt?", +# "How about non-us?". + +# Which do you have on your system? Pick dpkg if Debian, ar if non-Debian. +#$package_tool = "/usr/bin/dpkg"; +#$package_tool = "/usr/bin/ar"; + +# Do you have apt installed? +#$apt = "yes"; + +# Pick one. +#$architecture = "alpha"; +#$architecture = "arm"; +#$architecture = "hurd-i386"; +#$architecture = "i386"; +#$architecture = "m68k"; +#$architecture = "powerpc"; +#$architecture = "sparc"; + +# Which distribution? Pick one. +#$distribution = "stable"; +#$distribution = "unstable"; +#$distribution = "frozen"; + +# Remove sections after qw that you do not want. Use non-US for non-us. +#@user_defined_section = qw(main contrib non-free); + diff --git a/swimrc.5 b/swimrc.5 new file mode 100644 index 0000000..5c25e87 --- /dev/null +++ b/swimrc.5 @@ -0,0 +1,402 @@ +.rn '' }` +''' $RCSfile$$Revision$$Date$ +''' +''' $Log$ +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.ie n \{\ +.ds -- \(*W- +.ds PI pi +.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH swimrc 5 " " "27/May/99" " " +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.bd B 3 +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds ? ? +. ds ! ! +. ds / +. ds q +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +swimrc \- swim configuration file +.SH "DESCRIPTION" +\fBswimrc\fR is the configuartion file for swim allowing many default values +to be set so that they do not have to be mentioned on the command line. +Swimrc interacts directly with Perl allowing a wide variety of variables +found in \fBSWIW::Conf\fR to be altered. +.SH "USAGE" +Values for variable can be altered for \fBswim\fR by assigning different +values enclosed in quotes or quoted whitespace (\fIqw()\fR), and ended with a +semi-colon. +.PP +.Vb 2 +\& $variable = "value"; +\& $variable = "qw(value1 value2 ..)"; +.Ve +.SH "VARIABLES" +This is a list of variables with explanations. The default values for +\fBswim\fR are shown. +.Sh "\s-1OUTPUT\s0 \s-1VARIABLE\s0 " +$my_number can be changed to how many lines you would like \*(L"swim \-qf <>\*(R" +to print out, before the program asks for \f(CW-t\fR or \f(CW--total\fR. Exception: +If \f(CW-i\fR is used in the query and there is more than one package then the +total will be presented. +.PP +Hint: \f(CW-t\fR can be used with all the various \f(CW--scripts\fR family members +to view the title of the script file regardless of this variable setting, +and if \f(CW-t\fR has to be used, the titles will be displayed, which makes +sense. +.PP +\fB$my_number = 23;\fR +.Sh "\s-1HISTORY\s0" +This is a shell-like history kept in relation to searches and the most +recent edit when \f(CW--stdin\fR is used. +.PP +\fB$\s-1HISTORY\s0 = 10;\fR +.Sh "\s-1AR\s0 or \s-1DPKG\s0?" +Debian packages are ar archives. If you are using a Debian Distribution +assign \*(L"dpkg\*(R" to \f(CW$package_tool\fR, otherwise assign \*(L"ar\*(R" to \f(CW$package_tool\fR. +.PP +\fB$package_tool = \*(L"/usr/bin/ar\*(R";\fR +.Sh "\s-1APT\s0" +\fBSwim\fR does not assign a value for apt. To use \f(CW--apt\fR and \f(CW-xyz\fR +assign \f(CW$apt\fR the value \*(L"yes\*(R". +.PP +Example: \fB$apt = \*(L"yes\*(R";\fR +.Sh "\s-1PAGER\s0" +less is a nice pager, unless you like more! Pager is used for \f(CW--help\fR +and \fBswim\fR called without any options. There is an option \f(CW--nopager\fR or +\f(CW-n\fR. more comes from the required package util-linux, whereas less +comes from a standard package called less. Values: \*(L"less\*(R", \*(L"more\*(R", or +\*(L"most\*(R" or... +.PP +\fB$\s-1ENV\s0{\s-1PAGER\s0} = \*(L"less\*(R";\fR +.Sh "\s-1NOT\s0\-\s-1INSTALLED\s0 \s-1VARIABLES\s0 " +Assign values for \f(CW$architecture\fR and/or \f(CW$distribution\fR to avoid having to +use \f(CW--arch\fR and \f(CW--dists\fR everytime the not-installed databases are +accessed with \f(CW-n\fR or made or altered. +.PP +Architectures are always being added so check with Debian to find a list. +There is \fIalpha, arm, hurd-i386 (alternative kernel to linux), i386, +m68k, powerpc, sparc\fR. Just use the arch found after the hyphen in the +Contents-(arch) file. +.PP +\fB$architecture = \*(L"i386\*(R";\fR +.PP +The distribution can be either \fIstable, unstable, frozen, or experimental +(rare)\fR. These represent the state of development that the packages are +under. The unstable distribution can have lot's of changes within a very +short time period, and frozen may or may not be available. +.PP +\fB$distribution = \*(L"unstable\*(R";\fR +.PP +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at one time separate distributions, but this has since changed. +.PP +You can determine which of the sections \fImain, non-free, contrib or +non-\s-1US\s0\fR to pull out of the Contents file if you don't want to use +\f(CW--main\fR, \f(CW--contrib\fR, \f(CW--non-free\fR, and \f(CW--non-us\fR to selectively +pick the sections. +.PP +For efficiency, you should choose the sections which you will be pulling +out of the Packages \fIfile\fR\|(s) being targetted. +.PP +Rule: Use \*(L"non-\s-1US\s0\*(R" not \*(L"non-us\*(R". +.PP +\fB@user_defined_section = qw(main contrib non-free non-\s-1US\s0);\fR +.Sh "\s-1DF\s0 \s-1LOCATION\s0" +A little philosophy: \fBswim\fR was developed for maximum versatility, so +whether you are just interested in researching, and keeping tabs on the +newest packages, or maintaining a Debian virtual distribution on a +non-Debian distribution, or you are a using \fBswim\fR for distribution +development, \fBswim\fR provides a way. +.PP +The next two variables determine the location of the \s-1DF\s0 (default +directory/file system) +.PP +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release +file are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim will still do the renaming and keeping track of the mtime, but you +will have to remember where you put the files. +.PP +\fB$default_directory = \*(L'/root/.swim\*(R';\fR +.PP +The default root directory (\s-1DRD\s0) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be a real ftp site on your computer, or put wherever else you are +allowed to have directories. The \s-1DRD\s0 is always placed below the value +assigned to \f(CW$default_directory\fR. According to the previous assignment to +\f(CW$default_directory\fR, if the \s-1DRD\s0 is \*(L"/pub/a/debian\*(R" then the full path +would be \*(L"/root/.swim/pub/a/debian\*(R". +.PP +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the \s-1DRD\s0. +.PP +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-\s-1US\s0 or +personal (specialized distribution). +.PP +\fB$default_root_directory = \*(L'/pub/debian\*(R';\fR +.PP +Because you may be using a real ftp site, this variable allows you to +determine what permissions \fBswim\fR will assign for directories it creates +below the \s-1DRD\s0. +.PP +\fB$permission = \*(L'0755\*(R';\fR +.Sh "\s-1TEMPORARY\s0 \s-1DIRECTORY\s0" +If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +\f(CW$tmp\fR a \s-1RAM\s0 disk. See package loadlin for initrd documentation and an +explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. +.PP +\fB$tmp = \*(L"/tmp\*(R";\fR +.Sh "\s-1FTP\s0" +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in \fINet::\s-1FTP\s0\fR\|(3pm) by providing +arguments to these variables. All variables but \f(CW$timeout\fR are set to untrue +by default. +.PP +.Vb 5 +\& $firewall = 0; (FTP firewall machine name) +\& $port = 0; (defaults to 23) +\& $timeout = 120; (120 seconds) +\& $debug = 0; (1 will turn on STDERR) +\& $passive = 0; (1 will enable) +.Ve +.SH "OTHER VARIABLES" +see SWIM::Conf +.SH "FILES" +.PP +.Vb 2 +\& /etc/swim/swimrc +\& ~/.swim/swimrc +.Ve +.SH "SEE ALSO" +\fIswim\fR\|(8), \fINet::FTP\fR\|(3pm) +.SH "BUGS" +Send directly to mttrader@access.mountain.net. +.SH "AUTHOR" +Jonathan D. Rosenbaum +.SH "COPYRIGHT" +Copyright (c) 1999 Jonathan Rosenbaum. All rights reserved. This program +is free software; you can redistribute it and/or modify it under the GPL. + +.rn }` '' +.IX Title "swimrc 5" +.IX Name "swimrc - swim configuration file" + +.IX Header "NAME" + +.IX Header "DESCRIPTION" + +.IX Header "USAGE" + +.IX Header "VARIABLES" + +.IX Subsection "\s-1OUTPUT\s0 \s-1VARIABLE\s0 " + +.IX Subsection "\s-1HISTORY\s0" + +.IX Subsection "\s-1AR\s0 or \s-1DPKG\s0?" + +.IX Subsection "\s-1APT\s0" + +.IX Subsection "\s-1PAGER\s0" + +.IX Subsection "\s-1NOT\s0\-\s-1INSTALLED\s0 \s-1VARIABLES\s0 " + +.IX Subsection "\s-1DF\s0 \s-1LOCATION\s0" + +.IX Subsection "\s-1TEMPORARY\s0 \s-1DIRECTORY\s0" + +.IX Subsection "\s-1FTP\s0" + +.IX Header "OTHER VARIABLES" + +.IX Header "FILES" + +.IX Header "SEE ALSO" + +.IX Header "BUGS" + +.IX Header "AUTHOR" + +.IX Header "COPYRIGHT" + diff --git a/swimrc.html/ch-description.html b/swimrc.html/ch-description.html new file mode 100644 index 0000000..56557f3 --- /dev/null +++ b/swimrc.html/ch-description.html @@ -0,0 +1,26 @@ + +swimrc - swim configuration file - DESCRIPTION + + + +

+swimrc - swim configuration file - chapter 1
+DESCRIPTION + +

+ +swimrc is the configuartion file for swim allowing many +default values to be set so that they do not have to be mentioned on the +command line. Swimrc interacts directly with Perl allowing a wide variety +of variables found in SWIW::Conf to be altered. +
+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch-files.html b/swimrc.html/ch-files.html new file mode 100644 index 0000000..f33a68a --- /dev/null +++ b/swimrc.html/ch-files.html @@ -0,0 +1,26 @@ + +swimrc - swim configuration file - FILES + + + +

+swimrc - swim configuration file - chapter 5
+FILES + +

+ + /etc/swim/swimrc

+ +~/.swim/swimrc + +


+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch-othervars.html b/swimrc.html/ch-othervars.html new file mode 100644 index 0000000..3ac3f37 --- /dev/null +++ b/swimrc.html/ch-othervars.html @@ -0,0 +1,23 @@ + +swimrc - swim configuration file - OTHER VARIABLES + + + +

+swimrc - swim configuration file - chapter 4
+OTHER VARIABLES + +

+ +see SWIM::Conf +
+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch-restrictions.html b/swimrc.html/ch-restrictions.html new file mode 100644 index 0000000..73948fb --- /dev/null +++ b/swimrc.html/ch-restrictions.html @@ -0,0 +1,35 @@ + +swimrc - swim configuration file - RESTRICTIONS + + + +

+swimrc - swim configuration file - chapter 6
+RESTRICTIONS + +

+ +Strange Situations: If the same package happens to exist in two different +sections, main and non-us for example, and you make the +databases, you will still be able to find this package in the non-us +group, but its section and locations will be the one which main recognizes +assuming that you use the order in the example below. + +

+ + +Example: You just want to pull out main and contrib every time you run +--initndb, --rebuildndb, or --ndb. +

+@user_defined_section = ``qw(main contrib non-US)''; +


+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; back. +
+
14 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch-usage.html b/swimrc.html/ch-usage.html new file mode 100644 index 0000000..bdde5c5 --- /dev/null +++ b/swimrc.html/ch-usage.html @@ -0,0 +1,29 @@ + +swimrc - swim configuration file - USAGE + + + +

+swimrc - swim configuration file - chapter 2
+USAGE + +

+Values for variable can be altered for swim by assigning +different values enclosed in quotes or quoted whitespace (qw()), and ending +with a semi-colon.

+ + $variable = ``value'';

+$variable = ``(value1 value2 ..)''; +

+

+


+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch-variables.html b/swimrc.html/ch-variables.html new file mode 100644 index 0000000..86bbf3e --- /dev/null +++ b/swimrc.html/ch-variables.html @@ -0,0 +1,284 @@ + +swimrc - swim configuration file - VARIABLES + + + +

+swimrc - swim configuration file - chapter 3
+VARIABLES + +

+This is a list of variables with explanations. The default values for +swim are shown. + + +
+

+3.1 OUTPUT VARIABLE + +

+$my_number can be changed to how many lines you would like +``swim -qf <>'' to print out, before the program asks for +-t or --total. Exception: If -i is +used in the query and there is more than one package then the total will +be presented. + +

+ +Hint: -t can be used with all the various +--scripts family members to view the title of the script file +regardless of this variable setting, and if -t has to be +used, the titles will be displayed, which makes sense. + +

+ +$my_number = 23; + +


+

+3.2 HISTORY + +

+ +This is a shell-like history kept in relation to searches and the most +recent edit when --stdin is used. +

+ +$HISTORY = 10; + +


+

+3.3 AR or DPKG? + +

+ +Debian packages are ar archives. If you are using a Debian Distribution +assign ``dpkg'' to $package_tool, otherwise assign ``ar'' to +$package_tool. +

+ +$package_tool = "/usr/bin/ar"; +


+

+3.4 APT + +

+ +Swim does not assign a value for apt. To use +--apt and -xyz assign $apt the +value ``yes''. + +

+ + +Example: $apt = "yes"; +


+

+3.5 PAGER + +

+ + +less is a nice pager, unless you like +more! Pager is used for --help and +swim called without any options. There is an option +--nopager or -n. more comes from the +required package util-linux, whereas less comes from a +standard package called less. Values: ``less'', ``more'', or ``most'' +or... + +

+ + +$ENV{PAGER} = "less"; +


+

+3.6 NOT-INSTALLED VARIABLES + +

+ +Assign values for $architecture and/or +$distribution to avoid having to use --arch and +--dists everytime the not-installed databases are accessed +with -n or made or altered. + +

+ + +Architectures are always being added so check with Debian to find a list. +There is alpha, arm, hurd-i386 (alternative kernel to linux), i386, +m68k, powerpc, sparc. Just use the arch found after the hyphen in the +Contents-(arch) file. + +

+ + +$architecture = "i386"; +

+ + +The distribution can be either stable, unstable, frozen, or +experimental (rare). These represent the state of development that +the packages are under. The unstable distribution can have lot's of +changes within a very short time period, and frozen may or may not be +available. + +

+ + +$distribution = "unstable"; +

+ + +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at +one time separate distributions, but this has since changed. + +

+ + +You can determine which of the sections main, non-free, contrib or +non-US to pull out of the Contents file if you don't want to use +--main, --contrib, --non-free, and +--non-us to selectively pick the sections. + +

+ + +For efficiency, you should choose the sections which you will be pulling +out of the Packages file(s) being targetted. + +

+ + +Rule: Use ``non-US'' not ``non-us''. + +

+ + +@user_defined_section = qw(main contrib non-free non-US); + +


+

+3.7 DF LOCATION + +

+ +A little philosophy: swim was developed for maximum +versatility, so whether you are just interested in researching, and +keeping tabs on the newest packages, or maintaining a Debian virtual +distribution on a non-Debian distribution, or you are a using +swim for distribution development, swim +provides a way. + +

+ + +The next two variables determine the location of the DF (default +directory/file system) + +

+ + +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release file +are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim + +will still do the renaming and keeping track of the mtime, but you will +have to remember where you put the files. + +

+ + +$default_directory = '/root/.swim'; + + + +

+ + +The default root directory (DRD) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be +a real ftp site on your computer, or put wherever else you are allowed to +have directories. The DRD is always placed below the value assigned to +$default_directory. According to the previous assignment to +$default_directory, if the DRD is ``/pub/a/debian'' then the full path +would be ``/root/.swim/pub/a/debian''. +

+ + +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the DRD. + +

+ + +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-US or +personal (specialized distribution). + +

+ + +$default_root_directory = '/pub/debian'; +

+ + +Because you may be using a real ftp site, this variable allows you to +determine what permissions swim will assign for +directories it +creates below the DRD. + +

+ + +$permission = '0755'; + +


+

+3.8 TEMPORARY DIRECTORY + +

+If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +$tmp a RAM disk. See package loadlin for initrd documentation and +an explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. +

+ + +$tmp = "/tmp"; +


+

+3.9 FTP + +

+ +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in Net::FTP(3pm) by providing +arguments to these variables. All variables but $timeout are set to untrue +by default. + +
 $firewall = 0; (FTP firewall machine name)
+ $port = 0;  (defaults to 23)   
+ $timeout = 120;  (120 seconds)
+ $debug = 0;  (1 will turn on STDERR)
+ $passive = 0; (1 will enable)
+
+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; next; back. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/ch6.html b/swimrc.html/ch6.html new file mode 100644 index 0000000..7ddeaad --- /dev/null +++ b/swimrc.html/ch6.html @@ -0,0 +1,20 @@ + +swimrc - swim configuration file - BUGS + + +

+swimrc - swim configuration file - chapter 6
+BUGS +

+Send directly to mttrader@access.mountain.net. +
+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents; back. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.html/index.html b/swimrc.html/index.html new file mode 100644 index 0000000..d91369b --- /dev/null +++ b/swimrc.html/index.html @@ -0,0 +1,76 @@ + +swimrc - swim configuration file + + +

swimrc - swim configuration file

+ +

+0.1 Table of contents +

+ +

0.2 Copyright

+ + Copyright © 1999 Jonathan D. Rosenbaum +

+ + SWIM, including this manual, is free software; you + may 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 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 with the swim source as the file + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +


+swimrc - swim configuration file +- + Copyright © 1999 Jonathan D. Rosenbaum + +
+Contents. +
+
27 May 1999
+Jonathan D. Rosenbaummttrader@access.mountain.net
+ diff --git a/swimrc.sgml b/swimrc.sgml new file mode 100644 index 0000000..65946ec --- /dev/null +++ b/swimrc.sgml @@ -0,0 +1,354 @@ + + + + + + + + + swimrc - swim configuration file + + + Jonathan D. Rosenbaum + mttrader@access.mountain.net + + + + + + + + Copyright © 1999 Jonathan D. Rosenbaum + + +

+ SWIM, including this manual, is free software; you + may 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 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 with the swim source as the file + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +

+ +
+ +
+ + + + DESCRIPTION + +

+ +swimrc is the configuartion file for swim allowing many +default values to be set so that they do not have to be mentioned on the +command line. Swimrc interacts directly with Perl allowing a wide variety +of variables found in SWIW::Conf to be altered. + +USAGE + +

+Values for variable can be altered for swim by assigning +different values enclosed in quotes or quoted whitespace (qw()), and ending +with a semi-colon. +

+ + $variable = ``value''; +

+$variable = ``(value1 value2 ..)''; + +

+ +

+VARIABLES + +

+This is a list of variables with explanations. The default values for +swim are shown. + + + +OUTPUT VARIABLE + +

+$my_number can be changed to how many lines you would like +``swim -qf <>'' to print out, before the program asks for +-t or --total. Exception: If -i is +used in the query and there is more than one package then the total will +be presented. + + +

+ +Hint: -t can be used with all the various +--scripts family members to view the title of the script file +regardless of this variable setting, and if -t has to be +used, the titles will be displayed, which makes sense. + + +

+ +$my_number = 23; + + +HISTORY + +

+ +This is a shell-like history kept in relation to searches and the most +recent edit when --stdin is used. + +

+ +$HISTORY = 10; + + +AR or DPKG? + +

+Debian packages are ar archives. If you are using a Debian Distribution +assign ``dpkg'' to $package_tool, otherwise assign ``ar'' to +$package_tool. + +

+$package_tool = "/usr/bin/ar"; + +APT + +

+Swim does not assign a value for apt. To use +--apt and -xyz assign $apt the +value ``yes''. + + +

+ +Example: $apt = "yes"; + +PAGER + +

+ +less is a nice pager, unless you like +more! Pager is used for --help and +swim called without any options. There is an option +--nopager or -n. more comes from the +required package util-linux, whereas less comes from a +standard package called less. Values: ``less'', ``more'', or ``most'' +or... + + +

+ +$ENV{PAGER} = "less"; + +NOT-INSTALLED VARIABLES + +

+Assign values for $architecture and/or +$distribution to avoid having to use --arch and +--dists everytime the not-installed databases are accessed +with -n or made or altered. + + +

+ +Architectures are always being added so check with Debian to find a list. +There is alpha, arm, hurd-i386 (alternative kernel to linux), i386, +m68k, powerpc, sparc. Just use the arch found after the hyphen in the +Contents-(arch) file. + + +

+ +$architecture = "i386"; + +

+ +The distribution can be either stable, unstable, frozen, or +experimental (rare). These represent the state of development that +the packages are under. The unstable distribution can have lot's of +changes within a very short time period, and frozen may or may not be +available. + + +

+ +$distribution = "unstable"; + +

+ +Distributions are divided into sections. These sections were called +distributions in the version 2.4.1.0 packaging manual, because they were +at +one time separate distributions, but this has since changed. + + +

+ +You can determine which of the sections main, non-free, contrib or +non-US to pull out of the Contents file if you don't want to use +--main, --contrib, --non-free, and +--non-us to selectively pick the sections. + + +

+ +For efficiency, you should choose the sections which you will be pulling +out of the Packages file(s) being targetted. + + +

+ + +Rule: Use ``non-US'' not ``non-us''. + + +

+ +@user_defined_section = qw(main contrib non-free non-US); + + +DF LOCATION + +

+A little philosophy: swim was developed for maximum +versatility, so whether you are just interested in researching, and +keeping tabs on the newest packages, or maintaining a Debian virtual +distribution on a non-Debian distribution, or you are a using +swim for distribution development, swim +provides a way. + + +

+ +The next two variables determine the location of the DF (default +directory/file system) + + +

+ +The default directory keeps track of Contents and/or Packages databases +retrieved with --ftp. The Contents and Packages databases and Release file +are give names specific to the distribution and architectures they +represent using the naming convention found in apt's sources directory. +You also have the freedom not to use the default directory, in which case +swim + +will still do the renaming and keeping track of the mtime, but you will +have to remember where you put the files. + + +

+ +$default_directory = '/root/.swim'; + + + + +

+ +The default root directory (DRD) is the key to easy management of binary +packages, source, dsc, and diff files received from --ftp, and provides an +easy way to put together a personalized distribution. This directory can +be +a real ftp site on your computer, or put wherever else you are allowed to +have directories. The DRD is always placed below the value assigned to +$default_directory. According to the previous assignment to +$default_directory, if the DRD is ``/pub/a/debian'' then the full path +would be ``/root/.swim/pub/a/debian''. + +

+ +Example: When a package is downloaded it will be placed in +dists/distribution/section/architecture/subject below the DRD. + + +

+ +Rule: debian must be the final directory before dists, this is because +other distributions are placed alongside debian, like debian-non-US or +personal (specialized distribution). + + +

+ +$default_root_directory = '/pub/debian'; + +

+ +Because you may be using a real ftp site, this variable allows you to +determine what permissions swim will assign for +directories it +creates below the DRD. + + +

+ +$permission = '0755'; + + +TEMPORARY DIRECTORY + +

+If you want to set an alternative directory for the temporary files +created when the databases are made, change here. You may want to make +$tmp a RAM disk. See package loadlin for initrd documentation and +an explanation for making such a disk. There is also documentation in +/usr/src/kernel-source.version/Documentation. Whether this will speed +things up is a subject of experimentation. + +

+ +$tmp = "/tmp"; + +FTP + +

+ +You can alter the Firewall, Port, Timeout, Debug and Passive +characteristics of the ftp client as defined in Net::FTP(3pm) by providing +arguments to these variables. All variables but $timeout are set to untrue +by default. + + + $firewall = 0; (FTP firewall machine name) + $port = 0; (defaults to 23) + $timeout = 120; (120 seconds) + $debug = 0; (1 will turn on STDERR) + $passive = 0; (1 will enable) + + +OTHER VARIABLES + +

+see SWIM::Conf + +FILES + +

+ /etc/swim/swimrc +

+~/.swim/swimrc + + +BUGS +

Send directly to mttrader@access.mountain.net. + + + + diff --git a/swimrc.text b/swimrc.text new file mode 100644 index 0000000..850c670 --- /dev/null +++ b/swimrc.text @@ -0,0 +1,294 @@ + + swimrc - swim configuration file + -------------------------------- + Jonathan D. Rosenbaum + 27 May 1999 + +0.1 Contents +------------ + + 1. DESCRIPTION + + 2. USAGE + + 3. VARIABLES + 3.1. OUTPUT VARIABLE + 3.2. HISTORY + 3.3. AR or DPKG? + 3.4. APT + 3.5. PAGER + 3.6. NOT-INSTALLED VARIABLES + 3.7. DF LOCATION + 3.8. TEMPORARY DIRECTORY + 3.9. FTP + + 4. OTHER VARIABLES + + 5. FILES + + 6. BUGS + +0.2 Copyright Notice +-------------------- + + Copyright © 1999 Jonathan D. Rosenbaum + + SWIM, including this manual, is free software; you may 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 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 with + the swim source as the file `COPYING'. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +------------------------------------------------------------------------------- + + +1. DESCRIPTION +--------------- + + swimrc is the configuartion file for swim allowing many default values + to be set so that they do not have to be mentioned on the command + line. Swimrc interacts directly with Perl allowing a wide variety of + variables found in SWIW::Conf to be altered. + + +------------------------------------------------------------------------------- + + +2. USAGE +--------- + + Values for variable can be altered for *swim* by assigning different + values enclosed in quotes or quoted whitespace (qw()), and ending with + a semi-colon. + + ` $variable = ``value'';' + + `$variable = ``(value1 value2 ..)'';' + + + +------------------------------------------------------------------------------- + + +3. VARIABLES +------------- + + This is a list of variables with explanations. The default values for + *swim* are shown. + + +3.1. OUTPUT VARIABLE +--------------------- + + `$my_number' can be changed to how many lines you would like ``swim + -qf <>'' to print out, before the program asks for `-t' or `--total'. + Exception: If `-i' is used in the query and there is more than one + package then the total will be presented. + + Hint: `-t' can be used with all the various `--scripts' family members + to view the title of the script file regardless of this variable + setting, and if `-t' has to be used, the titles will be displayed, + which makes sense. + + *$my_number = 23;* + + +3.2. HISTORY +------------- + + This is a shell-like history kept in relation to searches and the most + recent edit when `--stdin' is used. + + *$HISTORY = 10;* + + +3.3. AR or DPKG? +----------------- + + Debian packages are ar archives. If you are using a Debian + Distribution assign ``dpkg'' to $package_tool, otherwise assign ``ar'' + to $package_tool. + + *$package_tool = "/usr/bin/ar";* + + +3.4. APT +--------- + + *Swim* does not assign a value for apt. To use `--apt' and `-xyz' + assign `$apt' the value ``yes''. + + Example: *$apt = "yes";* + + +3.5. PAGER +----------- + + *less* is a nice pager, unless you like *more*! Pager is used for + `--help' and *swim* called without any options. There is an option + `--nopager' or `-n'. *more* comes from the required package + util-linux, whereas *less* comes from a standard package called less. + Values: ``less'', ``more'', or ``most'' or... + + *$ENV{PAGER} = "less";* + + +3.6. NOT-INSTALLED VARIABLES +----------------------------- + + Assign values for `$architecture' and/or `$distribution' to avoid + having to use `--arch' and `--dists' everytime the not-installed + databases are accessed with `-n' or made or altered. + + Architectures are always being added so check with Debian to find a + list. There is *alpha, arm, hurd-i386 (alternative kernel to linux), + i386, m68k, powerpc, sparc*. Just use the arch found after the hyphen + in the Contents-(arch) file. + + *$architecture = "i386";* + + The distribution can be either *stable, unstable, frozen, or + experimental (rare)*. These represent the state of development that + the packages are under. The unstable distribution can have lot's of + changes within a very short time period, and frozen may or may not be + available. + + *$distribution = "unstable";* + + Distributions are divided into sections. These sections were called + distributions in the version 2.4.1.0 packaging manual, because they + were at one time separate distributions, but this has since changed. + + You can determine which of the sections *main, non-free, contrib or + non-US* to pull out of the Contents file if you don't want to use + `--main', `--contrib', `--non-free', and `--non-us' to selectively + pick the sections. + + For efficiency, you should choose the sections which you will be + pulling out of the Packages `file(s)' being targetted. + + Rule: Use ``non-US'' not ``non-us''. + + *@user_defined_section = qw(main contrib non-free non-US);* + + +3.7. DF LOCATION +----------------- + + A little philosophy: *swim* was developed for maximum versatility, so + whether you are just interested in researching, and keeping tabs on + the newest packages, or maintaining a Debian virtual distribution on a + non-Debian distribution, or you are a using *swim* for distribution + development, *swim* provides a way. + + The next two variables determine the location of the DF (default + directory/file system) + + The default directory keeps track of Contents and/or Packages + databases retrieved with --ftp. The Contents and Packages databases + and Release file are give names specific to the distribution and + architectures they represent using the naming convention found in + apt's sources directory. You also have the freedom not to use the + default directory, in which case swim will still do the renaming and + keeping track of the mtime, but you will have to remember where you + put the files. + + *$default_directory = '/root/.swim';* + + The default root directory (DRD) is the key to easy management of + binary packages, source, dsc, and diff files received from --ftp, and + provides an easy way to put together a personalized distribution. This + directory can be a real ftp site on your computer, or put wherever + else you are allowed to have directories. The DRD is always placed + below the value assigned to $default_directory. According to the + previous assignment to $default_directory, if the DRD is + ``/pub/a/debian'' then the full path would be + ``/root/.swim/pub/a/debian''. + + Example: When a package is downloaded it will be placed in + dists/distribution/section/architecture/subject below the DRD. + + Rule: debian must be the final directory before dists, this is because + other distributions are placed alongside debian, like debian-non-US or + personal (specialized distribution). + + *$default_root_directory = '/pub/debian';* + + Because you may be using a real ftp site, this variable allows you to + determine what permissions *swim* will assign for directories it + creates below the DRD. + + *$permission = '0755';* + + +3.8. TEMPORARY DIRECTORY +------------------------- + + If you want to set an alternative directory for the temporary files + created when the databases are made, change here. You may want to make + `$tmp' a RAM disk. See package loadlin for initrd documentation and an + explanation for making such a disk. There is also documentation in + /usr/src/kernel-source.version/Documentation. Whether this will speed + things up is a subject of experimentation. + + *$tmp = "/tmp";* + + +3.9. FTP +--------- + + You can alter the Firewall, Port, Timeout, Debug and Passive + characteristics of the ftp client as defined in Net::FTP(3pm) by + providing arguments to these variables. All variables but $timeout are + set to untrue by default. + $firewall = 0; (FTP firewall machine name) + $port = 0; (defaults to 23) + $timeout = 120; (120 seconds) + $debug = 0; (1 will turn on STDERR) + $passive = 0; (1 will enable) + + +------------------------------------------------------------------------------- + + +4. OTHER VARIABLES +------------------- + + see SWIM::Conf + + +------------------------------------------------------------------------------- + + +5. FILES +--------- + + ` /etc/swim/swimrc' + + `~/.swim/swimrc' + + +------------------------------------------------------------------------------- + + +6. BUGS +------- + + Send directly to mttrader@access.mountain.net. + + +------------------------------------------------------------------------------- + + + swimrc - swim configuration file + Jonathan D. Rosenbaum 27 May 1999 + diff --git a/swimz.list b/swimz.list new file mode 100644 index 0000000..ad86b0e --- /dev/null +++ b/swimz.list @@ -0,0 +1,11 @@ +# Read QUICKSTART for a quick start, and check out the SWIMZ.LIST +# section in swim(8) for much more information. This list is read +# sequentially, so earlier entries are read before later entries +# +# Debian users: Unlike apt which only downloads Packages, swim reads this +# list based on the specified or default distribution/architecture to +# make handling the downloading of both the Contents and Packages files +# easier. Look at the Cron example in /usr/doc/swim/examples. +# +# deb ftp://ftp.debian.org/pub/debian unstable contrib non-free main +# deb ftp://ftp.debian.org/pub/debian stable contrib non-free main