From 9c526f54968557dc7bcdd16e2619fd9f972818c3 Mon Sep 17 00:00:00 2001 From: karltk Date: Sun, 11 Aug 2002 00:29:04 +0000 Subject: [PATCH 1/1] Initial revision svn path=/; revision=2 --- trunk/AUTHORS | 3 + trunk/COPYING | 340 ++++++++++ trunk/ChangeLog | 3 + trunk/NEWS | 0 trunk/README | 33 + trunk/TODO | 1 + trunk/src/change/AUTHORS | 5 + trunk/src/change/ChangeLog | 3 + trunk/src/change/README | 20 + trunk/src/change/change | 344 ++++++++++ trunk/src/change/change.1 | 0 trunk/src/dep-clean/AUTHORS | 0 trunk/src/dep-clean/ChangeLog | 0 trunk/src/dep-clean/README | 0 trunk/src/dep-clean/dep-clean | 266 ++++++++ trunk/src/dep-clean/dep-clean.1 | 187 ++++++ trunk/src/emerge-rsync/AUTHORS | 0 trunk/src/emerge-rsync/ChangeLog | 0 trunk/src/emerge-rsync/README | 0 trunk/src/emerge-rsync/emerge-rsync | 52 ++ trunk/src/emerge-webrsync/AUTHORS | 0 trunk/src/emerge-webrsync/ChangeLog | 0 trunk/src/emerge-webrsync/README | 0 trunk/src/emerge-webrsync/emerge-webrsync | 62 ++ trunk/src/epm/AUTHORS | 0 trunk/src/epm/ChangeLog | 0 trunk/src/epm/README | 0 trunk/src/epm/epm | 421 ++++++++++++ trunk/src/etc-update/AUTHORS | 0 trunk/src/etc-update/ChangeLog | 0 trunk/src/etc-update/README | 0 trunk/src/pkg-clean/AUTHORS | 0 trunk/src/pkg-clean/ChangeLog | 0 trunk/src/pkg-clean/README | 0 trunk/src/pkg-clean/pkg-clean | 100 +++ trunk/src/pkg-size/AUTHORS | 0 trunk/src/pkg-size/ChangeLog | 0 trunk/src/pkg-size/README | 0 trunk/src/pkg-size/pkg-size | 52 ++ trunk/src/portage-statistics/AUTHORS | 0 trunk/src/portage-statistics/ChangeLog | 2 + trunk/src/portage-statistics/README | 0 trunk/src/portage-statistics/histogram.awk | 14 + .../portage-statistics/pst-author-coverage | 12 + .../src/portage-statistics/pst-package-count | 9 + .../src/portage-statistics/pst-total-coverage | 7 + trunk/src/qpkg/AUTHORS | 0 trunk/src/qpkg/ChangeLog | 0 trunk/src/qpkg/README | 0 trunk/src/qpkg/qpkg | 473 ++++++++++++++ trunk/src/qpkg/qpkg.1 | 110 ++++ trunk/src/useflag/AUTHORS | 0 trunk/src/useflag/ChangeLog | 0 trunk/src/useflag/README | 0 trunk/src/useflag/useflag | 610 ++++++++++++++++++ trunk/src/useflag/useflag.1 | 69 ++ 56 files changed, 3198 insertions(+) create mode 100644 trunk/AUTHORS create mode 100644 trunk/COPYING create mode 100644 trunk/ChangeLog create mode 100644 trunk/NEWS create mode 100644 trunk/README create mode 100644 trunk/TODO create mode 100644 trunk/src/change/AUTHORS create mode 100644 trunk/src/change/ChangeLog create mode 100644 trunk/src/change/README create mode 100644 trunk/src/change/change create mode 100644 trunk/src/change/change.1 create mode 100644 trunk/src/dep-clean/AUTHORS create mode 100644 trunk/src/dep-clean/ChangeLog create mode 100644 trunk/src/dep-clean/README create mode 100644 trunk/src/dep-clean/dep-clean create mode 100644 trunk/src/dep-clean/dep-clean.1 create mode 100644 trunk/src/emerge-rsync/AUTHORS create mode 100644 trunk/src/emerge-rsync/ChangeLog create mode 100644 trunk/src/emerge-rsync/README create mode 100755 trunk/src/emerge-rsync/emerge-rsync create mode 100644 trunk/src/emerge-webrsync/AUTHORS create mode 100644 trunk/src/emerge-webrsync/ChangeLog create mode 100644 trunk/src/emerge-webrsync/README create mode 100644 trunk/src/emerge-webrsync/emerge-webrsync create mode 100644 trunk/src/epm/AUTHORS create mode 100644 trunk/src/epm/ChangeLog create mode 100644 trunk/src/epm/README create mode 100644 trunk/src/epm/epm create mode 100644 trunk/src/etc-update/AUTHORS create mode 100644 trunk/src/etc-update/ChangeLog create mode 100644 trunk/src/etc-update/README create mode 100644 trunk/src/pkg-clean/AUTHORS create mode 100644 trunk/src/pkg-clean/ChangeLog create mode 100644 trunk/src/pkg-clean/README create mode 100644 trunk/src/pkg-clean/pkg-clean create mode 100644 trunk/src/pkg-size/AUTHORS create mode 100644 trunk/src/pkg-size/ChangeLog create mode 100644 trunk/src/pkg-size/README create mode 100644 trunk/src/pkg-size/pkg-size create mode 100644 trunk/src/portage-statistics/AUTHORS create mode 100644 trunk/src/portage-statistics/ChangeLog create mode 100644 trunk/src/portage-statistics/README create mode 100644 trunk/src/portage-statistics/histogram.awk create mode 100755 trunk/src/portage-statistics/pst-author-coverage create mode 100755 trunk/src/portage-statistics/pst-package-count create mode 100755 trunk/src/portage-statistics/pst-total-coverage create mode 100644 trunk/src/qpkg/AUTHORS create mode 100644 trunk/src/qpkg/ChangeLog create mode 100644 trunk/src/qpkg/README create mode 100644 trunk/src/qpkg/qpkg create mode 100644 trunk/src/qpkg/qpkg.1 create mode 100644 trunk/src/useflag/AUTHORS create mode 100644 trunk/src/useflag/ChangeLog create mode 100644 trunk/src/useflag/README create mode 100644 trunk/src/useflag/useflag create mode 100644 trunk/src/useflag/useflag.1 diff --git a/trunk/AUTHORS b/trunk/AUTHORS new file mode 100644 index 0000000..4196571 --- /dev/null +++ b/trunk/AUTHORS @@ -0,0 +1,3 @@ +Karl Trygve Kalleberg + - Maintenance + diff --git a/trunk/COPYING b/trunk/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/trunk/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/trunk/ChangeLog b/trunk/ChangeLog new file mode 100644 index 0000000..357d642 --- /dev/null +++ b/trunk/ChangeLog @@ -0,0 +1,3 @@ +2002-08-06 Karl Trygve Kalleberg + * Created separate CVS module for Gentoolkit + * Restructured directory hierarchy diff --git a/trunk/NEWS b/trunk/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/README b/trunk/README new file mode 100644 index 0000000..cd3a695 --- /dev/null +++ b/trunk/README @@ -0,0 +1,33 @@ +Package: Gentoolkit +Version: 0.1.3 +Authors: Karl Trygve Kalleberg + Brandon Low + See src//AUTHORS for tool-specific authors + +MOTIVATION + +Gentoolkit is a collection of useful adminstration scripts particular to +the Gentoo Linux distribution. It contains rough drafts and +implementations of features that may in time make it into Portage, or +into full-fledged tools in their own right. + +CONTENTS + +dep-clean - cleans out unwanted dependencies +emerge-rsync - coloured output of changes in last rsync +emerge-webrsync - rsync-over-http +epm - rpm-like query tool +etc-update - keeps your /etc up to date after package installs +pkg-clean - cleans packages +pkg-size - calculates size of an installed package +portage-statistics - shows various statistics about the Portage Tree +qpkg - convient package query tool +useflag - tool for handling use flag settings + + +IMPROVEMENTS + +Any suggestions for improvements should be sent to karltk@gentoo.org, or +added as a bug assigned to me. + +We only accept new contributions if they are written in bash or python. diff --git a/trunk/TODO b/trunk/TODO new file mode 100644 index 0000000..7028f5f --- /dev/null +++ b/trunk/TODO @@ -0,0 +1 @@ +- Merge emerge-webrsync with emerge-rsync diff --git a/trunk/src/change/AUTHORS b/trunk/src/change/AUTHORS new file mode 100644 index 0000000..fc3af19 --- /dev/null +++ b/trunk/src/change/AUTHORS @@ -0,0 +1,5 @@ +Dan Armak + - Basic idea + - Initial version +Karl Trygve Kalleberg + - Gentoolkit-specific changes diff --git a/trunk/src/change/ChangeLog b/trunk/src/change/ChangeLog new file mode 100644 index 0000000..6002078 --- /dev/null +++ b/trunk/src/change/ChangeLog @@ -0,0 +1,3 @@ +2002-08-09 Karl Trygve Kalleberg : + * Reformatted usage to work with 80 columns + * Now loads ~/.gentoo/gentool-env instead of ~/.change diff --git a/trunk/src/change/README b/trunk/src/change/README new file mode 100644 index 0000000..bda1842 --- /dev/null +++ b/trunk/src/change/README @@ -0,0 +1,20 @@ +Package : change +Version : 0.2.4 +Author : See AUTHORS + +MOTIVATION + +Maintaing Gentoo's ChangeLog files in the Portage Tree is a tedious affair. +Many of the details are well-defined enough for a tool to do. change is this +tool. + +MECHANICS + +change can create a ChangeLog, add entries to the ChangeLog file, scan for +updated files. + + +IMPROVEMENTS + +For improvements, send a mail to karltk@gentoo.org or make out a bug at +bugs.gentoo.org and assign it to me. diff --git a/trunk/src/change/change b/trunk/src/change/change new file mode 100644 index 0000000..da2e91b --- /dev/null +++ b/trunk/src/change/change @@ -0,0 +1,344 @@ +#! /bin/bash + +# Copyright 1999-2002 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# Author: Dan Armak +# $Header: $ + +eval `grep PORTDIR= /etc/make.globals` +eval `grep PORTDIR= /etc/make.conf` +[ -z "$PORTDIR" ] && PORTDIR="/usr/portage" + +# register temp files (we delete them in the end) +TMPMESSAGE=`tempfile -p change` || cleanup 1 +TMPHEADER=`tempfile -p change` || cleanup 1 +TMPENTRY=`tempfile -p change` || cleanup 1 +TMPOLDLOG=`tempfile -p change` || cleanup 1 +TMPCHANGELOG=`tempfile -p change` || cleanup 1 + +# get user info from config file - $AUTHORNAME and $AUTHOREMAIL +init() { + . ~/.gentoo/gentool-env || return 1 +} + +print_about() { + + echo "change v 0.2.4 - A Gentoo ChangeLog editor." + echo "Author Dan Armak " +} + +print_usage() { + + echo "Usage: +change [-shv] [-m|--message msg] [-f|--message-file file] + [-a|--authorname name] [-l|--authormail mail] + [-n|--new-version ver] [-o|--output dest] + +: List of packages whose changelogs are to be edited. All +changelogs edited in one run will be added the same log message. + +Acceptable formats: Example: +category/package kde-base/kdebase +path to package dir kdebase || ../../kdebase +path to changelog file portage/kde-base/kdebase/ChangeLog + +Note that you must use -g for changelog files outside $PORTDIR. + +-m, --message \"msg\" Use log message \"msg\", do not open editor. +-f, --message-file Use contents of as log message, do not open + editor. +-a, --authorname \"name\" Use \"name\" (e.g. Dan Armak) in log. +-l, --authormail \"email\" Use \"email\" (e.g. danarmak@gentoo.org) in log. +-n, --new-version \"ver\" Add a line about a new version number \"ver\" to + the log. +-g, --generate Create a new changelog file if one does not exist. + This option must come before the list of affected + changelog files. Incidentally, this option also + enables you to work with a changelog file outside + $PORTDIR. + You must use it every time you edit such a file. + However, change won't be able to figure out the + category and package names of your changelog file + and those parts will be missing. (FIXME!) +-o, --output \"file\" Save new changelog in file \"file\". + Default is the the same file we're changing (i.e. + no backup). +-s, --stdout Print new changelog to stdout (disables saving to + file). This suppresses the usual info messages. +-c, --changed-files List of changed files (goes into entry header). + Default is to simply say \"ChangeLog :\". Multiple + -c options can be given. +-h, --help Print this usage information. +-v, --version Print a short about line and the version number and + exit. + +See also the mandatory config file ~/.gentoo/gentool-env (the gentool-env man +page contains a template). +" + +} + +# parse command line parameters +# this function should be called before all others (e.g. before init()) +# or else it might stomp on some settings +parse_params() { + + # at least one parameter required - changelog to process + if [ -z "$1" ]; then + echo "At least one parameter is required." + print_about + print_usage + cleanup 1 + fi + + while [ -n "$1" ]; do + + # note: with parameters that come in two pieces (i.e. -m foo) + # we identify the first one, grab the second one from $2 and + # shift an extra time + case "$1" in + + # optional log message, if defined then we won't launch $EDITOR + # comes in explicit string and file reference variations + -m | --message) + MESSAGE="$2" + shift + ;; + -f | --message-file) + cp $2 $TMPMESSAGE + shift + ;; + + # general settings (usually set in .change) + -a | --authorname) + AUTHORNAME="$2" + shift + ;; + -l | --authormail) + AUTHOREMAIL="$2" + shift + ;; + + # add a line about a new version (starting with *) to the changelog + # to add the line but no changelog info, call with -n -m "" + -n | --new-version) + NEWVERSION="$2" + shift + ;; + + # create a new changelog file + -g | --generate) + GENERATE=true + ;; + + # output redirection. default (if $OUTPUT isn't set) is to change the + # specified changelog file. + # illegal if more than one changelog file/package is specified. + -o | --output) + OUTPUT="$2" + shift + ;; + # redirect output to stdout - can be combined with -o + -s | --stdout) + STDOUT="true" + OUTPUT="/dev/null" + ;; + + # list of files changed (second part inclosed in quotes!) + -c | --changed-files) + CHANGED="$CHANGED $2" + shift + ;; + + # request for version/usage information etc + -h | --help) + print_about + print_usage + cleanup 0 + ;; + -v | --version) + print_about + cleanup 0 + ;; + + # everything else we couldn't identify. most of it is packages/files to work on. + *) + for x in "$MYPORTDIR/$1/ChangeLog" "$PORTDIR/$1/ChangeLog" "$PWD/$1/ChangeLog" "$PWD/$1"; do + if [ -f "$x" ]; then + FILES="$FILES $x" + shift # because by calling continue we skip the shift at the end of the case block + continue 2 # next while iteration + fi + done + # if we haveb't detected a changelog file, maybe we need to create one + if [ -n "$GENERATE" ]; then + for x in "$PWD/$1" "$1" "$MYPORTDIR/$1" "$PORTDIR/$1"; do + if [ -d "$x" ]; then + touch $x/ChangeLog + FILES="$FILES $x/ChangeLog" + shift # because by calling continue we skip the shift at the end of the case block + continue 2 # next while iteration + fi + done + fi + + echo "!!! Error: unrecognized option: $1" + echo + print_usage + cleanup 1 + + ;; + + esac + + shift + done + + if [ -z "$FILES" ]; then + echo "No changelog path or package name passed, mandatory parameter missing." + echo + print_usage + cleanup 1 + fi + +} + +# get the log message +get_msg() { + + if [ -n "`cat $TMPMESSAGE`" ]; then + echo "Using message-on-file." + elif [ -n "$MESSAGE" ]; then + echo "$MESSAGE" > $TMPMESSAGE + else # [ -z "$MESSAGE" ] + + echo > $TMPMESSAGE + echo "Please enter changelog. You can leave this line, it will be automatically removed." >> $TMPMESSAGE + $EDITOR $TMPMESSAGE + cp $TMPMESSAGE ${TMPMESSAGE}2 + sed -e '/Please enter changelog. You can leave this line, it will be automatically removed./ D' \ + ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + + fi + + # break up into 80-character columns (actually 78 chars because we'll + # add two spaces to every line) + cp $TMPMESSAGE ${TMPMESSAGE}2 + fmt -s -w 78 ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + + # add two spaces to the beginning of every line of the message. + # do this separately from the sed in the else section above + # because it should be executed for the if and elif sections too. + cp $TMPMESSAGE ${TMPMESSAGE}2 + sed -e 's:^: :g' ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + +} + +# get list of files and wrap it in the following manner: +# 1 item on the first list and upto 80 chars on every other. +# also adds 2 spaces to the beginning of every line but the first. +wrap_list() { + + echo -n $1 + shift + + while [ -n "$1" ]; do + if [ -n "$LIST" ]; then + LIST="$LIST, $1" + else + echo , + LIST=$1 + fi + shift + done + LIST="$LIST :" + + echo $LIST | fmt -s -w 78 | sed -e 's:^: :g' - + +} + +# do the actual work on te changelog file passed as $1 +process() { + + # figure out category and package names + name=${1//${PORTDIR}\/} + name=${name//${MYPORTDIR}\/} + name=${name//\/ChangeLog} + + OLDIFS="$IFS" + IFS="/" + for x in $name; do + if [ -z "$CATEGORY" ]; then + CATEGORY="$x" + else + PACKAGE="$x" + fi + done + IFS="$OLDIFS" + + # create header + echo \ +"# ChangeLog for $CATEGORY/$PACKAGE +# Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL +# \$Header: \$ +" > $TMPHEADER + + # create entry line + if [ -n "$NEWVERSION" ]; then + echo "*$PACKAGE-$NEWVERSION (`date '+%d %b %Y'`)" > $TMPENTRY + echo >> $TMPENTRY + fi + + echo -n " `date "+%d %b %Y"`; ${AUTHORNAME} <${AUTHOREMAIL}> " >> $TMPENTRY + [ -z "$CHANGED" ] && CHANGED="ChangeLog " + wrap_list $CHANGED >> $TMPENTRY + + echo >> $TMPENTRY + + # get the original changelog, minus the old header + sed -e " +/# ChangeLog for $CATEGORY\/$PACKAGE/ D +/# Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL/ D +/^# \$Header:/ D" $1 > $TMPOLDLOG + + # join everything together + cat $TMPHEADER $TMPENTRY $TMPMESSAGE $TMPOLDLOG > $TMPCHANGELOG + + # various output options + if [ -n "$OUTPUT" ]; then + cp $TMPCHANGELOG $OUTPUT + [ -z "$STDOUT" ] && echo "New changelog saved in $OUTPUT." + else + cp $TMPCHANGELOG $1 + [ -z "$STDOUT" ] && echo "Original changelog $1 replaced." + fi + + if [ -n "$STDOUT" ]; then + cat $TMPCHANGELOG + fi + +} + +# pass exit code to this function +cleanup() { + + rm -f $TMPMESSAGE $TMPHEADER $TMPENTRY $TMPCHANGELOG $TMPOLDLOG + + exit $1 + +} + +parse_params "${@}" + +init + +get_msg + +for x in $FILES; do + process $x +done + +cleanup 0 diff --git a/trunk/src/change/change.1 b/trunk/src/change/change.1 new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/dep-clean/AUTHORS b/trunk/src/dep-clean/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/dep-clean/ChangeLog b/trunk/src/dep-clean/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/dep-clean/README b/trunk/src/dep-clean/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/dep-clean/dep-clean b/trunk/src/dep-clean/dep-clean new file mode 100644 index 0000000..9bb3871 --- /dev/null +++ b/trunk/src/dep-clean/dep-clean @@ -0,0 +1,266 @@ +#!/bin/bash +#Shows unrequired packages and missing dependencies. +#Author: Jerry Haltom + +PROG=`basename ${0}` + +tmp="/tmp/$$" +rm -rf ${tmp} > /dev/null 2>&1 +mkdir ${tmp} > /dev/null 2>&1 + +declare -i i + +set -- `getopt -n ${PROG} -o N,R,U,I,v,C,h -l needed,removed,unneeded,interactive,verbose,nocolor,help -- ${*/ --/};[ $? != 0 ] && echo "y"` + +while [ ${#} -gt 0 ] +do + a=${1} + shift + case "${a}" in + + -I|--interactive) + interactive=y + ;; + + -N|--needed) + needed=y + ;; + + -U|--unneeded) + unneeded=y + ;; + + -R|--removed) + removed=y + ;; + + -v|--verbose) + verb=y + ;; + + -C|--nocolor) + nocolor=y + ;; + + -h|--help) + usage=y + ;; + + --) + [ ${1} ] && usage=y && broke=y + break + ;; + + *) + usage=y + broke=y + echo "FIXME - OPTION PARSING - ${a}" + break + ;; + + esac +done + +if [ ! ${needed} ] && [ ! ${unneeded} ] && [ ! ${removed} ]; then + needed=y + unneeded=y + removed=y +fi + +#Set up colors +if [ ! "${nocolor}" ]; then + NO="\x1b[0;0m" + BR="\x1b[0;01m" + CY="\x1b[36;01m" + GR="\x1b[32;01m" + RD="\x1b[31;01m" + YL="\x1b[33;01m" + BL="\x1b[34;01m" +elif [ ! ${verb} ] && ( + ( [ ${needed} ] && [ ${unneeded} ] ) || + ( [ ${unneeded} ] && [ ${removed} ] ) || + ( [ ${removed} ] && [ ${needed} ] ) + ); then + NEED=" N" + UNNE=" U" + REMO=" R" +fi + +if [ `whoami` != "root" ] +then + echo -e "${RD}Only root can run ${PROG}${NO}" + rm -rf ${tmp} + exit 1 +fi + +if [ ${usage} ]; then + echo -e "${BR}GenToolKit's Dependency Checker! +${NO}Displays packages that are installed but which none +of the packages in world or system depend on, and +displays packages which are depended on by world or +system, but are not currently installed. + +${BR}USAGE: + ${BL}${PROG}${YL} [${NO}options${YL}]${NO} + ${BL}${PROG}${GR} --help${NO} + +${BR}OPTIONS: + ${GR}-U, --unneeded${NO} display unneeded packages that are installed (${GR}green${NO}) + ${GR}-N, --needed${NO} display needed packages that are not installed (${RD}red${NO}) + ${GR}-R, --removed${NO} display installed packages not in portage (${YL}yellow${NO}) + + ${GR}-I, --interactive${NO} interactively modify world file before proceeding + ${GR}-C, --nocolor${NO} output without color, if necessary, package types are + noted with ${GR}U, N${NO} and ${GR}R${NO} respectively + ${GR}-v, --verbose${NO} be more verbose + +${BR}NOTES: + ${GR}*${NO} If this script is run on a system that is not up-to-date or which hasn't + been cleaned (with '${BL}emerge -c${NO}') recently, the output may be deceptive. + ${GR}*${NO} If the same package name appears in all three categories, then it is + definitely time to update that package and then run '${BL}emerge -c${NO}'. + ${GR}*${NO} The ${GR}-U, -N${NO} and ${GR}-R${NO} options may be combined, defaults to ${GR}-UNR${NO}" + rm -rf ${tmp} > /dev/null 2>&1 + [ ${broke} ] && exit 1 || exit 0 +fi + +X="\([^/]*\)" + +#Retrieve currently merged packages. +[ ${verb} ] && \ +echo -e "${CY}Retrieving currently merged packages.${NO}" +find /var/db/pkg -name '*.ebuild' | \ + sed -e "s:/var/db/pkg/::" \ + -e "s:${X}/${X}/${X}:\1/\2:" | \ + sort | uniq >> ${tmp}/current + +[ ${verb} ] && \ +echo -e "${CY}"`cat ${tmp}/current | wc -l` "currently merged packages.${NO}" +[ ${verb} ] && \ +echo -e + +#Retrieve system packages and add to image. +[ ${verb} ] && \ +echo -e "${CY}Retrieving system packages.${NO}" +emerge system -eup | \ + grep ebuild | \ + sed -e "s:^.*] ::" \ + -e "s: to /::" | \ + sort | uniq \ + > ${tmp}/system +# -e "s:-r[0-9]*::" \ +# -e "s:-[0-9].*::" | \ + +[ ${verb} ] && \ +echo -e "${CY}"`cat ${tmp}/system | wc -l 2> /dev/null` "packages contained in system.${NO}" +[ ${verb} ] && \ +echo -e + +#Create local copy of world and ask user to verify it. +[ ${verb} ] && \ +echo -e "${CY}Preparing world file.${NO}" +cp /var/cache/edb/world ${tmp}/world + +[ ${interactive} ] && \ +${EDITOR} ${tmp}/world + +[ ${verb} ] && \ +echo -e "${CY}"`cat ${tmp}/world | wc -l` "packages contained in world.${NO}" +[ ${verb} ] && \ +echo -e + +#Retrieve world packages and dependencies and add to image. +[ ${verb} ] && \ +echo -e "${CY}Listing world and total dependencies.${NO}" + +qpkg -I -nc -vv | \ + grep ebuild | \ + fgrep "`cat ${tmp}/world`" | \ + cut -f5,6 -d"/" > ${tmp}/world.all + +cat ${tmp}/world.all | sed -e s:$:xxx: | \ + fgrep "`find /usr/portage/ -iname '*.ebuild'|cut -f4,6 -d/ | \ + sed -e s:\\.ebuild:xxx:`" | \ + sed -e "s:^:\\\=:" -e "s:xxx::" > ${tmp}/world.new + +sort ${tmp}/world.new | uniq | \ + xargs emerge -eup | tee ${tmp}/log | \ + grep ebuild | \ + sed -e "s:^.*] :: ; s: to /::" > ${tmp}/image.unsorted + +depends=`cat ${tmp}/image.unsorted|wc -l` + +if [ ${depends} -lt "2" ]; then + echo -e "${RD}There appears to be an unresolved dependency in your world file." + echo -e "Please check for masking errors or other world file issues," + echo -e "and then try again." + echo -e + echo -e "The following is the emerge output for your reference:${NO}" + cat ${tmp}/log + rm -rf ${tmp} > /dev/null 2>&1 + exit 1 +fi + +cat ${tmp}/system >> ${tmp}/image.unsorted + +#Cleanup image +sort ${tmp}/image.unsorted | uniq > ${tmp}/image + +[ ${verb} ] && \ +echo -e "${CY}"`cat ${tmp}/image | wc -l` "packages contained in final image.${NO}" + +#Determine packages that exist in current but not in image. +#These packages are safe to clean up. +if [ ${unneeded} ]; then + [ ${verb} ] && \ + echo -e + [ ${verb} ] && \ + echo -e "${CY}These packages have no other packages depending on them.${NO}" + i=0 + for pkg in `cat ${tmp}/current`; do + if [ "`cat ${tmp}/image | grep -x ${pkg} | wc -l`" -eq "0" ]; then + echo -e "${GR}${pkg}${CY}${UNNE}${NO}" + i=${i}+1 + fi + done + [ ${verb} ] && \ + echo -e "${CY}Total of ${i} unneeded packages.${NO}" +fi + +#Determine packages that exist in image but not in current. +#These packages should be added. +if [ ${needed} ]; then + [ ${verb} ] && \ + echo -e + [ ${verb} ] && \ + echo -e "${CY}These packages are depended upon but are not present on the system.${NO}" + i=0 + for pkg in `cat ${tmp}/image`; do + if [ "`cat ${tmp}/current | grep -x ${pkg} | wc -l`" -eq "0" ]; then + echo -e "${RD}${pkg}${CY}${NEED}${NO}" + i=${i}+1 + fi + done + [ ${verb} ] && \ + echo -e "${CY}Total of ${i} needed packages.${NO}" +fi + +#Determine packages that are installed but not currently in portage +if [ ${removed} ]; then + [ ${verb} ] && \ + echo -e + [ ${verb} ] && \ + echo -e "${CY}These packages are installed but not in the portage tree.${NO}" + cat ${tmp}/current | sed -e s:$:xxx: | \ + fgrep -v "`find /usr/portage/ -iname '*.ebuild'|cut -f4,6 -d/ | \ + sed -e s:\\\.ebuild:xxx:`" | \ + sed -e "s:xxx:${CY}${REMO}${YL}:" > ${tmp}/world + echo -ne "${YL}" + cat ${tmp}/world + echo -ne "${NO}" + [ ${verb} ] && \ + echo -e "${CY}Total of" `cat ${tmp}/world|wc -l` "removed packages.${NO}" +fi + +rm -rf ${tmp} > /dev/null 2>&1 + diff --git a/trunk/src/dep-clean/dep-clean.1 b/trunk/src/dep-clean/dep-clean.1 new file mode 100644 index 0000000..5e46c10 --- /dev/null +++ b/trunk/src/dep-clean/dep-clean.1 @@ -0,0 +1,187 @@ +.\" Automatically generated by Pod::Man version 1.15 +.\" Thu Jul 18 15:59:55 2002 +.\" +.\" Standard preamble: +.\" ====================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R + +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used +.\" to do unbreakable dashes and therefore won't be available. \*(C` and +.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<> +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.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" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr +.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and +.\" index entries marked with X<> in POD. Of course, you'll have to process +.\" the output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it +.\" makes way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +.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 / +.\} +.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 / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" 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 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 +. \" 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 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 +.\} +.rm #[ #] #H #V #F C +.\" ====================================================================== +.\" +.IX Title "DEP-CLEAN 1" +.TH DEP-CLEAN 1 "Copyright 2002 Gentoo Technologies, Inc." "2002-07-18" "GenToolKit's Dependency Checker!" +.UC +.SH "NAME" +dep-clean \- Shows unrequired packages and missing dependencies. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& dep-clean [-RUNICv] +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +dep-clean displays extraneous, missing or extra packages. Extra packages are those in which are not a part of the portage tree (/usr/portage). It does \s-1NOT\s0 modify the system in any way. +.SH "OPTIONS" +.IX Header "OPTIONS" +.Ip "\-N, \-\-needed" 4 +.IX Item "-N, --needed" +Display needed packages that are not installed. (red) (default) +.Ip "\-R, \-\-removed" 4 +.IX Item "-R, --removed" +Display installed packages not in portage. (yellow) (default) +.Ip "\-U, \-\-unneeded" 4 +.IX Item "-U, --unneeded" +Display unneeded packages that are installed. (green) (default) +.Ip "\-I, \-\-interactive" 4 +.IX Item "-I, --interactive" +Interactively modify world file before proceeding. +.Ip "\-C, \-\-nocolor" 4 +.IX Item "-C, --nocolor" +Output without color. Package types will be noted with R, U and N. +.Ip "\-v, \-\-verbose" 4 +.IX Item "-v, --verbose" +Be more verbose. +.SH "NOTES" +.IX Header "NOTES" +.Ip "" 4 +If this script is run on a system that is not up-to-date or which hasn't been cleaned (with 'emerge \-c') recently, the output may be deceptive. +.Ip "" 4 +If the same package name appears in all three categories, then it is definitely time to update that package and then run 'emerge \-c'. +.Ip "" 4 +The \-U, \-N and \-R options may be combined, default is \-UNR +.SH "AUTHORS" +.IX Header "AUTHORS" +Jerry Haltom (dep-clean) +.br +Brandon Low (dep-clean) +.PP +Paul Belt (man page) diff --git a/trunk/src/emerge-rsync/AUTHORS b/trunk/src/emerge-rsync/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-rsync/ChangeLog b/trunk/src/emerge-rsync/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-rsync/README b/trunk/src/emerge-rsync/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-rsync/emerge-rsync b/trunk/src/emerge-rsync/emerge-rsync new file mode 100755 index 0000000..224b548 --- /dev/null +++ b/trunk/src/emerge-rsync/emerge-rsync @@ -0,0 +1,52 @@ +#!/bin/sh +BASE=/var/cache +USE_COLORS=yes + +# end user configuration section +. /etc/make.globals +BEFORE=$BASE/ebuild-rsync.before +AFTER=$BASE/ebuild-rsync.after +NEW=$BASE/ebuild-rsync.new +REMOVED=$BASE/ebuild-rsync.removed + +if [ "$USE_COLORS" == "yes" ]; then + RED="\033[;31m" + GREEN="\033[;32m" + NORMAL="\033[m" +fi + +function portagetree () { + find $PORTDIR -type d -mindepth 2 -maxdepth 2 +} + +# do it +portagetree >$BEFORE +emerge $@ rsync +portagetree >$AFTER +diff $BEFORE $AFTER | grep ">" | sed "s/> //g" > $NEW +diff $BEFORE $AFTER | grep "<" | sed "s/< //g" > $REMOVED + +# cleanup +rm $BEFORE $AFTER + +# display new ebuilds +if ! diff -q $NEW /dev/null >/dev/null; then + echo + echo New ebuilds: + for i in $(cat $NEW); do + DESCRIPTION="$i/*.ebuild ${RED}does not exist$NORMAL" + EBUILD=$(ls $i/*.ebuild --sort=time 2>/dev/null | head -n 1) + [ -z "$EBUILD" ] || . $EBUILD + echo -e $GREEN${i##$PORTDIR/}$NORMAL: $DESCRIPTION + done +fi + +# display removed ebuilds +if ! diff -q $REMOVED /dev/null >/dev/null; then + echo + echo Removed ebuilds: + for i in $(cat $REMOVED); do + echo -e $RED${i##$PORTDIR/}$NORMAL + done +fi + diff --git a/trunk/src/emerge-webrsync/AUTHORS b/trunk/src/emerge-webrsync/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-webrsync/ChangeLog b/trunk/src/emerge-webrsync/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-webrsync/README b/trunk/src/emerge-webrsync/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/emerge-webrsync/emerge-webrsync b/trunk/src/emerge-webrsync/emerge-webrsync new file mode 100644 index 0000000..af3e89b --- /dev/null +++ b/trunk/src/emerge-webrsync/emerge-webrsync @@ -0,0 +1,62 @@ +#! /bin/sh + +# Copyright(c) 2002 Gentoo Technologies, Inc. +# Author: Karl Trygve Kalleberg +# Rewritten from the old, Perl-based emerge-webrsync script + +. /etc/make.conf + +syncpath="/var/tmp/emerge-webrsync" + +if [ ! -d $syncpath ] ; then + mkdir -p $syncpath +fi + +cd $syncpath + +found=0 +attempts=0 +download=1 +wgetops=-q + +if [ "$1" == "-n" ] ; then + download=0 +fi + +sync_local() { + echo Syncing local tree... + tar jxf $file + rm -f $file + rsync -av . /usr + rm -rf portage +} + +echo "Fetching most recent snapshot" + +while (( $attempts < 40 )) ; do + + day=`date -d "-$attempts day" +"%d"` + month=`date -d "-$attempts day" +"%m"` + year=`date -d "-$attempts day" +"%Y"` + + file="portage-${year}${month}${day}.tar.bz2" + + if [ -f $file ] && [ $download == 0 ] ; then + sync_local + exit 0 + fi + + for i in $GENTOO_MIRRORS ; do + url="${i}/snapshots/$file" + rm -f $file + if (wget $wgetops $url) ; then + sync_local + exit 0 + fi + done + attempts=$[attempts+1] +done + +rm -rf portage + +exit 1 diff --git a/trunk/src/epm/AUTHORS b/trunk/src/epm/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/epm/ChangeLog b/trunk/src/epm/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/epm/README b/trunk/src/epm/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/epm/epm b/trunk/src/epm/epm new file mode 100644 index 0000000..408f312 --- /dev/null +++ b/trunk/src/epm/epm @@ -0,0 +1,421 @@ +#!/usr/bin/perl -wI. +# $Id$ + +use Getopt::Long; +#use epm; + +# Global vars +my $verbose = 0; +my $dbpath = '/var/db/pkg'; +my $pkgregex = + '^(.+?)'. # name + '-(\d+(?:\.\d+)*\w*)'. # version, eg 1.23.4a + '((?:(?:_alpha|_beta|_pre|_rc)\d*)?)'. # special suffix + '((?:-r\d+)?)$'; # revision, eg r12 +my $root = '/'; +my %opt = ( + 'dbpath' => \$dbpath, + 'root' => \$root, + 'v' => \$verbose, +); +my $exitcode = 0; + +############################################## +# +# UTILITY FUNCTIONS +# +############################################## +sub verb { + print STDERR map "-- $_\n", @_ if $verbose; +} + +sub vverb { + print STDERR map "-- $_\n", @_ if $verbose > 1; +} + +############################################## +# +# QUERY MODE +# +############################################## +sub query { + verb "query mode"; + verb "actually Verify mode" if $opt{'V'}; + + # Implied -l similar to rpm + $opt{'dump'} and $opt{'l'} = 1; + $opt{'d'} and $opt{'l'} = 1; + $opt{'c'} and $opt{'l'} = 1; + + # @dgrps contains a list of all the groups at dbpath + # @dpkgs contains a list of all the packages at dbpath/@dgrps + # %dpkggrp contains a mapping of pkg=>grp + # %dnampkg contains a mapping of nam=>@pkg (libxml=>[libxml-1.8.13]) + # @pkgs is the list of packages being queried + # %dfilepkg is a mapping of filename=>@pkg + my (@dgrps, @dpkgs, %dpkggrp, %dnampkg, @pkgs); + + # Read all groups in the db (except for virtual) + opendir D, $dbpath or + die "epm: Database not found at $dbpath\n"; + @dgrps = grep {-d "$dbpath/$_" && !/^\./ && $_ ne 'virtual'} readdir D; + closedir D; + verb "read ".@dgrps." groups from $dbpath"; vverb @dgrps; + + # Read all pkgs in the db + for my $g (@dgrps) { + opendir D, "$dbpath/$g" or + die "epm: Error reading directory $dbpath/$g\n"; + my @dp = grep {-d "$dbpath/$g/$_" && !/^\./} readdir D; + verb "read ".@dp." pkgs in group $g"; vverb @dp; + @dpkggrp{@dp} = ($g) x @dp; + push @dpkgs, @dp; + } + vverb "package to group associations:"; + vverb map " $_ => $dpkggrp{$_}", keys %dpkggrp; + + # Create association of names => pkgs + for my $p (@dpkgs) { + $p =~ /$pkgregex/o || $dpkggrp{$p} eq 'virtual' || + die "epm: Could't parse name/version/suffix/rev from $p"; + # $2, $3, $4 aren't used right now, but they're in the regex + # for the sake of completeness. + push @{$dnampkg{$1}}, $p; + } + + # File-based query + if ($opt{'f'}) { + # Search through CONTENTS for elements in ARGV. Building an + # index would be bad because it would be HUGE. + for my $a (@ARGV) { + my $found = 0; + # Trim trailing slashes from directories + $a =~ s#/*$##; + # TODO: If it's a relative pathname, then figure out + # the full pathname + if ($a !~ m#^/#) { } + # TODO: stat the file here so that we can determine later + # what package the file currently belongs to + for my $p (@dpkgs) { + my ($CONTENTS, @files); + $CONTENTS = "$dbpath/$dpkggrp{$p}/$p/CONTENTS"; + unless (-s $CONTENTS) { + verb "skipping empty/nonexistent $CONTENTS"; + next; + } + open F, "<$CONTENTS" or die "epm: Can't open $CONTENTS\n"; + @files = ; + close F; + # Check this list of files for the current query + for my $f (@files) { + $f = (split ' ', $f)[1]; + next unless $f eq $a; + $found = 1; + # If not doing -qlf, then print the package name + unless ($opt{'l'}) { + # If doing -qGf, then include the group name + print $opt{'G'} ? "$dpkggrp{$p}/$p\n" : "$p\n"; + } + push @pkgs, $p; + } + } + unless ($found) { + print "file $a is not owned by any package\n"; + $exitcode = 1; + } + } + # Clear out ARGV so queries below don't get confused + @ARGV = (); + } + + # Group-based query + # Note that if -qfg specified, then rpm prioritizes -qf over -qg, + # so we do too. + elsif ($opt{'g'}) { + for my $a (@ARGV) { + verb "checking for packages in group $a"; + my @l = grep $dpkggrp{$_} eq $a, @dpkgs; + vverb "packages in group $a:"; + vverb " ", join "\n ", @l; + unless (@l) { + print "group $a does not contain any packages\n"; + $exitcode = 1; + } + push @pkgs, @l; + } + # Clear out ARGV so queries below don't get confused + @ARGV = (); + } + + # Package-based query (how does this work with emerge?) + if ($opt{'p'}) { + die "epm: Sorry, package-based query not yet supported\n"; + } + + # Query on all packages + if ($opt{'a'}) { + die "epm: extra arguments given for query of all packages\n" if @ARGV; + @pkgs = @dpkgs; + } + elsif (@pkgs) { + # must have been populated by, for instance, -qf + } + else { + for my $a (@ARGV) { + if ($a =~ /$pkgregex/o) { + verb "$a matches pkgregex"; + vverb "name=$1, version=$2, suffix=$3, revision=$4"; + push @pkgs, $a; + next; + } + if (defined $dnampkg{$a}) { + verb "$a found in dnampkg"; + vverb @{$dnampkg{$a}}; + push @pkgs, @{$dnampkg{$a}}; + next; + } + print "package $a is not installed\n"; + next; + } + } + + # Do a file listing of the requested packages + if ($opt{'l'}) { + for my $p (@pkgs) { + my $CONTENTS = "$dbpath/$dpkggrp{$p}/$p/CONTENTS"; + open F, "<$CONTENTS" || die "epm: Can't open $CONTENTS\n"; + my @files = ; + close F; + # Trim @files if config files requested + if ($opt{'c'}) { + # Read in CONFIG_PROTECT from /etc/make.{global,conf} + my @CONFIG_PROTECT = split ' ', + `. /etc/make.globals; + . /etc/make.conf; + echo \$CONFIG_PROTECT`; + die "CONFIG_PROTECT is empty" unless @CONFIG_PROTECT; + my $confprotre = join '|', @CONFIG_PROTECT; + @files = grep { + (split ' ', $_)[1] =~ /^($confprotre)/o + } @files; + } + # Trim @files if doc files requested + if ($opt{'d'}) { + # We don't have a variable like CONFIG_PROTECT to work + # with, so just fake it... :-) + my $docre = '/usr/share/doc|/usr/share/man'; + @files = grep { + (split ' ', $_)[1] =~ m/^($docre)/o + } @files; + } + # If this is a dump query, then print the entire array + if ($opt{'dump'}) { + print @files; + } + # Otherwise do some work so that intermediate directories + # aren't listed + else { + for (my $i=0; $i < @files; $i++) { + my ($f1) = $files[$i]; + $f1 = (split ' ', $f1)[1]; + if ($i < @files-1) { + my $f2 = $files[$i+1]; + $f2 = (split ' ', $f2)[1]; + vverb "Comparing $f1 to $f2"; + next if $f2 =~ m#^\Q$f1\E/#; + } + print $f1, "\n"; + } + } + } + } + + # If not another type of listing, then simply list the packages + if (!$opt{'l'} && !$opt{'f'}) { + # If doing -qG, then include the group name + print map(($opt{'G'} ? "$dpkggrp{$_}/$_\n" : "$_\n"), @pkgs); + } +} + +############################################## +# +# ERASE MODE +# +############################################## +sub erase { + verb "erase mode"; + verb "(testing)" if $opt{'test'}; + + # Catch empty command-line + die "epm: no packages given for uninstall\n" unless @ARGV; + + # Must be root to erase; rpm just lets permissions slide but I don't + if ($> != 0) { + print STDERR "Must be root to remove packages from the system\n"; + $exitcode = 1; + return; + } + + # Erase everything listed on the command-line. Give an error + # message on bogus names, but continue anyway, a la rpm. Note + # that for epm, we require the group name... + for my $a (@ARGV) { + unless ($a =~ '/') { + print STDERR "error: $a does not contain group/ prefix\n"; + $exitcode = 1; + next; + } + my $p = $a; + $p =~ s,^.*/,,; # remove the group + unless (-f "$dbpath/$a/$p.ebuild") { + print STDERR "error: package $a is not installed\n"; + $exitcode = 1; + next; + } + my @cmd = ('ebuild', "$dbpath/$a/$p.ebuild", 'unmerge'); + print STDERR join(" ", @cmd), "\n"; + unless ($opt{'test'}) { + system @cmd; + die "epm: Fatal error running ebuild; aborting\n" if $?; + } + } +} + +############################################## +# +# MAIN +# +############################################## + +# Syntax string for errors +my $syntax = < - use as the directory for the database + --root - use as the top level directory + Package specification options: + -a, --all - query all packages + -f + - query package owning + *-p + - query (uninstalled) package + *--triggeredby - query packages triggered by + *--whatprovides - query packages which provide capability + *--whatrequires - query packages which require capability + -g + --group + - query packages in group + Information selection options: + *-i, --info - display package information + -l - display package file list + -G, --showgroup - display group name in output (not in rpm) + -d - list only documentation files (implies -l) + -c - list only configuration files (implies -l) + --dump - show all verifiable information for each file + (must be used with -l, -c, or -d) + *--provides - list capabilities package provides + *-R, --requires - list package dependencies + *--scripts - print the various [un]install scripts + + --erase + -e - erase (uninstall) package + *--allmatches - remove all packages which match + (normally an error is generated if + specified multiple packages) + --dbpath - use as the directory for the database + *--justdb - update the database, but do not modify the + filesystem + *--nodeps - do not verify package dependencies + *--noorder - do not reorder package installation to satisfy + dependencies + *--noscripts - do not execute any package specific scripts + *--notriggers - don't execute any scripts triggered by this + package + --root - use as the top level directory + --test - don't uninstall, but tell what would happen + + -V, -y, --verify - verify a package installation using the same + package specification options as -q + --dbpath - use as the directory for the database + --root - use as the top level directory + --nodeps - do not verify package dependencies + --nomd5 - do not verify file md5 checksums + --nofiles - do not verify file attributes +EOT + +# Allow bundling of options since rpm does +Getopt::Long::Configure ("bundling"); + +# Parse the options on the cmdline. Put the short versions first in +# each optionstring so that the hash keys are created using the short +# versions. For example, use 'q|query', not 'query|q'. +my $result = GetOptions( + \%opt, + 'help', # help message + 'v+', # verbose, more v's for more verbosity + + 'q|query', # query mode + 'dbpath=s', # use as the directory for the database + 'root=s', # use as the top level directory + # Package specification options: + 'a|all', # query all packages + 'f', # query package owning file(s) + 'p', # query (uninstalled) package + 'g|group', # query packages in group(s) + 'whatprovides', # query packages which provide capability + 'whatrequires', # query packages which require capability + # Information selection options: + 'i|info', # display package information + 'l', # display package file list + 'd', # list documentation files (implies -l) + 'c', # list configuration files (implies -l) + 'dump', # show all verifiable information for each file + # (must be used with -l, -c, or -d) + 'R|requires', # list package dependencies + 'scripts', # print the various [un]install scripts + 'G|showgroup', # include group name in output + + 'e|erase', # erase mode + 'test', # don't uninstall, but tell what would happen + + 'V|y|verify', # verify a package installation using the same + # package specification options as -q + 'nodeps', # do not verify package dependencies + 'nomd5', # do not verify file md5 checksums + 'nofiles', # do not verify file attributes +); + +# Handle help message +if ($opt{'help'}) { print $syntax; exit 0 } + +# Determine which mode we're running in; make sure it's valid. +# (q)uery +# (V)erify +# (i)nstall +# (U)pgrade +# (e)rase +# (b)uild +# other +if ((defined $opt{"q"} || 0) + + (defined $opt{"V"} || 0) + + (defined $opt{"i"} || 0) + + (defined $opt{"U"} || 0) + + (defined $opt{"e"} || 0) + + (defined $opt{"b"} || 0) != 1) { + die "One mode required, and only one mode allowed\n"; +} + +# Query mode +if ($opt{'q'}) { query(); exit $exitcode } +if ($opt{'V'}) { query(); exit $exitcode } +if ($opt{'e'}) { erase(); exit $exitcode } + +# Other modes not implemented yet +die "epm: Sorry, this mode isn't implemented yet. Check back later! :-)\n"; diff --git a/trunk/src/etc-update/AUTHORS b/trunk/src/etc-update/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/etc-update/ChangeLog b/trunk/src/etc-update/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/etc-update/README b/trunk/src/etc-update/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-clean/AUTHORS b/trunk/src/pkg-clean/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-clean/ChangeLog b/trunk/src/pkg-clean/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-clean/README b/trunk/src/pkg-clean/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-clean/pkg-clean b/trunk/src/pkg-clean/pkg-clean new file mode 100644 index 0000000..e311f43 --- /dev/null +++ b/trunk/src/pkg-clean/pkg-clean @@ -0,0 +1,100 @@ +#!/usr/bin/python +# vim: set ts=4 sw=4: +# Copyright 2002 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License, v2 or later +# Author: Leo Lipelis +# Author: Karl Trygve Kalleberg + +import commands +import re +import sys +import string +import time +import os + +# constants for package tuples that are stored in pkg_hash +PKG_TIME = 0 # number of seconds for ctime function +PKG = 1 # package full path as accepted by ebuild +PKG_NAME = 2 # package name as accepted by emerge + +(status, pkg_files) = commands.getstatusoutput( + "find /var/db/pkg -iname '*.ebuild' -printf '%T@ %p\n' | sort -n") + +pkg_file_list = pkg_files.splitlines() + +pkg_hash = {} +for time_pkg_pair in pkg_file_list: + (pkg_time, pkg) = time_pkg_pair.split() + pkg_time = string.atoi(pkg_time) + # This covers developer trees with not-accepted categories + tmp_name = re.match(r'/var/db/pkg/(.*/.*)/.*', pkg) + if not tmp_name: continue + pkg_name = tmp_name.group(1) + tmp_core = re.match(r'(.*)-\d.*', pkg_name) + if not tmp_core: continue + pkg_core = tmp_core.group(1) + if pkg_hash.has_key(pkg_core): + pkg_hash[pkg_core].append((pkg_time, pkg, pkg_name)) + else: + pkg_hash[pkg_core] = [(pkg_time, pkg, pkg_name)] + +total_len = len(pkg_hash.keys()) +curpkg = 0 +tmpname = os.tmpnam() +assume_yes = 0 + +if len(sys.argv) > 1: + if sys.argv[1] in ["-y", "--yes"]: + assume_yes = 1 + elif sys.argv[1] in ["-h", "--help"]: + print """pkg-clean [options] + +-y, --yes Don't ask for individual confirmation before unmerging; assume yes. +""" + sys.exit(0) + +for pkg_core in pkg_hash.keys(): + print "Examining %s:" % (pkg_core) + if len(pkg_hash[pkg_core]) < 2: + continue + unmerged_indexes = [] + + curpkg += 1 + choices = "" + idx = 1 + for pkg_tuple in pkg_hash[pkg_core]: + choices += " %d \"%s %s\" 0" % \ + (idx, time.ctime(pkg_tuple[PKG_TIME]), + pkg_tuple[PKG_NAME]) + idx += 1 + + params = "dialog --separate-output --backtitle \"pkg-clean processing package %d of %d\" " % ( curpkg, total_len) + params += "--checklist \"Select which package(s) to unmerge\" 20 70 12" + choices + res = os.system(params + " 2> " + tmpname) + if res: + sys.exit(0) + + ins = open(tmpname) + for j in ins.readlines(): + idx = string.atoi(j) + if idx == 0: + break + + full_path = pkg_hash[pkg_core][idx-1][PKG] + ebuild = string.replace(full_path, "/var/db/pkg/", "") + + if not assume_yes: + params = "dialog --backtitle \"" + ebuild + "\" " + \ + "--yesno \"Are you sure you want to unmerge " + ebuild + " ?\" 20 70" + res = os.system(params) + else: + res = 0 + + if res == 0: + (status, unmerge_out) = commands.getstatusoutput( + "ebuild %s unmerge" % (full_path)) + print unmerge_out + time.sleep(2) + if status != 0: + sys.exit(status) + ins.close() diff --git a/trunk/src/pkg-size/AUTHORS b/trunk/src/pkg-size/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-size/ChangeLog b/trunk/src/pkg-size/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-size/README b/trunk/src/pkg-size/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/pkg-size/pkg-size b/trunk/src/pkg-size/pkg-size new file mode 100644 index 0000000..96cdff2 --- /dev/null +++ b/trunk/src/pkg-size/pkg-size @@ -0,0 +1,52 @@ +#!/bin/sh + +# Copyright(c) 2002, Gentoo Technologies, Inc +# Author: Karl Trygve Kalleberg + +spec=$1 + +name=`echo $1 | sed "s/\([^/]*\)\///"` +category=`echo $1 | sed "s/\/.*//"` + +if [ "$category" == "$name" ] ; then + category= +fi + +function tryfile() { + local foo + foo=/var/db/pkg/$1/CONTENTS + bar=`ls $foo 2> /dev/null` + for i in $bar ; do + if [ -f "$i" ] ; then + echo $i + break + fi + done +} + +file=`tryfile "${category}/${name}"` +if [ -z $file ] ; then + file=`tryfile "${category}/${name}*"` + if [ -z $file ] ; then + file=`tryfile "${category}*/${name}"` + if [ -z $file ] ; then + file=`tryfile "${category}*/${name}*"` + if [ -z $file ] ; then + echo "!!! Package resembling ${category}/${name} not found" + exit 1 + fi + fi + fi +fi + +pkgname=`echo $file | sed -e "s:\/var\/db\/pkg\/::" -e "s:\/CONTENTS::"` + +totals=`cat $file|grep "obj"|awk '{ print $2 }' | sed "s/ /\\ /" | xargs du -scb | grep total | cut -f 1` + +size=0 +for i in $totals ; do + size=$[size+i] +done + +echo "$pkgname $size ($[size/1024]KB)" + diff --git a/trunk/src/portage-statistics/AUTHORS b/trunk/src/portage-statistics/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/portage-statistics/ChangeLog b/trunk/src/portage-statistics/ChangeLog new file mode 100644 index 0000000..b83850b --- /dev/null +++ b/trunk/src/portage-statistics/ChangeLog @@ -0,0 +1,2 @@ +2002-03-22 Karl Trygve Kalleberg + * Threw away the coverage scripts, replaced with this. diff --git a/trunk/src/portage-statistics/README b/trunk/src/portage-statistics/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/portage-statistics/histogram.awk b/trunk/src/portage-statistics/histogram.awk new file mode 100644 index 0000000..146f4e4 --- /dev/null +++ b/trunk/src/portage-statistics/histogram.awk @@ -0,0 +1,14 @@ +{ + match($0, "<([A-Za-z0-9.-]+@[A-Za-z0-9.-]+)>") + val=substr($0, RSTART, RLENGTH) + arr[val]++ + total++ +} + +END { + for (x in arr) { + printf("%35s: %-4d of %-4d (%-4.2f%)\n",x,arr[x],total,arr[x]*100/total) + mytot += arr[x] + } + printf("%35s: %-4d of %-4d (%-4.2f%)\n","TOTAL",mytot, total,mytot*100/total) +} \ No newline at end of file diff --git a/trunk/src/portage-statistics/pst-author-coverage b/trunk/src/portage-statistics/pst-author-coverage new file mode 100755 index 0000000..6f7451a --- /dev/null +++ b/trunk/src/portage-statistics/pst-author-coverage @@ -0,0 +1,12 @@ +#! /bin/sh + +if [ -z "$1" ] ; then + echo "Usage: $1 " + exit 1 +fi + +numebuilds=`find /usr/portage/ -name "*.ebuild" | wc -l` +numebuildsfor=`find /usr/portage/ -name "*.ebuild" | xargs grep "$1" | wc -l` + +pct=`echo "scale=2 ; $numebuildsfor*100/$numebuilds" | bc` +printf "%25s: %-4d of %-4d (%-4.2f)\n" $1 $numebuildsfor $numebuilds $pct diff --git a/trunk/src/portage-statistics/pst-package-count b/trunk/src/portage-statistics/pst-package-count new file mode 100755 index 0000000..f7e02e4 --- /dev/null +++ b/trunk/src/portage-statistics/pst-package-count @@ -0,0 +1,9 @@ +#! /bin/sh + +pcnt=`find /usr/portage/ -type f -name "*.ebuild" | sed "s/-[0-9].*//" | sort | uniq | wc -l` +numebuilds=`find /usr/portage/ -type f -name "*.ebuild" | wc -l` +numcat=`find /usr/portage/ -type d -name "*-*" -maxdepth 1 | wc -l` + +echo "Number of categories : $numcat" +echo "Number of ebuilds : $numebuilds" +echo "Unique packages : $pcnt" diff --git a/trunk/src/portage-statistics/pst-total-coverage b/trunk/src/portage-statistics/pst-total-coverage new file mode 100755 index 0000000..0da5c6e --- /dev/null +++ b/trunk/src/portage-statistics/pst-total-coverage @@ -0,0 +1,7 @@ +#! /bin/sh + + +find /usr/portage/ -name "*.ebuild" | \ + xargs egrep -i "<[a-z]+@[a-z\.]+>" | \ + awk -f /usr/share/gentoolkit/histogram.awk | \ + sort -n +1 -r diff --git a/trunk/src/qpkg/AUTHORS b/trunk/src/qpkg/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/qpkg/ChangeLog b/trunk/src/qpkg/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/qpkg/README b/trunk/src/qpkg/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/qpkg/qpkg b/trunk/src/qpkg/qpkg new file mode 100644 index 0000000..b409f09 --- /dev/null +++ b/trunk/src/qpkg/qpkg @@ -0,0 +1,473 @@ +#!/bin/sh +# +# qpkg - query portage package system for various information +# +# Copyright (c) Vitaly Kushneriuk +# This program is distributed under the terms of GPL version 2. +# +# Maintainer: Brandon Low +# +# $Header$ +ID='$Id$' +VERSION=0.`echo ${ID} | cut -d\ -f3` + +PROG=`basename ${0}` + +# Parse args +verb=0 +group="*" +while [ ${#} -gt 0 ] +do + a=${1} + shift + case "${a}" in + + -h|--help) + usage=y + break + ;; + + -i|--info) + info=y + ;; + + -d|--dups) + dups=y + inst=y + ;; + + -q|--query-deps) + query=y + ;; + + -s|--slot) + slot=y + ;; + + -f|--find-file) + ffind=y + inst=y + ;; + + -fp|--find-pattern) + ffind=y + fpat=y + inst=y + ;; + + -I|--installed) + inst=y + ;; + + -U|--uninstalled) + uninst=y + ;; + + -g|--group) + group=$1 + shift + ;; + + -l|--list) + list=y + inst=y + ;; + + -ct|--check-time|-tc|--time-check) + tcheck=y + inst=y + ;; + + -cm|--check-md5|-mc|--md5-check) + mcheck=y + inst=y + ;; + + -c|--check) + mcheck=y + tcheck=y + inst=y + ;; + + -v|--verbose) + let $((verb++)) + ;; + + -vv) + let $((verb++)) + let $((verb++)) + ;; + + -nc|--no-color|--nocolor|--no-colors|--nocolors) + nocolor=y + ;; + + -*) + echo -e ${CY}${PROG}${NO}:${YL} Invalid option ${RD}$a 1>&2 + usage=y + break + ;; + *) + if [ -n "${arg}" ]; then + echo -e ${CY}${PROG}: ${YL}Only one argument supported + usage=y + break + fi + arg=$a + ;; + + esac +done + +#This is a dumb way to handle things, take it out next time +T="\t" + +#Set up colors +if [ ! "${nocolor}" ]; then + NO="\x1b[0;0m" + BR="\x1b[0;01m" + CY="\x1b[36;01m" + RD="\x1b[31;01m" + GR="\x1b[32;01m" + YL="\x1b[33;01m" + BL="\x1b[34;01m" + STAR=" *" +elif [ ! "${inst}" ] && [ ! "${uninst}" ]; then + STAR=" *" +fi + + +# check for option conflicts +if [ "${inst}" -a "${uninst}" \ + -o \( "${ffind}" -o "${list}" -o "${tcheck}" -o "${mcheck}" \) \ + -a "${uninst}" ]; then + echo -e ${CY}${PROG}${NO}:${YL} conflicting options/modes${NO} + usage=y +fi + +if [ "${usage}" ]; then + echo -e "${CY}${PROG} v. ${VERSION}${NO} + +${CY}${PROG}${NO} is GenToolKit's \"query package\" tool, using it, you can +find packages owning files on your filesystem, check the integrity +of installed packages, and do other queries against installed or +uninstalled packages. + +${BR}Usage: +${T}${CY}${PROG}${NO} [${BR}options${NO}] [${YL}pkgname${NO}] [${BL}-g${YL} group${NO}] [${BL}-f${YL} ${NO}|${BL}-fp${YL} ${NO}] +${T}${CY}${PROG}${NO} ${BL}--dups${NO} [${BL}--slot${NO}] +${T}${CY}${PROG}${NO} ${BL}--help${NO} + +${BR}Duplicate Locating: + ${BL}-d, --dups${NO}${T}${T}print packages that have multiple versions installed + ${BL}-s, --slot${NO}${T}${T}make ${BL}-d${NO} SLOT only print dups of the same SLOT + +${BR}Package Selection: + ${BL}-f, --find-file${NO}${T}finds package that owns file + ${BL}-fp, --find-pattern${NO}${T}finds to package that owns file matching ** + ${BL}-I, --installed${NO}${T}Include${YL} only${NO} installed packages + ${BL}-U, --uninstalled${NO}${T}Include${YL} only${NO} uninstalled packages + ${BL}-g, --group${NO}${T}${T}Find by goup (can be combined with other searches) + +${BR}Information Selection: + ${BL}-l, --list${NO}${T}${T}List package content + ${BL}-i, --info${NO}${T}${T}Get package description and home page. + ${BL}-ct, --check-time${NO} + ${BL}-tc, --time-check${NO}${T}Verify package files timestamps + ${BL}-cm, --check-md5${NO} + ${BL}-mc, --md5-check${NO}${T}Verify package files md5 + ${BL}-c, --check${NO}${T}${T}Verify mtimes${YL} and${NO} md5. + ${BL}-q, --query-deps${NO}${T}display all installed packages +${T}${T}${T}depending on selected packages + +${BR}Operation Modifiers: + ${BL}-nc, --no-color${NO}${T}don't use colors + ${BL}-v, --verbose${NO}${T}Be more verbose [ can be repeated twise ] + ${BL}-vv${NO}${T}${T}${T}Same as ${BL}-v -v${NO} + +${YL}Notes${NO}: +${YL}*${NO} ${BL}-f${NO}, ${BL}-fp, ${BL}-d${NO}, ${BL}-l${NO}, ${BL}-ct${NO}, ${BL}-cm${NO}, and ${BL}-c${NO} apply only to installed packages. +${YL}*${NO} Short options may not be combined on the command-line, yet. +${YL}*${NO} The operation of some flags has been changed by the + stripping of version numbers from some output to see + the version numbers play with ${BL}-v${NO} and ${BL}-vv${NO}. +${YL}*${NO} When using${BL} -f${NO} with ${BL}-l${NO} or ${BL}--check.. -v${NO} options, only + matching files will be displayed, unless ${BL}-v${NO} is doubled, + (yet more verbose) or ${BL}-vv${NO} is used. + + +${YL}Examples${NO}: + ${PROG} --dups print duplicates oldest first + ${PROG} --dups -v .. with versions + ${PROG} print list of installed packages + ${PROG} porta -I print versions of installed portage + ${PROG} porta -i .. + versions in portage tree + descriptions + and homepages + ${PROG} gawk -c -v check integrity all installed versions of gawk + the older will have \"damaged\" files. + ${PROG} -f /bin/ls print package(s) that own /bin/ls +" + exit +fi + +#For the --dups switch only +if [ "${dups}" ]; then + #First dig out the list of packages with duplicates + find /var/db/pkg -iname "*${arg}*.ebuild" 2> /dev/null > /tmp/qpkg.lst + dups=`cat /tmp/qpkg.lst | cut -f7 -d/ | + sed -e 's:\.ebuild$::; s:-r[0-9]*$::; s:-[^-]*$::; /^$/d' | + sort | + uniq -d` + + #Next get all the exact versions + duppak=`cat /tmp/qpkg.lst | fgrep "${dups}"` + + #Now cut that down to the directory name so we can be smart + dirs=`sed -e 's:/[^/]*$::' /tmp/qpkg.lst` + + #Go through each package's DB and create a sortable file + #to play with + declare -i defcount=`cat /var/cache/edb/counter` + for DIR in ${dirs} + do #Package COUNTER + NUM=`cat "${DIR}/COUNTER" 2> /dev/null` + [ -z "${NUM}" ] && NUM=defcount + #Package slot if requested + [ ${slot} ] && SLOT=`cat "${DIR}/SLOT"` + #Package fullname + PKG=`ls --color=no -1 ${DIR}/*.ebuild|cut -f5,7 -d"/"` + #Package basename + NAME=`echo "${PKG}"|sed -e 's:\.ebuild$::; s:-r[0-9]\+$::; s:-[0-9].*$::'` + echo "${NUM} ${PKG} ${NAME}${SLOT}" + #Finish loop, and sort that nice sortable file based on + #installation order, and then based on package basename + #bash hates me so I decided to use a temp file + done |sort -t" " -k3 -k1g,2|uniq -D -f2 > /tmp/qpkg.lst + duppak=`cat /tmp/qpkg.lst` + rm /tmp/qpkg.lst + + #If max verbosity is set output with full path to each ebuild + if [ "${verb}" -gt 1 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:^:${BL}/var/db/pkg/${BR}:" \ + -e "s:\(/\)\([^/]*\)\(.ebuild\):\1${CY}\2${NO}\1\2\3:" + + #If normal verbosity output package group, package name and package version + elif [ "${verb}" -gt 0 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:\(^[^/]*/\)\(.*\)\(\.ebuild\):${BR}\1${CY}\2${NO}:" + + #Otherwise just output package group and package name + else + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:-r[0-9]\+$::" \ + -e "s:-[0-9].*$::" \ + -e "s:\(^[^/]*/\)\(.*\):${BR}\1${CY}\2${NO}:"|uniq + fi + exit +fi + +# get list of ebuilds to work on +if [ "${ffind}" ]; then + # file find mode - list all ebuilds for + # package/CONTENTS containing + if [ "${fpat}" ]; then + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -l "${arg}" \ + | xargs --no-run-if-empty -n 1 dirname` + else + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -l " ${arg}\( .*\)*$" \ + | xargs --no-run-if-empty -n 1 dirname` + fi + ipak=`( + for d in ${dirs} -;do + [ "-" = "$d" ] && break + ls ${d}/*.ebuild + done)` +else + # normal mode - list ebuilds for ebuild name containing + + # installed packages + if [ ! "${uninst}" ]; then + ipak=`find /var/db/pkg/ -iname "*.ebuild" 2>/dev/null` + if [[ ${group} != "*" ]]; then + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${arg}` + fi + fi + # not installed packages (yet:-) + if [ ! "${inst}" ]; then + upak=`find /usr/portage/ -iname "*.ebuild" 2>/dev/null|grep -v --regex="/usr/portage/[^/]*\.ebuild"` + if [[ ${group} != "*" ]]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${arg}` + fi + fi +fi + +X="\([^/]*\)" + +for p in ${ipak} ${upak} -;do + [ "${p}" = "-" ] && break + + # cut common prefix from ebuild name and mark installed/uninstalled packages + # Note: iii/uuu will be replaced by the pipe at the end + n=`echo $p | sed -e "s:^/var/db/pkg/${X}/${X}/${X}.ebuild:iii \1/\3:" \ + -e "s:^/usr/portage/${X}/${X}/${X}\.ebuild:uuu \1/\3:"` + d=`dirname ${p}` + echo ${n} + if [ ${verb} -gt 1 ];then + echo "vvv ${p}" + fi + + if [ "${info}" ]; then + home=`grep HOMEPAGE ${p}| cut -d\" -f2` + desc=`grep DESCRIPTION ${p}| cut -d\" -f2` + echo -e "${T}${BL}${desc}${NO} [ ${YL}${home}${NO} ]" + fi + + if [ "${query}" ]; then + echo -e "${BL}DEPENDED ON BY:${NO}" + package="`echo ${n}|sed -e 's:-r[0-9]\+$::' \ + -e 's:-[0-9].*$::' \ + -e 's:^iii ::' \ + -e 's:^uuu ::'`" + place="`echo ${n}|cut -f1 -d' '`" + [[ "${place}" == "iii" ]] && color="${GR}" || color="${RD}" + grep -R "${package}" /var/db/pkg/*/*/RDEPEND | \ + cut -f5,6 -d"/" | sed -e "s:^:\t${color}:;s:$:${NO}:" | sort | uniq +# gawk -F "/" '{printf("${place}\n\t%s/%s${NO}",$5,$6)}' | sort | uniq + fi + + # cat package content, remove obj/sym/dir, md5 and mtime when not verbose + # display only match in file-find mode unless extra verbose + if [ "${list}" ]; then + echo -e ${BL}CONTENTS:${NO} + + if [ ${verb} -gt 1 ]; then + cat ${d}/CONTENTS + else + if [ "${ffind}" ]; then + if [ "${fpat}" ]; then + grep "${arg}" $d/CONTENTS + else + grep " ${arg}\( .*\)*$" $d/CONTENTS + fi + else + cat $d/CONTENTS + fi | + if [ ${verb} -gt 0 ]; then + cat + else + sed -e "s:\(^obj \)\([^ ]*\)\(.*$\):\1${BR}\2${NO}:; + s:\(^sym \)\([^ ]*\)\( -> \)\([^ ]*\)\(.*$\):\1${CY}\2${NO}\3\4:; + s:\(^dir \)\([^ ]*\)\(.*$\):\1${YL}\2${NO}:" + fi + fi + + echo + + # check files mtime and md5, display summary at the end + elif [ "${tcheck}" -o "${mcheck}" ]; then + # counters + fe=0 + fs=0 + # read the CONTENTS file and check md5 and mtime if needed + # process only matching files in find-file mode unless extra verbose + cat ${d}/CONTENTS | + if [ "${ffind}" -a ${verb} -lt 2 ];then + if [ "${fpat}" ]; then + grep "${arg}" + else + grep " ${arg} " + fi + else + cat + fi | + ( + while read -a line + do + fs=$((fs + 1)) + + unset md5 + unset _md5 + unset mtime + unset _mtime + unset err + + name=${line[1]} + + missing= + [ ! -e ${name} ] && missing=1 + + # colorize name and compute mtime/md5 + if [ "obj" = ${line[0]} ]; then + [ -e ${name} ] && { + [ "${tcheck}" ] && mtime=${line[3]} + [ "${tcheck}" ] && _mtime=`date -r ${name} +%s` + + [ "${mcheck}" ] && md5=${line[2]} + [ "${mcheck}" ] && _md5=`md5sum ${name}|cut -f1 -d" "` + } + + name=${BR}${name}${NO} + + elif [ "sym" = ${line[0]} ]; then + name=${CY}${name}${NO} + + elif [ "dir" = ${line[0]} ]; then + name=${YL}${name}${NO} + fi + + # compare + if [ "$missing" ]; then + err=1 + name="${name} ${RD}!not exist!${NO}" + fi + if [ "${md5}" != "${_md5}" ]; then + #If the md5 fails the first time check it with + #everything changed to lowercase :-D + md5=`echo "${md5}"|tr A-Z a-z` + if [ "${md5}" != "${_md5}" ]; then + err=1 + name="${name} ${RD}!md5!${NO}" + fi + fi + if [ "${mtime}" != "${_mtime}" ]; then + err=1 + name="${name} ${RD}!mtime!${NO}" + fi + + [ ${verb} -gt 1 ] && echo -e ${name} + [[ ${verb} -eq 1 ]] && [[ $err -eq 1 ]] && echo -e ${name} + + fe=$((fe + err)) + done + if [ "$fe" = "0" ]; then + echo -e ${YL}$fe${CY}/$fs${NO} + else + echo -e ${RD}$fe${CY}/$fs${NO} + fi + echo + ) + fi + +done | ( + if [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o ${verb} -gt 0 \) ]; then + sed -e "s:-r[0-9]\+$::" -e "s:-[0-9][^-]*$::"|sort -k2|uniq -1 + elif [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o ${verb} -lt 2 \) ]; then + sort -k2|uniq -1 + else + cat + fi | sed \ + -e "s:^iii ${X}/${X}:${BR}\1/${CY}\2${STAR}${NO}:" \ + -e "s:^uuu ${X}/${X}:${BR}\1/${YL}\2${NO}:" \ + -e "s:^vvv \(.*\)$:${BL}\1${NO}:" \ + -e "s:^obj ::;s:^sym ::;s:^dir ::" + +) diff --git a/trunk/src/qpkg/qpkg.1 b/trunk/src/qpkg/qpkg.1 new file mode 100644 index 0000000..b9803b7 --- /dev/null +++ b/trunk/src/qpkg/qpkg.1 @@ -0,0 +1,110 @@ +.TH "qpkg" "1" "1.6" "gentoolkit 0.1.11-r1" "" +.SH "NAME" +qpkg \- the "query package" tool for Gentoo Linux +.SH "SYNOPSIS" +.LP +.B qpkg\fR [\fIoptions\fR] [\fIpkgname\fR] [\fI\-g group\fR] +.br + [\fI\-f \fR|\fI\-fp \fR] +.TP +.B qpkg \fI\-\-dups\fR [\fI\-\-slot\fR] +.TP +.B qpkg \fI\-\-help\fR +.SH "DESCRIPTION" +qpkg is GenToolKit's "query package" tool, using it, you can find packages owning files on your filesystem, check the integrity of installed packages, and do other queries against installed or uninstalled packages. +.SH "OPTIONS " +.LP +.I Duplicate Locating: +.LP +.B \-d, \-\-dups\fR print packages that have multiple +.br + versions installed +.br +.B \-s, \-\-slot\fR make \-d SLOT only print dups of the +.br + same SLOT +.LP +.I Package Selection: +.LP +.B \-f, \-\-find\-file\fR Finds package that owns file +.br +.B \-fp, \-\-find\-pattern\fR Finds to package that owns file +.br + matching ** +.br +.B \-I, \-\-installed\fR Include only installed packages +.br +.B \-U, \-\-uninstalled\fR Include only uninstalled packages +.br +.B \-g, \-\-group\fR Find by goup (can be combined with +.br + other searches) +.LP +.I Information Selection: +.LP +.B \-l, \-\-list\fR List package content +.br +.B \-i, \-\-info\fR Get package description and home page. +.br +.B \-ct, \-\-check\-time +.br +.B \-tc, \-\-time\-check\fR Verify package files timestamps +.br +.B \-cm, \-\-check\-md5 +.br +.B \-mc, \-\-md5\-check\fR Verify package files md5 +.br +.B \-c, \-\-check\fR Verify mtimes and md5. +.br +.B \-q, \-\-query\-deps\fR display all installed packages +.br +\fR depending on selected packages +.LP +.I Operation Modifiers: +.LP +.B \-nc, \-\-no\-color\fR Don't use colors +.br +.B \-v, \-\-verbose\fR Be more verbose [2 levels] +.br +.B \-vv\fR Same as \-v \-v +.SH "NOTES" +\fI\-f, \-fp, \-d, \-l, \-ct, \-cm, \fRand \fI\-c\fR apply only to installed packages. +.br +.TP +Short options may not be combined on the command\-line, yet. +.TP +The operation of some flags has been changed in version 1.6 by the stripping of version numbers from some output to see the version numbers play with \fI\-v\fR and \fI\-vv\fR. +.TP +When using \fI\-f\fR with \fI\-l\fR or \fI\-\-check.. \-v\fR options, only matching files will be displayed, unless \fI\-v\fR is doubled, (yet more verbose), equivalent to \fI\-vv\fR. +.SH "EXAMPLES" +.LP +.B qpkg \fI\-\-dups\fR print duplicates oldest first +.br +.B qpkg \fI\-\-dups \-v\fR.. with versions +.br +.B qpkg\fR print list of packages +.br +.B qpkg\fR porta \fI\-I\fR print versions of installed portage +.br +.B qpkg porta \fI\-i\fR .. + versions in portage tree + +.br + descriptions and homepages +.br +.B qpkg gawk \fI\-c \-v\fR check integrity all installed versions +.br + of gawk the older versions will have +.br + "damaged" files. +.br +.B qpkg \fI\-f\fR /bin/ls print package(s) that own /bin/ls +.SH "AUTHORS" +Vitaly Kushneriuk , 2002: qpkg +.br +Karl Trygve Kalleberg , 2002: man page +.br +Brandon Low , 2002: maintainance +.SH "SEE ALSO" +ebuild(5) +.TP +The \fI/usr/sbin/qpkg\fR script. +.TP diff --git a/trunk/src/useflag/AUTHORS b/trunk/src/useflag/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/useflag/ChangeLog b/trunk/src/useflag/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/useflag/README b/trunk/src/useflag/README new file mode 100644 index 0000000..e69de29 diff --git a/trunk/src/useflag/useflag b/trunk/src/useflag/useflag new file mode 100644 index 0000000..fd4cc08 --- /dev/null +++ b/trunk/src/useflag/useflag @@ -0,0 +1,610 @@ +#!/bin/bash +# useflag v0.3.1 +# Script to help users manage USE flags in Gentoo Linux +# +# Distributed under the terms of the GNU General Public License, v2 or later +# Author: Michael Thompson , (c) 2002 + +run_name=`basename $0` +use_desc="/usr/portage/profiles/use.desc" +make_conf_dir="/etc" +make_conf="${make_conf_dir}/make.conf" +# Home directory was chosen as the use of /tmp allows for symlink attacks +make_temp="${HOME}/use.make.conf.tmp" +use_cache_parent="/var/cache" +use_cache_dir="${use_cache_parent}/use_desc" +use_cache="${use_cache_dir}/use.cache" +lock_cache="${use_cache_dir}/lock.cache" +changes="0" + + +# Get flag description +# parm1 = Use flag to get description of +do_get_desc() { + local parm1=$1 + # Strip the comments and find the flag. + local out_get_desc=`grep -v "#" ${use_desc} | grep -w -e "${parm1} -"` + if [ "${out_get_desc}" = "" ]; then + local lcl_avail=`grep -v "#" ${use_desc} | cut -d ' ' -f1 | \ + grep -w -e "${parm1}"` + if [ "${lcl_avail}" != "" ]; then + echo "${parm1} - No description available." + else + echo "!!! ${parm1} does not exist." + fi + else + echo "${out_get_desc}" + fi +} + +# Get the contents of the USE variable +# parm1 controls whether or not to include the '-' with each flag +do_get_make() { + local parm1=$1 + # Get the USE flags from make.conf + # using `source` now instead of brain-damaged grepping + source ${make_conf} + local get_make_out=${USE} + # If called with "nodashes", then strip the leading dashes + if [ "${parm1}" = "nodashes" ]; then + for tr_sucks in ${get_make_out}; do + if [ "${tr_sucks:0:1}" = "-" ]; then + local tr_out="${tr_out} ${tr_sucks:1}" + else + local tr_out="${tr_out} ${tr_sucks}" + fi + done + get_make_out="${tr_out}" + fi + echo "${get_make_out}" +} + +# Yes, it's pointless. But it could be used more than once in the future +# so it's a function. +# Gets the master list of available USE flags from use.desc +do_get_avail() { + grep -v "#" ${use_desc} | cut -d " " -f1 | tr '\n' ' ' +} + +# Get deprecated flags. +# parm1 = flag to check for deprecation +# parm2 = list of available flags +do_get_depr() { + local parm1=$1 + local parm2=${@:2} + # This next var can't be local + get_depr_tmp=`echo "${parm2}" | tr ' ' '\n' | grep -x -e "${parm1}"` + local ret_code=$? + if [ "${ret_code}" != "0" ]; then + echo "${parm1}" | tr '\n' ' ' + fi +} + +# Removes a USE flag from make.conf +# parm1 = flag to remove +# use_rm_out = list of available flags +do_use_rm() { + local parm1=$1 + local use_rm_out=${@:2} + # Strip matching USE flags. Yes, this is ugly, I know. + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "${parm1}" | tr '\n' ' '` + # Also strip the inverse. Even uglier... + if [ "${parm1:0:1}" = "-" ]; then + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "${parm1:1}" | tr '\n' ' '` + else + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "-${parm1}" | tr '\n' ' '` + fi + echo "${use_rm_out}" +} + +# Adds a USE flag to make.conf +# parm1 = flag to add +# use_add_out = list of available flags +do_use_add() { + local parm1=$1 + local use_add_out=${@:2} + # First strip existing flags (matching or inverse), then add. + # This is not the best way to do this. Better would be to replace a + # flag if it already exists. That turned out to be a real PITA. + # Maybe in a later version... + use_add_out=`do_use_rm ${parm1} ${use_add_out}` + use_add_out="${use_add_out} ${parm1}" + echo "${use_add_out}" +} + +# Adds a flag to the locked flag cache +# Pass list of flags to lock as parameter. +do_lock_flags() { + local flag_list=$@ + # Merge the new list of flags flags that are already locked. + if [ -r ${lock_cache} ]; then + local lock_old=`cat ${lock_cache}` + fi + flag_list="${lock_old} ${flag_list}" + # Remove duplicates. + echo "${flag_list}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ' +} + +# Writes the list of locked flags to the cache file +# Pass list of flags to write as parameter. +do_write_lock() { + local write_flags=$@ + if [ -r ${make_conf} ]; then + local make_prune=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + # Be sure and remove any locked flags that no longer exist in USE. + for prune in ${write_flags}; do + local prune_test=`do_get_depr ${prune} ${make_prune}` + if [ "$prune_test" = "" ]; then + local new_cache="${prune} ${new_cache}" + fi + done + if [ -w ${use_cache_parent} ]; then + mkdir -p ${use_cache_dir} + chmod 700 ${use_cache_dir} + echo "${new_cache}" > ${lock_cache} + chmod 600 ${lock_cache} + else + do_report_err ${lock_cache} write + fi +} + +# Writes new USE variable to make.conf +# Pass new list of USE flags as parameter. +do_write_make() { + local use_write="USE=\"$@\"" + local old_use="USE=\"`do_get_make dashes`\"" + if [ -w ${make_conf} ] && [ -w ${make_conf_dir} ]; then + local use_write="USE=\"$@\"" + local old_use=`grep "USE=\"" ${make_conf} | grep -v "#"` + local start_line=`grep -n "USE=\"" ${make_conf} | \ + grep -v "#" | cut -d ":" -f1` + if [ "${old_use:0-1}" != "\\" ]; then + sed -e "s/${old_use}/${use_write}/" ${make_conf} > \ + ${make_temp} + else + sed -e "s/${old_use}\\/${use_write}/" ${make_conf} > \ + ${make_temp} + fi + let start_line="${start_line} + 1" + if [ "${old_use:0-1}" != "\"" ]; then + del_line=`head -n ${start_line} ${make_temp} | \ + tail -n 1` + until [ "${del_line:0-1}" != "\\" ]; do + let del_length="${#del_line} - 1" + del_line="${del_line:0:${del_length}}" + grep -v -w "${del_line}" ${make_temp} > \ + ${make_temp}.2 + mv ${make_temp}.2 ${make_temp} + del_line=`head -n ${start_line} \ + ${make_temp} | tail -n 1` + done + let del_length="${#del_line} - 1" + del_line="${del_line:0:${del_length}}" + grep -v -x "${del_line}\"" ${make_temp} > \ + ${make_temp}.2 + mv ${make_temp}.2 ${make_temp} + fi + mv ${make_temp} ${make_conf} + else + do_report_err ${make_conf} write + fi +} + +# Reports a read/write error and exits +# parm1 = File to report on +# parm2 = read, write, etc +do_report_err() { + local parm1=$1 + local parm2=$2 + if [ "${parm2}" = "read" ]; then + echo "!!! Could not read ${parm1}" + echo -n "!!! Verify that file exists and that you have " + echo "appropriate permissions." + elif [ "${parm2}" = "write" ]; then + echo "!!! Could not write ${parm1}" + echo "!!! Got root?" + elif [ "${parm2}" = "nolock" ]; then + echo "!!! Could not read ${parm1}" + echo -n "!!! You have no locked flags or you have " + echo "insufficient permissions." + fi + exit 1 +} + + +# The main section of the script +# desc: +# This is the feature for getting USE descriptions. +if [ "$1" = "desc" ] || [ "$1" = "-i" ]; then + if [ -r ${use_desc} ]; then + for flag in ${@:2}; do + do_get_desc ${flag} + done + else + do_report_err ${use_desc} read + fi + +# show: +# This is the feature for showing the contents of the USE variable. +elif [ "$1" = "show" ] || [ "$1" = "-s" ]; then + if [ -r ${make_conf} ]; then + do_get_make dashes + else + do_report_err ${make_conf} read + fi + +# del: +# This is the feature for removing a USE flag. +elif [ "$1" = "del" ] || [ "$1" = "-d" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make dashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + del_test1=`do_get_depr ${flag} ${make_use}` + del_test2=`do_get_depr -${flag} ${make_use}` + if [ "${del_test1}" = "" ] || [ "${del_test2}" = "" ]; then + changes="1" + make_use=`do_use_rm ${flag} ${make_use}` + else + echo "!!! ${flag} is not in your USE variable." + fi + done + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + # Prune deleted USE flags from lock cache + lock_flags=`do_lock_flags $2` + do_write_lock ${lock_flags} + fi + +# add: +# This is the feature for explicitly enabling or disabling a USE flag. +elif [ "$1" = "add" ] || [ "$1" = "-a" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make dashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + changes="1" + make_use=`do_use_add ${flag} ${make_use}` + done + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + fi + +# lock: +# This is the feature to lock a deprecated USE flag to prevent removal +elif [ "$1" = "lock" ] || [ "$1" = "-l" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + lock_test=`do_get_depr ${flag} ${make_use}` + if [ "${lock_test}" = "" ]; then + lock_flags="${lock_flags} ${flag}" + else + echo "!!! ${flag} is not in your USE variable." + fi + done + lock_out=`do_lock_flags ${lock_flags}` + do_write_lock ${lock_out} + +# unlock: +# This is the feature to unlock a deprecated USE flag to allow removal +elif [ "$1" = "unlock" ] || [ "$1" = "-k" ]; then + if [ -r ${lock_cache} ]; then + lock_out=`cat ${lock_cache}` + else + do_report_err nolock + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + lock_flag_check=`do_get_depr ${flag} ${lock_out}` + if [ "${lock_flag_check}" = "" ]; then + lock_out=`do_use_rm ${flag} ${lock_out}` + else + echo "!!! ${flag} is not a locked flag." + fi + done + do_write_lock ${lock_out} + +# showlock: +# This feature prints a list of USE flags that have been locked +elif [ "$1" = "showlock" ] || [ "$1" = "-w" ]; then + if [ -r ${lock_cache} ]; then + cat ${lock_cache} + else + do_report_err nolock + fi + +# update: +# This is the feature to update your USE by removing deprecated flags and +# handling new flags. +elif [ "$1" = "update" ] || [ "$1" = "-u" ]; then + if [ -r ${make_conf} ]; then + # Get our USE but strip leading dashes + make_use=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + # Get available USE flags from use.desc + if [ -r ${use_desc} ]; then + use_avail=`do_get_avail` + else + do_report_err ${use_desc} read + fi + # First we check for deprecated flags. + echo "Your USE variable currently looks like this:" + echo + echo `do_get_make dashes` + echo + # Print the list of locked flags if any exist. + if [ -r ${lock_cache} ]; then + lock_test=`cat ${lock_cache} | tr -d ' '` + if [ "${lock_test}" != "" ]; then + echo "The following flags are locked:" + cat ${lock_cache} + echo + fi + fi + echo + echo "*** Checking for deprecated USE flags ..." + echo + for check_flag in ${make_use}; do + depr_ret=`do_get_depr ${check_flag} ${use_avail}` + flag_depr="${flag_depr}${depr_ret}" + done + # Filter out locked flags + if [ -r ${lock_cache} ] && [ "${lock_test}" != "" ]; then + lock_list=`cat ${lock_cache}` + for check_locks in ${flag_depr}; do + lock_ret=`do_get_depr ${check_locks} ${lock_list}` + lock_out="${lock_out}${lock_ret}" + done + flag_depr="${lock_out}" + fi + make_use=`do_get_make dashes` + if [ "${flag_depr}" = "" ]; then + echo "!!! No deprecated flags were found." + else + echo "The following USE flags appear to be deprecated:" + echo "${flag_depr}" + echo + echo "How would you like to handle them?" + echo "1) Handle them individually" + echo "2) Remove all deprecated flags" + echo "3) Don't remove any deprecated flags" + echo "4) Lock all deprecated flags" + echo + echo -n "Type (1, 2, 3, or 4): " + while [ "${luser_input}" = "" ]; do + read luser_input + case ${luser_input} in + "2") + changes="1" + for flag in ${flag_depr}; do + make_use=`do_use_rm \ + ${flag} ${make_use}` + done + echo + echo -n "*** All deprecated flags were " + echo "removed." + ;; + "3") + echo + echo "*** No flags were removed." + ;; + "1") + for flag in ${flag_depr}; do + echo -n "${flag} appears to be " + echo -n "deprecated. Remove it? " + echo -n "[Y]es/[N]o/[L]ock : " + luser_yn="" + while [ "${luser_yn}" = "" ]; do + read luser_yn + case ${luser_yn} in + "y" | "Y") + changes="1" + make_use=`do_use_rm \ + ${flag} \ + ${make_use}` + ;; + "n" | "N") + ;; + "l" | "L") + wlk="${flag} ${wlk}" + ;; + *) + luser_yn="" + ;; + esac + done + done + echo + echo -n "*** All deprecated flags " + echo "processed." + ;; + "4") + wlk="${flag_depr}" + echo + echo "*** All deprecated flags were locked." + ;; + *) + luser_input="" + ;; + esac + done + fi + if [ "${wlk}" != "" ]; then + do_write_lock ${wlk} + fi + # Now we check for new flags. + echo + echo + echo "*** Checking for new USE flags ..." + echo + # Load up our cached USE flags for comparison with use.desc + # Create the cache if it does not exist + if [ -w ${use_cache} ]; then + use_old=`cat ${use_cache}` + echo "${use_avail}" > ${use_cache} + chmod 600 ${use_cache} + elif [ -w ${use_cache_parent} ]; then + mkdir -p ${use_cache_dir} + chmod 700 ${use_cache_dir} + echo "${use_avail}" > ${use_cache} + chmod 600 ${use_cache} + use_old="" + else + do_report_err ${use_cache} write + fi + # Grab the contents of the USE variable. + make_cand=`do_get_make nodashes` + # Build a list of flags that do not exist in the USE variable. + for flag in ${use_avail}; do + new_cand="${new_cand}`do_get_depr ${flag} ${make_cand}`" + done + # Filter that list through the cached master list of flags. + for flag in ${new_cand}; do + new_flags="${new_flags}`do_get_depr ${flag} ${use_old}`" + done + if [ "${new_flags}" = "" ]; then + echo "!!! No new USE flags are available." + else + echo "The following new USE flags are available:" + echo "${new_flags}" + echo + echo "How would you like to handle them?" + echo "1) Handle them individually" + echo "2) Use Portage defaults (do not add to USE)" + echo "3) Explicitly enable all new flags" + echo "4) Explicitly disable all new flags" + echo + echo -n "Type (1, 2, 3, or 4): " + luser_input="" + while [ "${luser_input}" = "" ]; do + read luser_input + case ${luser_input} in + "1") + for h_flag in ${new_flags}; do + do_get_desc ${h_flag} + echo -n "How would you like to handle " + echo -n "${h_flag}? [e]nable, " + echo -n "[d]isable, [u]se default : " + luser_handle="" + while [ "${luser_handle}" = "" ]; do + read luser_handle + case ${luser_handle} in + "e" | "E") + changes="1" + make_use=`do_use_add \ + ${h_flag} \ + ${make_use}` + echo + ;; + "d" | "D") + changes="1" + make_use=`do_use_add \ + "-${h_flag}" \ + ${make_use}` + echo + ;; + "u" | "U") + echo + ;; + *) + luser_handle="" + ;; + esac + done + done + echo -n "*** All new flags have been " + echo "processed." + ;; + "2") + echo + echo -n "*** No new flags were added to " + echo "your USE." + ;; + "3") + changes="1" + for h_flag in ${new_flags}; do + make_use=`do_use_add ${h_flag} \ + ${make_use}` + done + echo + echo -n "*** All new flags were enabled in " + echo "your USE." + ;; + "4") + changes="1" + for h_flag in ${new_flags}; do + make_use=`do_use_add \ + "-${h_flag}" ${make_use}` + done + echo + echo -n "*** All new flags were disabled in " + echo "your USE." + ;; + *) + luser_input="" + ;; + esac + done + fi + # Write the changes if necessary. + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + # Prune any locked flags that do not exist in the USE variable + lock_prot=`do_lock_flags fakeflag` + do_write_lock ${lock_prot} + fi + echo + echo + echo "*** Script finished ..." + +# Display USAGE statement for unhandled parameters +else + echo "Usage:" + echo " ${run_name} action [flag] [...]" + echo + echo "Actions:" + echo "-s, show Displays the contents of the USE variable." + echo "-i, desc Displays a description of one or more USE flags." + echo -n "-a, add Adds the specified flag(s) to the USE " + echo "variable." + echo -n "-d, del Deletes the specified flag(s) from " + echo "the USE variable." + echo "-l, lock Locks the specified flag(s) to prevent deprecation." + echo -n "-k, unlock Unlocks the specified flags to allow " + echo "deprecation." + echo "-w, showlock Displays a list of locked flags." + echo -n "-u, update Interactively updates the USE variable to " + echo "reflect changes" + echo " to use.desc." + echo + exit 1 +fi +exit 0 + diff --git a/trunk/src/useflag/useflag.1 b/trunk/src/useflag/useflag.1 new file mode 100644 index 0000000..d321861 --- /dev/null +++ b/trunk/src/useflag/useflag.1 @@ -0,0 +1,69 @@ +.TH useflag "1" "May 2002" "gentoolkit" +.SH NAME +useflag \- manage and update Gentoo Linux USE flags +.SH SYNOPSIS +.B useflag +\fIaction\fR [\fIflag\fR] [\fI...\fR] +.SH DESCRIPTION +The \fBuseflag\fR utility allows the user to manage Gentoo Linux USE flags through a simple command-line interface. It allows quick and easy, single-command manipulation of the USE variable defined in \fI/etc/make.conf\fR. It also simplifies the process of handling changes to the master list of USE flags defined in \fI/usr/portage/profile/use.desc\fR. +.br + +It is important to note that a USE variable must exist in \fImake.conf\fR for this utility to work. Be sure that the USE variable is uncommented. It is OK for the USE variable to be empty. Please be sure to back up \fImake.conf\fR before using this utility for the first time. +.PP +.SH ACTIONS +.TP +\fBshow, -s\fR +Displays the raw contents of the USE variable as defined in \fImake.conf\fR. The output contains only the flags themselves. +.TP +\fBdesc, -i [flag] ...\fR +Displays a description of one or more USE flags specified on the command line. The flags should be seperated by spaces and should not contain leading dashes. Specifying a flag that does not exist returns a non-fatal error. +.TP +\fBadd, -a [[\-]flag] ...\fR +Adds one or more specified flags to the USE variable defined in \fImake.conf\fR. The flags are appended to the USE variable exactly as they appear on the command line. If a specified flag already exists in the USE variable, it is removed before the new set of flags is appended. The utility removes existing flags regardless of whether they are in an enabled or disabled state, allowing the user to enable or disable a flag with a single command. The user may add flags that are not defined in the \fIuse.desc\fR master list. +.TP +\fBdel, -d [flag] ...\fR +Deletes one or more specified flags from the USE variable defined in \fImake.conf\fR. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored. Attempting to delete a flag that is not in the USE variable returns a non-fatal error. When a flag is deleted from the USE variable using this utility, it is automatically unlocked. +.TP +\fBlock, -l [flag] ...\fR +Locks one or more specified flags that exist in the USE variable defined in \fImake.conf\fR. Locked flags are not considered to be deprecated by the update function of this utility. This allows the user to avoid being queried by the utility about deprecated, undocumented, or custom flags that the user wishes to preserve when performing an update. A flag must exist in the USE variable in order to be locked. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored. +.TP +\fBunlock, -k [flag] ...\fR +Unlocks one or more specified USE flags. This allows the update function to consider a flag deprecated if it no longer exists in the master list defined in \fIuse.desc\fR. Any dashes prepended to flags on the command line are ignored. Attempting to unlock flags that are not locked returns a non-fatal error. +.TP +\fBshowlock, -w\fR +Displays the raw list of locked flags, seperated by spaces. +.TP +\fBupdate, -u\fR +Interactively updates the USE variable defined in \fImake.conf\fR to reflect changes to the master list of USE flags defined in \fI use.desc\fR. +.br + +First, the user is presented with the current raw contents of the USE variable. The user is also shown the list of locked flags if any exist. +.br + +Next, the USE variable is searched for flags that do not appear in the master list. If any are found and they are not locked, then they are considered to be deprecated and are displayed to the user along with a list of options for handling them. The user may choose to remove all of the flags, remove none of the flags, lock all of the flags, or handle each flag individually. +.br + +Last, the master list is searched for any new flags that have become available since the last time the update function was run, and these are displayed to the user. If this is the first time, then all flags not currently defined in the USE variable will be displayed. The user will then be presented with a list of options for handling these flags. The user may choose to add all of the new flags to the USE variable as enabled, add all of the new flags as disabled, use Portage defaults for all of the flags, or handle each flag individually. +.SH FILES +.TP +\fI/etc/make.conf\fR +Contains the USE variable that Portage uses to control build-time functionality. +.TP +\fI/usr/portage/profile/use.desc\fR +Contains a master list of all documented USE flags along with their descriptions. +.TP +\fI/var/cache/use_desc/use.cache\fR +Contains a cached list of flags from \fIuse.desc\fR. This prevents the user from being repeatedly queried about flags that exist in \fIuse.desc\fR but not in the USE variable. DO NOT EDIT THIS FILE MANUALLY. +.TP +\fI/var/cache/use_desc/lock.cache\fR +Contains a list of USE flags that have been locked. DO NOT EDIT THIS FILE MANUALLY. +.SH AUTHOR +Michael Thompson , 2002 +.SH SEE ALSO +ebuild(1), ebuild(5), emerge(1), make.conf(5). +.TP +See \fI/usr/share/doc/gentoolkit-/\fR for documentation on other gentoolkit utilities. +.SH TIPS +.TP +Deleting \fI/var/cache/use_desc/use.cache\fR will allow the utility to query about all flags not currently defined in the USE variable. + -- 2.26.2