From 26c15dd62ff6ed506531576eecfb9b9801510b5c Mon Sep 17 00:00:00 2001 From: freesource Date: Sat, 27 Jan 2001 00:03:46 +0000 Subject: [PATCH] *** empty log message *** --- .gitignore | 28 + BUGS | 8 + COPYING | 340 +++++ Conf.pm | 672 +++++++++ Conf.pm.alternative | 672 +++++++++ INSTALL | 51 + Makefile | 76 + Makefile.alternative | 73 + Programming_swim | 114 ++ QUICKSTART.html | 206 +++ QUICKSTART.text | 140 ++ REQUIREMENTS.html | 139 ++ REQUIREMENTS.text | 90 ++ THEMES | 34 + TODO | 126 ++ bin/fastswim | 167 +++ bin/imswim | 99 ++ bin/longswim | 591 ++++++++ bin/slowswim | 131 ++ changelog | 78 + contact_and_website | 7 + examples/Cron | 20 + lib/Ag.pm | 263 ++++ lib/Apt.pm | 1219 +++++++++++++++ lib/Compare.pm | 358 +++++ lib/Conf.pm | 672 +++++++++ lib/DB.pm | 947 ++++++++++++ lib/DB_Init.pm | 648 ++++++++ lib/DB_Library.pm | 497 +++++++ lib/Deb.pm | 1752 ++++++++++++++++++++++ lib/Deps.pm | 456 ++++++ lib/Dir.pm | 110 ++ lib/F.pm | 92 ++ lib/File.pm | 877 +++++++++++ lib/Findex.pm | 358 +++++ lib/Format.pm | 62 + lib/Global.pm | 62 + lib/Groups.pm | 73 + lib/Indexer.pm | 509 +++++++ lib/Info.pm | 586 ++++++++ lib/Library.pm | 144 ++ lib/MD.pm | 268 ++++ lib/NDB.pm | 1834 +++++++++++++++++++++++ lib/NDB_File.pm | 251 ++++ lib/NDB_Init.pm | 2366 ++++++++++++++++++++++++++++++ lib/Pn_print.pm | 97 ++ lib/Qftp.pm | 951 ++++++++++++ lib/Ramdisk.pm | 180 +++ lib/Safex.pm | 470 ++++++ lib/Search.pm | 850 +++++++++++ swim | 1991 +++++++++++++++++++++++++ swim.8 | 1558 ++++++++++++++++++++ swim.html/ch-aptprep.html | 49 + swim.html/ch-commandline.html | 158 ++ swim.html/ch-description.html | 32 + swim.html/ch-history.html | 37 + swim.html/ch-important.html | 330 +++++ swim.html/ch-makinginst.html | 180 +++ swim.html/ch-notinstalled.html | 230 +++ swim.html/ch-query.html | 672 +++++++++ swim.html/ch-ramdisk.html | 82 ++ swim.html/ch-search.html | 191 +++ swim.html/ch-seealso.html | 23 + swim.html/ch-version.html | 26 + swim.html/ch10.html | 64 + swim.html/ch12.html | 29 + swim.html/ch13.html | 29 + swim.html/ch15.html | 20 + swim.html/ch9.html | 64 + swim.html/index.html | 162 ++ swim.pod | 1365 +++++++++++++++++ swim.sgml | 2036 +++++++++++++++++++++++++ swim.text | 1622 ++++++++++++++++++++ swim_by_example.html | 755 ++++++++++ swimrc | 29 + swimrc.5 | 402 +++++ swimrc.html/ch-description.html | 26 + swimrc.html/ch-files.html | 26 + swimrc.html/ch-othervars.html | 23 + swimrc.html/ch-restrictions.html | 35 + swimrc.html/ch-usage.html | 29 + swimrc.html/ch-variables.html | 284 ++++ swimrc.html/ch6.html | 20 + swimrc.html/index.html | 76 + swimrc.sgml | 354 +++++ swimrc.text | 294 ++++ swimz.list | 11 + 87 files changed, 34128 insertions(+) create mode 100644 .gitignore create mode 100644 BUGS create mode 100644 COPYING create mode 100644 Conf.pm create mode 100644 Conf.pm.alternative create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 Makefile.alternative create mode 100644 Programming_swim create mode 100644 QUICKSTART.html create mode 100644 QUICKSTART.text create mode 100644 REQUIREMENTS.html create mode 100644 REQUIREMENTS.text create mode 100644 THEMES create mode 100644 TODO create mode 100755 bin/fastswim create mode 100755 bin/imswim create mode 100755 bin/longswim create mode 100755 bin/slowswim create mode 100644 changelog create mode 100644 contact_and_website create mode 100755 examples/Cron create mode 100644 lib/Ag.pm create mode 100644 lib/Apt.pm create mode 100644 lib/Compare.pm create mode 100644 lib/Conf.pm create mode 100644 lib/DB.pm create mode 100644 lib/DB_Init.pm create mode 100644 lib/DB_Library.pm create mode 100644 lib/Deb.pm create mode 100644 lib/Deps.pm create mode 100644 lib/Dir.pm create mode 100644 lib/F.pm create mode 100644 lib/File.pm create mode 100644 lib/Findex.pm create mode 100644 lib/Format.pm create mode 100644 lib/Global.pm create mode 100644 lib/Groups.pm create mode 100644 lib/Indexer.pm create mode 100644 lib/Info.pm create mode 100644 lib/Library.pm create mode 100644 lib/MD.pm create mode 100644 lib/NDB.pm create mode 100644 lib/NDB_File.pm create mode 100644 lib/NDB_Init.pm create mode 100644 lib/Pn_print.pm create mode 100644 lib/Qftp.pm create mode 100644 lib/Ramdisk.pm create mode 100644 lib/Safex.pm create mode 100644 lib/Search.pm create mode 100755 swim create mode 100644 swim.8 create mode 100644 swim.html/ch-aptprep.html create mode 100644 swim.html/ch-commandline.html create mode 100644 swim.html/ch-description.html create mode 100644 swim.html/ch-history.html create mode 100644 swim.html/ch-important.html create mode 100644 swim.html/ch-makinginst.html create mode 100644 swim.html/ch-notinstalled.html create mode 100644 swim.html/ch-query.html create mode 100644 swim.html/ch-ramdisk.html create mode 100644 swim.html/ch-search.html create mode 100644 swim.html/ch-seealso.html create mode 100644 swim.html/ch-version.html create mode 100644 swim.html/ch10.html create mode 100644 swim.html/ch12.html create mode 100644 swim.html/ch13.html create mode 100644 swim.html/ch15.html create mode 100644 swim.html/ch9.html create mode 100644 swim.html/index.html create mode 100644 swim.pod create mode 100644 swim.sgml create mode 100644 swim.text create mode 100644 swim_by_example.html create mode 100644 swimrc create mode 100644 swimrc.5 create mode 100644 swimrc.html/ch-description.html create mode 100644 swimrc.html/ch-files.html create mode 100644 swimrc.html/ch-othervars.html create mode 100644 swimrc.html/ch-restrictions.html create mode 100644 swimrc.html/ch-usage.html create mode 100644 swimrc.html/ch-variables.html create mode 100644 swimrc.html/ch6.html create mode 100644 swimrc.html/index.html create mode 100644 swimrc.sgml create mode 100644 swimrc.text create mode 100644 swimz.list 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