From: Jose V Beneyto Date: Tue, 13 Aug 2013 19:00:23 +0000 (+0000) Subject: Removed old src directory X-Git-Url: http://gitweb/?a=commitdiff_plain;h=b2b54f4619f440639e1d5a97eb533aa427132f92;p=pkgutils-cross.git Removed old src directory --- diff --git a/src/COPYING b/src/COPYING deleted file mode 100644 index 96e4591..0000000 --- a/src/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - 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 - - Appendix: 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., 675 Mass Ave, Cambridge, MA 02139, 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/src/Makefile b/src/Makefile deleted file mode 100644 index 023d6c2..0000000 --- a/src/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -# -# pkgutils -# -# Copyright (c) 2000-2005 by Per Liden -# Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -# -# 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. -# - -DESTDIR = -BINDIR = /usr/bin -MANDIR = /usr/man -ETCDIR = /etc - -VERSION = 5.35.2 -NAME = pkgutils-$(VERSION) - -CXXFLAGS += -DNDEBUG -CXXFLAGS += -O2 -Wall -pedantic -D_GNU_SOURCE -DVERSION=\"$(VERSION)\" \ - -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 - -LIBARCHIVELIBS := $(shell pkg-config --libs --static libarchive) - -LDFLAGS += -static $(LIBARCHIVELIBS) - -OBJECTS = main.o pkgutil.o pkgadd.o pkgrm.o pkginfo.o - -MANPAGES = pkgadd.8 pkgrm.8 pkginfo.8 pkgmk.8 rejmerge.8 pkgmk.conf.5 - -all: pkgadd pkgmk rejmerge man - -pkgadd: .depend $(OBJECTS) - $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) - -pkgmk: pkgmk.in - -rejmerge: rejmerge.in - -man: $(MANPAGES) - -mantxt: man $(MANPAGES:=.txt) - -%.8.txt: %.8 - nroff -mandoc -c $< | col -bx > $@ - -%: %.in - sed -e "s/#VERSION#/$(VERSION)/" $< > $@ - -.depend: - $(CXX) $(CXXFLAGS) -MM $(OBJECTS:.o=.cc) > .depend - -ifeq (.depend,$(wildcard .depend)) -include .depend -endif - -.PHONY: install clean distclean dist - -dist: distclean - rm -rf $(NAME) $(NAME).tar.gz - git archive --format=tar --prefix=$(NAME)/ HEAD | tar -x - git log > $(NAME)/ChangeLog - tar czvf $(NAME).tar.gz $(NAME) - rm -rf $(NAME) - -install: all - install -D -m0755 pkgadd $(DESTDIR)$(BINDIR)/pkgadd - install -D -m0644 pkgadd.conf $(DESTDIR)$(ETCDIR)/pkgadd.conf - install -D -m0755 pkgmk $(DESTDIR)$(BINDIR)/pkgmk - install -D -m0755 rejmerge $(DESTDIR)$(BINDIR)/rejmerge - install -D -m0644 pkgmk.conf $(DESTDIR)$(ETCDIR)/pkgmk.conf - install -D -m0644 rejmerge.conf $(DESTDIR)$(ETCDIR)/rejmerge.conf - install -D -m0644 pkgadd.8 $(DESTDIR)$(MANDIR)/man8/pkgadd.8 - install -D -m0644 pkgrm.8 $(DESTDIR)$(MANDIR)/man8/pkgrm.8 - install -D -m0644 pkginfo.8 $(DESTDIR)$(MANDIR)/man8/pkginfo.8 - install -D -m0644 pkgmk.8 $(DESTDIR)$(MANDIR)/man8/pkgmk.8 - install -D -m0644 rejmerge.8 $(DESTDIR)$(MANDIR)/man8/rejmerge.8 - install -D -m0644 pkgmk.conf.5 $(DESTDIR)$(MANDIR)/man5/pkgmk.conf.5 - ln -sf pkgadd $(DESTDIR)$(BINDIR)/pkgrm - ln -sf pkgadd $(DESTDIR)$(BINDIR)/pkginfo - -clean: - rm -f .depend - rm -f $(OBJECTS) - rm -f $(MANPAGES) - rm -f $(MANPAGES:=.txt) - -distclean: clean - rm -f pkgadd pkginfo pkgrm pkgmk rejmerge - -# End of file diff --git a/src/README b/src/README deleted file mode 100644 index 703a8ef..0000000 --- a/src/README +++ /dev/null @@ -1,28 +0,0 @@ - - pkgutils - Package Management Utilities - - http://www.fukt.bth.se/~per/pkgutils/ - - -Description ------------ -pkgutils is a set of utilities (pkgadd, pkgrm, pkginfo, pkgmk and rejmerge), -which are used for managing software packages in Linux. It is developed for -and used by the CRUX distribution (http://crux.nu). - - -Building and installing ------------------------ -$ make -$ make install -or -$ make DESTDIR=/some/other/path install - - -Copyright ---------- -pkgutils is Copyright (c) 2000-2005 Per Liden and -Copyright (c) 2006-2010 CRUX team (http://crux.nu). - -pkgutils is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/main.cc b/src/main.cc deleted file mode 100644 index 6897c8f..0000000 --- a/src/main.cc +++ /dev/null @@ -1,77 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#if (__GNUC__ < 3) -#error This program requires GCC 3.x to compile. -#endif - -#include -#include -#include -#include -#include -#include "pkgutil.h" -#include "pkgadd.h" -#include "pkgrm.h" -#include "pkginfo.h" - -using namespace std; - -static pkgutil* select_utility(const string& name) -{ - if (name == "pkgadd") - return new pkgadd; - else if (name == "pkgrm") - return new pkgrm; - else if (name == "pkginfo") - return new pkginfo; - else - throw runtime_error("command not supported by pkgutils"); -} - -int main(int argc, char** argv) -{ - string name = basename(argv[0]); - - try { - auto_ptr util(select_utility(name)); - - // Handle common options - for (int i = 1; i < argc; i++) { - string option(argv[i]); - if (option == "-v" || option == "--version") { - util->print_version(); - return EXIT_SUCCESS; - } else if (option == "-h" || option == "--help") { - util->print_help(); - return EXIT_SUCCESS; - } - } - - util->run(argc, argv); - } catch (runtime_error& e) { - cerr << name << ": " << e.what() << endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/src/pkgadd.8.in b/src/pkgadd.8.in deleted file mode 100644 index 34dcb52..0000000 --- a/src/pkgadd.8.in +++ /dev/null @@ -1,63 +0,0 @@ -.TH pkgadd 8 "" "pkgutils #VERSION#" "" -.SH NAME -pkgadd \- install software package -.SH SYNOPSIS -\fBpkgadd [options] \fP -.SH DESCRIPTION -\fBpkgadd\fP is a \fIpackage management\fP utility, which installs -a software package. A \fIpackage\fP is an archive of files (.pkg.tar.gz). -.SH OPTIONS -.TP -.B "\-u, \-\-upgrade" -Upgrade/replace package with the same name as . -.TP -.B "\-f, \-\-force" -Force installation, overwrite conflicting files. If the package -that is about to be installed contains files that are already -installed this option will cause all those files to be overwritten. -This option should be used with care, preferably not at all. -.TP -.B "\-r, \-\-root " -Specify alternative installation root (default is "/"). This -should \fInot\fP be used as a way to install software into -e.g. /usr/local instead of /usr. Instead this should be used -if you want to install a package on a temporary mounted partition, -which is "owned" by another system. By using this option you not only -specify where the software should be installed, but you also -specify which package database to use. -.TP -.B "\-v, \-\-version" -Print version and exit. -.TP -.B "\-h, \-\-help" -Print help and exit. -.SH CONFIGURATION -\fBpkgadd\fP is configured by the file \fI/etc/pkgadd.conf\fP. This file can contain rules, that are built out of three fragments: \fIevent\fP, \fIpattern\fP and \fIaction\fP. The event describes in what kind of situation this rule applies. Currently there are two types of events: \fBUPGRADE\fP and \fBINSTALL\fP. \fBUPGRADE\fP rules are applied when a package is installed over an existing version, and \fBINSTALL\fP rules are applied in any case. The pattern is a regular expression. The action applicable to both the \fBUPGRADE\fP and \fBINSTALL\fP event is \fBYES\fP and \fBNO\fP. More than one rule of the same -event type is allowed, in which case the first rule will have the lowest priority and the last rule -will have the highest priority. Example: - -.nf -UPGRADE ^etc/.*$ NO -UPGRADE ^var/log/.*$ NO -UPGRADE ^etc/X11/.*$ YES -UPGRADE ^etc/X11/XF86Config$ NO -.fi - -The above example will cause pkgadd to never upgrade anything in /etc/ or /var/log/ (subdirectories included), -except files in /etc/X11/ (subdirectories included), unless it is the file /etc/X11/XF86Config. -The default rule is to upgrade/install everything, rules in this file are exceptions to that rule. -(NOTE! A \fIpattern\fP should never contain an initial "/" since you are referring to the files in the -package, not the files on the disk.) - -If pkgadd finds that a specific file should not be upgraded it will install it under \fI/var/lib/pkg/rejected/\fP. -The user is then free to examine/use/remove that file manually. -.SH FILES -.TP -.B "/etc/pkgadd.conf" -Configuration file. -.SH SEE ALSO -pkgrm(8), pkginfo(8), pkgmk(8), rejmerge(8) -.SH COPYRIGHT -pkgadd (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -pkgadd (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/pkgadd.cc b/src/pkgadd.cc deleted file mode 100644 index a5721fe..0000000 --- a/src/pkgadd.cc +++ /dev/null @@ -1,278 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#include "pkgadd.h" -#include -#include -#include -#include -#include - -void pkgadd::run(int argc, char** argv) -{ - // - // Check command line options - // - string o_root; - string o_config; - string o_package; - bool o_upgrade = false; - bool o_force = false; - - for (int i = 1; i < argc; i++) { - string option(argv[i]); - if (option == "-r" || option == "--root") { - assert_argument(argv, argc, i); - o_root = argv[i + 1]; - i++; - } else if (option == "-c" || option == "--config") { - assert_argument(argv, argc, i); - o_config = argv[i + 1]; - i++; - } else if (option == "-u" || option == "--upgrade") { - o_upgrade = true; - } else if (option == "-f" || option == "--force") { - o_force = true; - } else if (option[0] == '-' || !o_package.empty()) { - throw runtime_error("invalid option " + option); - } else { - o_package = option; - } - } - - if (o_package.empty()) - throw runtime_error("option missing"); - - // - // Check UID - // - if (getuid()) - throw runtime_error("only root can install/upgrade packages"); - - // - // Install/upgrade package - // - { - db_lock lock(o_root, true); - db_open(o_root); - - pair package = pkg_open(o_package); - vector config_rules = read_config(o_config); - - bool installed = db_find_pkg(package.first); - if (installed && !o_upgrade) - throw runtime_error("package " + package.first + " already installed (use -u to upgrade)"); - else if (!installed && o_upgrade) - throw runtime_error("package " + package.first + " not previously installed (skip -u to install)"); - - set non_install_files = apply_install_rules(package.first, package.second, config_rules); - set conflicting_files = db_find_conflicts(package.first, package.second); - - if (!conflicting_files.empty()) { - if (o_force) { - set keep_list; - if (o_upgrade) // Don't remove files matching the rules in configuration - keep_list = make_keep_list(conflicting_files, config_rules); - db_rm_files(conflicting_files, keep_list); // Remove unwanted conflicts - } else { - copy(conflicting_files.begin(), conflicting_files.end(), ostream_iterator(cerr, "\n")); - throw runtime_error("listed file(s) already installed (use -f to ignore and overwrite)"); - } - } - - set keep_list; - - if (o_upgrade) { - keep_list = make_keep_list(package.second.files, config_rules); - db_rm_pkg(package.first, keep_list); - } - - db_add_pkg(package.first, package.second); - db_commit(); - pkg_install(o_package, keep_list, non_install_files); - ldconfig(); - } -} - -void pkgadd::print_help() const -{ - cout << "usage: " << utilname << " [options] " << endl - << "options:" << endl - << " -u, --upgrade upgrade package with the same name" << endl - << " -f, --force force install, overwrite conflicting files" << endl - << " -r, --root specify alternative installation root" << endl - << " -c, --config use alternate configuration file" << endl - << " -v, --version print version and exit" << endl - << " -h, --help print help and exit" << endl; -} - -vector pkgadd::read_config(string file) const -{ - vector rules; - unsigned int linecount = 0; - string filename = root + PKGADD_CONF; - - if (!file.empty()) filename = file; - ifstream in(filename.c_str()); - - if (in) { - while (!in.eof()) { - string line; - getline(in, line); - linecount++; - if (!line.empty() && line[0] != '#') { - if (line.length() >= PKGADD_CONF_MAXLINE) - throw runtime_error(filename + ":" + itos(linecount) + ": line too long, aborting"); - - char event[PKGADD_CONF_MAXLINE]; - char pattern[PKGADD_CONF_MAXLINE]; - char action[PKGADD_CONF_MAXLINE]; - char dummy[PKGADD_CONF_MAXLINE]; - if (sscanf(line.c_str(), "%s %s %s %s", event, pattern, action, dummy) != 3) - throw runtime_error(filename + ":" + itos(linecount) + ": wrong number of arguments, aborting"); - - if (!strcmp(event, "UPGRADE") || !strcmp(event, "INSTALL")) { - rule_t rule; - rule.event = strcmp(event, "UPGRADE") ? INSTALL : UPGRADE; - rule.pattern = pattern; - if (!strcmp(action, "YES")) { - rule.action = true; - } else if (!strcmp(action, "NO")) { - rule.action = false; - } else - throw runtime_error(filename + ":" + itos(linecount) + ": '" + - string(action) + "' unknown action, should be YES or NO, aborting"); - - rules.push_back(rule); - } else - throw runtime_error(filename + ":" + itos(linecount) + ": '" + - string(event) + "' unknown event, aborting"); - } - } - in.close(); - } - -#ifndef NDEBUG - cerr << "Configuration:" << endl; - for (vector::const_iterator j = rules.begin(); j != rules.end(); j++) { - cerr << "\t" << (*j).pattern << "\t" << (*j).action << endl; - } - cerr << endl; -#endif - - return rules; -} - -set pkgadd::make_keep_list(const set& files, const vector& rules) const -{ - set keep_list; - vector found; - - find_rules(rules, UPGRADE, found); - - for (set::const_iterator i = files.begin(); i != files.end(); i++) { - for (vector::reverse_iterator j = found.rbegin(); j != found.rend(); j++) { - if (rule_applies_to_file(*j, *i)) { - if (!(*j).action) - keep_list.insert(keep_list.end(), *i); - - break; - } - } - } - -#ifndef NDEBUG - cerr << "Keep list:" << endl; - for (set::const_iterator j = keep_list.begin(); j != keep_list.end(); j++) { - cerr << " " << (*j) << endl; - } - cerr << endl; -#endif - - return keep_list; -} - -set pkgadd::apply_install_rules(const string& name, pkginfo_t& info, const vector& rules) -{ - // TODO: better algo(?) - set install_set; - set non_install_set; - vector found; - - find_rules(rules, INSTALL, found); - - for (set::const_iterator i = info.files.begin(); i != info.files.end(); i++) { - bool install_file = true; - - for (vector::reverse_iterator j = found.rbegin(); j != found.rend(); j++) { - if (rule_applies_to_file(*j, *i)) { - install_file = (*j).action; - break; - } - } - - if (install_file) - install_set.insert(install_set.end(), *i); - else - non_install_set.insert(*i); - } - - info.files.clear(); - info.files = install_set; - -#ifndef NDEBUG - cerr << "Install set:" << endl; - for (set::iterator j = info.files.begin(); j != info.files.end(); j++) { - cerr << " " << (*j) << endl; - } - cerr << endl; - - cerr << "Non-Install set:" << endl; - for (set::iterator j = non_install_set.begin(); j != non_install_set.end(); j++) { - cerr << " " << (*j) << endl; - } - cerr << endl; -#endif - - return non_install_set; -} - -void pkgadd::find_rules(const vector& rules, rule_event_t event, vector& found) const -{ - for (vector::const_iterator i = rules.begin(); i != rules.end(); i++) - if (i->event == event) - found.push_back(*i); -} - -bool pkgadd::rule_applies_to_file(const rule_t& rule, const string& file) const -{ - regex_t preg; - bool ret; - - if (regcomp(&preg, rule.pattern.c_str(), REG_EXTENDED | REG_NOSUB)) - throw runtime_error("error compiling regular expression '" + rule.pattern + "', aborting"); - - ret = !regexec(&preg, file.c_str(), 0, 0, 0); - regfree(&preg); - - return ret; -} diff --git a/src/pkgadd.conf b/src/pkgadd.conf deleted file mode 100644 index 234f961..0000000 --- a/src/pkgadd.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# /etc/pkgadd.conf: pkgadd(8) configuration -# - -# Crosscompiling rules to avoid libtool issues -# with the hardcoded libdir variable -INSTALL .*\.la NO -UPGRADE .*\.la NO - -# Default rule (implicit) -#UPGRADE ^.*$ YES - -UPGRADE ^etc/.*$ NO -UPGRADE ^var/log/.*$ NO -UPGRADE ^var/spool/\w*cron/.*$ NO -UPGRADE ^var/run/utmp$ NO - -UPGRADE ^etc/ports/drivers/.*$ YES -UPGRADE ^etc/X11/.*$ YES - -UPGRADE ^etc/rc.*$ YES -UPGRADE ^etc/rc\.local$ NO -UPGRADE ^etc/rc\.modules$ NO -UPGRADE ^etc/rc\.conf$ NO -UPGRADE ^etc/rc\.d/net$ NO - -UPGRADE ^etc/udev/rules.d/.*$ YES -UPGRADE ^etc/udev/rules.d/1.*$ NO - -# End of file diff --git a/src/pkgadd.h b/src/pkgadd.h deleted file mode 100644 index e20561b..0000000 --- a/src/pkgadd.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2007 by CRUX team (http://crux.nu) -// -// 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. -// - -#ifndef PKGADD_H -#define PKGADD_H - -#include "pkgutil.h" -#include -#include - -#define PKGADD_CONF "/etc/pkgadd.conf" -#define PKGADD_CONF_MAXLINE 1024 - -enum rule_event_t { - UPGRADE, - INSTALL -}; - -struct rule_t { - rule_event_t event; - string pattern; - bool action; -}; - -class pkgadd : public pkgutil { -public: - pkgadd() : pkgutil("pkgadd") {} - virtual void run(int argc, char** argv); - virtual void print_help() const; - -private: - vector read_config(string file) const; - set make_keep_list(const set& files, const vector& rules) const; - set apply_install_rules(const string& name, pkginfo_t& info, const vector& rules); - void find_rules(const vector& rules, rule_event_t event, vector& found) const; - bool rule_applies_to_file(const rule_t& rule, const string& file) const; -}; - -#endif /* PKGADD_H */ diff --git a/src/pkginfo.8.in b/src/pkginfo.8.in deleted file mode 100644 index ee0da6c..0000000 --- a/src/pkginfo.8.in +++ /dev/null @@ -1,42 +0,0 @@ -.TH pkginfo 8 "" "pkgutils #VERSION#" "" -.SH NAME -pkginfo \- display software package information -.SH SYNOPSIS -\fBpkginfo [options]\fP -.SH DESCRIPTION -\fBpkginfo\fP is a \fIpackage management\fP utility, which displays -information about software packages that are installed on the system -or that reside in a particular directory. -.SH OPTIONS -.TP -.B "\-i, \-\-installed" -List installed packages and their version. -.TP -.B "\-l, \-\-list " -List files owned by the specified or contained in . -.TP -.B "\-o, \-\-owner " -List owner(s) of file(s) matching . -.TP -.B "\-f, \-\-footprint " -Print footprint for . This feature is mainly used by pkgmk(8) -for creating and comparing footprints. -.TP -.B "\-r, \-\-root " -Specify alternative installation root (default is "/"). This -should be used if you want to display information about a package -that is installed on a temporary mounted partition, which is "owned" -by another system. By using this option you specify which package -database to use. -.TP -.B "\-v, \-\-version" -Print version and exit. -.TP -.B "\-h, \-\-help" -Print help and exit. -.SH SEE ALSO -pkgadd(8), pkgrm(8), pkgmk(8), rejmerge(8) -.SH COPYRIGHT -pkginfo (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -pkginfo (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/pkginfo.cc b/src/pkginfo.cc deleted file mode 100644 index fb4d993..0000000 --- a/src/pkginfo.cc +++ /dev/null @@ -1,155 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#include "pkginfo.h" -#include -#include -#include -#include -#include - -void pkginfo::run(int argc, char** argv) -{ - // - // Check command line options - // - int o_footprint_mode = 0; - int o_installed_mode = 0; - int o_list_mode = 0; - int o_owner_mode = 0; - string o_root; - string o_arg; - - for (int i = 1; i < argc; ++i) { - string option(argv[i]); - if (option == "-r" || option == "--root") { - assert_argument(argv, argc, i); - o_root = argv[i + 1]; - i++; - } else if (option == "-i" || option == "--installed") { - o_installed_mode += 1; - } else if (option == "-l" || option == "--list") { - assert_argument(argv, argc, i); - o_list_mode += 1; - o_arg = argv[i + 1]; - i++; - } else if (option == "-o" || option == "--owner") { - assert_argument(argv, argc, i); - o_owner_mode += 1; - o_arg = argv[i + 1]; - i++; - } else if (option == "-f" || option == "--footprint") { - assert_argument(argv, argc, i); - o_footprint_mode += 1; - o_arg = argv[i + 1]; - i++; - } else { - throw runtime_error("invalid option " + option); - } - } - - if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode == 0) - throw runtime_error("option missing"); - - if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode > 1) - throw runtime_error("too many options"); - - if (o_footprint_mode) { - // - // Make footprint - // - pkg_footprint(o_arg); - } else { - // - // Modes that require the database to be opened - // - { - db_lock lock(o_root, false); - db_open(o_root); - } - - if (o_installed_mode) { - // - // List installed packages - // - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) - cout << i->first << ' ' << i->second.version << endl; - } else if (o_list_mode) { - // - // List package or file contents - // - if (db_find_pkg(o_arg)) { - copy(packages[o_arg].files.begin(), packages[o_arg].files.end(), ostream_iterator(cout, "\n")); - } else if (file_exists(o_arg)) { - pair package = pkg_open(o_arg); - copy(package.second.files.begin(), package.second.files.end(), ostream_iterator(cout, "\n")); - } else { - throw runtime_error(o_arg + " is neither an installed package nor a package file"); - } - } else { - // - // List owner(s) of file or directory - // - regex_t preg; - if (regcomp(&preg, o_arg.c_str(), REG_EXTENDED | REG_NOSUB)) - throw runtime_error("error compiling regular expression '" + o_arg + "', aborting"); - - vector > result; - result.push_back(pair("Package", "File")); - unsigned int width = result.begin()->first.length(); // Width of "Package" - - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) { - for (set::const_iterator j = i->second.files.begin(); j != i->second.files.end(); ++j) { - const string file('/' + *j); - if (!regexec(&preg, file.c_str(), 0, 0, 0)) { - result.push_back(pair(i->first, *j)); - if (i->first.length() > width) - width = i->first.length(); - } - } - } - - regfree(&preg); - - if (result.size() > 1) { - for (vector >::const_iterator i = result.begin(); i != result.end(); ++i) { - cout << left << setw(width + 2) << i->first << i->second << endl; - } - } else { - cout << utilname << ": no owner(s) found" << endl; - } - } - } -} - -void pkginfo::print_help() const -{ - cout << "usage: " << utilname << " [options]" << endl - << "options:" << endl - << " -i, --installed list installed packages" << endl - << " -l, --list list files in or " << endl - << " -o, --owner list owner(s) of file(s) matching " << endl - << " -f, --footprint print footprint for " << endl - << " -r, --root specify alternative installation root" << endl - << " -v, --version print version and exit" << endl - << " -h, --help print help and exit" << endl; -} diff --git a/src/pkginfo.h b/src/pkginfo.h deleted file mode 100644 index 8db95da..0000000 --- a/src/pkginfo.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#ifndef PKGINFO_H -#define PKGINFO_H - -#include "pkgutil.h" - -class pkginfo : public pkgutil { -public: - pkginfo() : pkgutil("pkginfo") {} - virtual void run(int argc, char** argv); - virtual void print_help() const; -}; - -#endif /* PKGINFO_H */ diff --git a/src/pkgmk.8.in b/src/pkgmk.8.in deleted file mode 100644 index b2043c2..0000000 --- a/src/pkgmk.8.in +++ /dev/null @@ -1,127 +0,0 @@ -.TH pkgmk 8 "" "pkgutils #VERSION#" "" -.SH NAME -pkgmk \- make software package -.SH SYNOPSIS -\fBpkgmk [options]\fP -.SH DESCRIPTION -\fBpkgmk\fP is a \fIpackage management\fP utility, which makes -a software package. A \fIpackage\fP is an archive of files (.pkg.tar.gz, .pkg.tar.bz2 or .pkg.tar.xz) -that can be installed using pkgadd(8). - -To prepare to use pkgmk, you must write a file named \fIPkgfile\fP -that describes how the package should be build. Once a suitable -\fIPkgfile\fP file exists, each time you change some source files, -you simply execute pkgmk to bring the package up to date. The pkgmk -program uses the \fIPkgfile\fP file and the last-modification -times of the source files to decide if the package needs to be updated. - -Global build configuration is stored in \fI/etc/pkgmk.conf\fP. This -file is read by pkgmk at startup. -.SH OPTIONS -.TP -.B "\-i, \-\-install" -Install package using pkgadd(8) after successful build. -.TP -.B "\-u, \-\-upgrade" -Install package as an upgrade using pkgadd(8) after successful build. -.TP -.B "\-r, \-\-recursive" -Search for and build packages recursively. -.TP -.B "\-d, \-\-download" -Download missing source file(s). -.TP -.B "\-do, \-\-download\-only" -Do not build, only download missing source file(s). -.TP -.B "\-utd, \-\-up\-to\-date" -Do not build, only check if the package is up to date. -.TP -.B "\-uf, \-\-update\-footprint" -Update footprint and treat last build as successful. -.TP -.B "\-if, \-\-ignore\-footprint" -Build package without checking footprint. -.TP -.B "\-in, \-\-ignore\-new" -Build package, ignore new files in a footprint mismatch. -.TP -.B "\-um, \-\-update\-md5sum" -Update md5sum using the current source files. -.TP -.B "\-im, \-\-ignore\-md5sum" -Build package without checking md5sum first. -.TP -.B "\-ns, \-\-no\-strip" -Do not strip executable binaries or libraries. -.TP -.B "\-f, \-\-force" -Build package even if it appears to be up to date. -.TP -.B "\-c, \-\-clean" -Remove the (previously built) package and the downloaded source files. -.TP -.B "\-kw, \-\-keep-work" -Keep temporary working directory. -.TP -.B "\-cf, \-\-config\-file " -Use alternative configuration file (default is /etc/pkgmk.conf). -.TP -.B "\-v, \-\-version" -Print version and exit. -.TP -.B "\-h, \-\-help" -Print help and exit. -.SH FILES -.TP -.B "Pkgfile" -Package build description. -.TP -.B ".footprint" -Package footprint (used for regression testing). -.TP -.B ".md5sum" -MD5 checksum of source files. -.TP -.B "/etc/pkgmk.conf" -Global package make configuration. -.TP -.B "wget" -Used by pkgmk to download source code. -.SH EXIT CODES -.TP -.B 0 -No error occured. -.TP -.B 1 -A general error has occured. -.TP -.B 2 -The Pkgfile is invalid. -.TP -.B 3 -The source or build directory is missing or is lacking read/write permissions. -.TP -.B 4 -An error occured during the download of source files. -.TP -.B 5 -An error occured during unpacking of source files. -.TP -.B 6 -An md5sum mismatch occured. -.TP -.B 7 -A footprint mismatch occured. -.TP -.B 8 -An error occured while running the build function. -.TP -.B 9 -An error occured while installing the package via pkgadd. -.SH SEE ALSO -pkgmk.conf(5), pkgadd(8), pkgrm(8), pkginfo(8), rejmerge(8), wget(1) -.SH COPYRIGHT -pkgmk (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -pkgmk (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/pkgmk.conf.5.in b/src/pkgmk.conf.5.in deleted file mode 100644 index f9f6908..0000000 --- a/src/pkgmk.conf.5.in +++ /dev/null @@ -1,75 +0,0 @@ -.TH pkgmk.conf 5 "" "pkgutils #VERSION#" "" -.SH NAME -\fBpkgmk.conf\fP \- Configuration file for pkgmk. -.SH DESCRIPTION -\fBpkgmk.conf\fP configures pkgutils package make, pkgmk(8). -.SH FILE FORMAT -The file consists of a number of variable assignments of the form \fBoption\fP=\fBvalue\fP. Comments can be specified by putting a hash (#) symbol as the first character on the line. -.SH DIRECTIVES -.LP -If some option is not used (commented out or not included in the configuration file at all) pkgmk will take a default action. -.TP -\fBexport CFLAGS='STRING'\fP -Set C compiler options. -.br -Default: none -.TP -\fBexport CXXFLAGS='STRING'\fP -Set C++ compiler options. -.br -Default: none -.TP -\fBPKGMK_SOURCE_MIRRORS=('STRING')\fP -Set mirrors to check and download source archives from. -.br -Default: none -.TP -\fBPKGMK_SOURCE_DIR='STRING'\fP -Set directory for downloaded source archives. -.br -Default: directory of Pkgfile. -.TP -\fBPKGMK_PACKAGE_DIR='STRING'\fR -Set directory for built packages. -.br -Default: directory of Pkgfile. -.TP -\fBPKGMK_WORK_DIR='STRING'\fP -Set directory for building packages. -.br -Default: '\fBfoo\fP/work', where \fBfoo\fP is the directory of the Pkgfile. -.TP -\fBPKGMK_WGET_OPTS='STRING'\fP -Additional options for wget(1), which is used by pkgmk to download all files. -.br -.TP -\fBPKGMK_DOWNLOAD='STRING'\fP -If set to 'yes', pkgmk will download the source archives if necessary. -.br -Default: 'no' -.TP -\fBPKGMK_IGNORE_FOOTPRINT='STRING'\fP -If set to 'yes', pkgmk will not perform a footprint check of the built package. -.br -Default: 'no' -.TP -\fBPKGMK_IGNORE_NEW='STRING'\fP -If set to 'yes', pkgmk will ignore new files in a footprint mismatch. -.br -Default: 'no' -.TP -\fBPKGMK_NO_STRIP='STRING'\fP -If set to 'no', pkgmk will strip built binaries. -.br -Default: 'no' -.TP -\fBPKGMK_COMPRESSION_MODE='STRING'\fP -Option to select the mode used to compress the packages. Valid strings are gz, bz2 and xz. -.br -Default: 'gz' -.SH SEE ALSO -pkgmk(8) -.SH COPYRIGHT -pkgmk (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -pkgmk (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/pkgmk.in b/src/pkgmk.in deleted file mode 100755 index ddce5e7..0000000 --- a/src/pkgmk.in +++ /dev/null @@ -1,751 +0,0 @@ -#!/bin/bash -# -# pkgutils -# -# Copyright (c) 2000-2005 Per Liden -# Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -# Patches for crosscompilation by Jose V Beneyto -# (CRUX-ARM System Team ) -# -# 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. -# - -## -# error codes -E_GENERAL=1 -E_PKGFILE=2 # invalid Pkgfile -E_DIR_PERM=3 # (source/build) directory missing or missing read/write permission -E_DOWNLOAD=4 # error during download -E_UNPACK=5 # error during unpacking of source file(s) -E_MD5=6 # md5sum verification failed -E_FOOTPRINT=7 # footprint check failure -E_BUILD=8 # error while running 'build()' -E_INSTALL=9 # error while installing the package via 'pkgadd' - -info() { - echo "=======> $1" -} - -warning() { - info "WARNING: $1" >&2 -} - -error() { - info "ERROR: $1" >&2 -} - -get_filename() { - if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then - echo "$PKGMK_SOURCE_DIR/${BASH_REMATCH[2]}" - else - echo $1 - fi -} - -get_basename() { - local FILE="`echo $1 | sed 's|^.*://.*/||g'`" - echo $FILE -} - -check_pkgfile() { - if [ ! "$name" ]; then - error "Variable 'name' not specified in $PKGMK_PKGFILE." - exit $E_PKGFILE - elif [ ! "$version" ]; then - error "Variable 'version' not specified in $PKGMK_PKGFILE." - exit $E_PKGFILE - elif [ ! "$release" ]; then - error "Variable 'release' not specified in $PKGMK_PKGFILE." - exit $E_PKGFILE - elif [ "`type -t build`" != "function" ]; then - error "Function 'build' not specified in $PKGMK_PKGFILE." - exit $E_PKGFILE - fi -} - -check_directory() { - if [ ! -d $1 ]; then - error "Directory '$1' does not exist." - exit $E_DIR_PERM - elif [ ! -w $1 ]; then - error "Directory '$1' not writable." - exit $E_DIR_PERM - elif [ ! -x $1 ] || [ ! -r $1 ]; then - error "Directory '$1' not readable." - exit $E_DIR_PERM - fi -} - -check_file() { - if [ -e $1 ] && [ ! -w $1 ]; then - error "File '$1' is not writable." - exit 1 - fi -} - -download_file() { - info "Downloading '$1'." - - if [ ! "`type -p wget`" ]; then - error "Command 'wget' not found." - exit $E_GENERAL - fi - - LOCAL_FILENAME=`get_filename $1` - LOCAL_FILENAME_PARTIAL="$LOCAL_FILENAME.partial" - DOWNLOAD_OPTS="--passive-ftp --no-directories --tries=3 --waitretry=3 \ - --directory-prefix=$PKGMK_SOURCE_DIR \ - --output-document=$LOCAL_FILENAME_PARTIAL --no-check-certificate" - - if [ -f "$LOCAL_FILENAME_PARTIAL" ]; then - info "Partial download found, trying to resume" - RESUME_CMD="-c" - fi - - error=1 - - BASENAME=`get_basename $1` - for REPO in ${PKGMK_SOURCE_MIRRORS[@]}; do - REPO="`echo $REPO | sed 's|/$||'`" - wget $RESUME_CMD $DOWNLOAD_OPTS $PKGMK_WGET_OPTS $REPO/$BASENAME - error=$? - if [ $error == 0 ]; then - break - fi - done - - if [ $error != 0 ]; then - while true; do - wget $RESUME_CMD $DOWNLOAD_OPTS $PKGMK_WGET_OPTS $1 - error=$? - if [ $error != 0 ] && [ "$RESUME_CMD" ]; then - info "Partial download failed, restarting" - rm -f "$LOCAL_FILENAME_PARTIAL" - RESUME_CMD="" - else - break - fi - done - fi - - if [ $error != 0 ]; then - error "Downloading '$1' failed." - exit $E_DOWNLOAD - fi - - mv -f "$LOCAL_FILENAME_PARTIAL" "$LOCAL_FILENAME" -} - -download_source() { - local FILE LOCAL_FILENAME - - for FILE in ${source[@]}; do - LOCAL_FILENAME=`get_filename $FILE` - if [ ! -e $LOCAL_FILENAME ]; then - if [ "$LOCAL_FILENAME" = "$FILE" ]; then - error "Source file '$LOCAL_FILENAME' not found (can not be downloaded, URL not specified)." - exit $E_DOWNLOAD - else - if [ "$PKGMK_DOWNLOAD" = "yes" ]; then - download_file $FILE - else - error "Source file '$LOCAL_FILENAME' not found (use option -d to download)." - exit $E_DOWNLOAD - fi - fi - fi - done -} - -unpack_source() { - local FILE LOCAL_FILENAME COMMAND - - for FILE in ${source[@]}; do - LOCAL_FILENAME=`get_filename $FILE` - case $LOCAL_FILENAME in - *.tar.gz|*.tar.Z|*.tgz|*.tar.bz2|*.tbz2|*.tar.xz|*.txz|*.tar.lzma|*.zip|*.rpm) - COMMAND="bsdtar -p -o -C $SRC -xf $LOCAL_FILENAME" ;; - *) - COMMAND="cp $LOCAL_FILENAME $SRC" ;; - esac - - echo "$COMMAND" - - $COMMAND - - if [ $? != 0 ]; then - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - rm -rf $PKGMK_WORK_DIR - fi - error "Building '$TARGET' failed." - exit $E_UNPACK - fi - done -} - -make_md5sum() { - local FILE LOCAL_FILENAMES - - if [ "$source" ]; then - for FILE in ${source[@]}; do - LOCAL_FILENAMES="$LOCAL_FILENAMES `get_filename $FILE`" - done - - md5sum $LOCAL_FILENAMES | sed -e 's| .*/| |' | sort -k 2 - fi -} - -make_footprint() { - pkginfo --footprint $TARGET | \ - sed "s|\tlib/modules/`uname -r`/|\tlib/modules//|g" | \ - sort -k 3 -} - -check_md5sum() { - local FILE="$PKGMK_WORK_DIR/.tmp" - - cd $PKGMK_ROOT - - if [ -f $PKGMK_MD5SUM ]; then - make_md5sum > $FILE.md5sum - sort -k 2 $PKGMK_MD5SUM > $FILE.md5sum.orig - diff -w -t -U 0 $FILE.md5sum.orig $FILE.md5sum | \ - sed '/^@@/d' | \ - sed '/^+++/d' | \ - sed '/^---/d' | \ - sed 's/^+/NEW /g' | \ - sed 's/^-/MISSING /g' > $FILE.md5sum.diff - if [ -s $FILE.md5sum.diff ]; then - error "Md5sum mismatch found:" - cat $FILE.md5sum.diff >&2 - - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - rm -rf $PKGMK_WORK_DIR - fi - - if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then - error "Md5sum not ok." - exit $E_MD5 - fi - - error "Building '$TARGET' failed." - exit $E_MD5 - fi - else - if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - rm -rf $PKGMK_WORK_DIR - fi - info "Md5sum not found." - exit $E_MD5 - fi - - warning "Md5sum not found, creating new." - make_md5sum > $PKGMK_MD5SUM - fi - - if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - rm -rf $PKGMK_WORK_DIR - fi - info "Md5sum ok." - exit 0 - fi -} - -strip_files() { - local FILE FILTER - - cd $PKG - - if [ -f $PKGMK_ROOT/$PKGMK_NOSTRIP ]; then - FILTER="grep -v -f $PKGMK_ROOT/$PKGMK_NOSTRIP" - else - FILTER="cat" - fi - - find . -type f -printf "%P\n" | $FILTER | while read FILE; do - case $(file -b "$FILE") in - *ELF*executable*not\ stripped) - $STRIP_CMD --strip-all "$FILE" - ;; - *ELF*shared\ object*not\ stripped) - $STRIP_CMD --strip-unneeded "$FILE" - ;; - current\ ar\ archive) - $STRIP_CMD --strip-debug "$FILE" - esac - done -} - -compress_manpages() { - local FILE DIR TARGET - - cd $PKG - - find . -type f -path "*/man/man*/*" | while read FILE; do - if [ "$FILE" = "${FILE%%.gz}" ]; then - gzip -9 "$FILE" - fi - done - - find . -type l -path "*/man/man*/*" | while read FILE; do - TARGET=`readlink -n "$FILE"` - TARGET="${TARGET##*/}" - TARGET="${TARGET%%.gz}.gz" - rm -f "$FILE" - FILE="${FILE%%.gz}.gz" - DIR=`dirname "$FILE"` - - if [ -e "$DIR/$TARGET" ]; then - ln -sf "$TARGET" "$FILE" - fi - done -} - -fix_cross_paths() { - # remove the last / from CLFS path if appeared - CLFS=${CLFS%*/} - - find $PKG -type f -name '*.la' -exec sed -e "s|$CLFS||g" -e "s|$CROSTOOLS/$CTARGET|/usr|g" -i {} \; -} - -check_footprint() { - local FILE="$PKGMK_WORK_DIR/.tmp" - - cd $PKGMK_ROOT - - if [ -f $TARGET ]; then - make_footprint > $FILE.footprint - if [ -f $PKGMK_FOOTPRINT ]; then - sort -k 3 $PKGMK_FOOTPRINT > $FILE.footprint.orig - diff -w -t -U 0 $FILE.footprint.orig $FILE.footprint | \ - sed '/^@@/d' | \ - sed '/^+++/d' | \ - sed '/^---/d' | \ - sed 's/^+/NEW /g' | \ - sed 's/^-/MISSING /g' > $FILE.footprint.diff - if [ -s $FILE.footprint.diff ]; then - if [ "$PKGMK_IGNORE_NEW" = "yes" ] && \ - [ -z "$(egrep -l ^MISSING $FILE.footprint.diff)" ] ; then - info "New files found:" - else - error "Footprint mismatch found:" - BUILD_SUCCESSFUL="no" - fi - cat $FILE.footprint.diff >&2 - fi - else - warning "Footprint not found, creating new." - mv $FILE.footprint $PKGMK_FOOTPRINT - fi - else - error "Package '$TARGET' was not found." - BUILD_SUCCESSFUL="no" - fi -} - -make_work_dir() { - export PKG="$PKGMK_WORK_DIR/pkg" - export SRC="$PKGMK_WORK_DIR/src" - umask 022 - - cd $PKGMK_ROOT - remove_work_dir - mkdir -p $SRC $PKG - - if [ "$PKGMK_IGNORE_MD5SUM" = "no" ]; then - check_md5sum - fi -} - -remove_work_dir() { - rm -rf $PKGMK_WORK_DIR -} - - -build_package() { - local BUILD_SUCCESSFUL="no" - local COMPRESSION - - check_file "$TARGET" - make_work_dir - - if [ "$UID" != "0" ]; then - warning "Packages should be built as root." - fi - - info "Building '$TARGET'." - - unpack_source - - cd $SRC - (set -e -x ; build) - - if [ $? = 0 ]; then - if [ "$PKGMK_NO_STRIP" = "no" ]; then - strip_files - fi - - compress_manpages - fix_cross_paths - - cd $PKG - info "Build result:" - - case $PKGMK_COMPRESSION_MODE in - gz) COMPRESSION="-z" ;; - bz2) COMPRESSION="-j" ;; - xz) COMPRESSION="-J" ;; - esac - bsdtar -c $COMPRESSION -f $TARGET * && bsdtar -t -v -f $TARGET - - if [ $? = 0 ]; then - BUILD_SUCCESSFUL="yes" - - if [ "$PKGMK_IGNORE_FOOTPRINT" = "yes" ]; then - warning "Footprint ignored." - else - check_footprint - fi - fi - fi - - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - remove_work_dir - fi - - if [ "$BUILD_SUCCESSFUL" = "yes" ]; then - info "Building '$TARGET' succeeded." - else - if [ -f $TARGET ]; then - touch -r $PKGMK_ROOT/$PKGMK_PKGFILE $TARGET &> /dev/null - fi - error "Building '$TARGET' failed." - exit 1 - fi -} - -install_package() { - local COMMAND - - info "Installing '$TARGET'." - - if [ "$PKGMK_INSTALL" = "install" ]; then - COMMAND="pkgadd $TARGET" - else - COMMAND="pkgadd -u $TARGET" - fi - - cd $PKGMK_ROOT - echo "$COMMAND" - $COMMAND - - if [ $? = 0 ]; then - info "Installing '$TARGET' succeeded." - else - error "Installing '$TARGET' failed." - exit 1 - fi -} - -recursive() { - local ARGS FILE DIR - - ARGS=`echo "$@" | sed -e "s/--recursive//g" -e "s/-r//g"` - - for FILE in `find $PKGMK_ROOT -name $PKGMK_PKGFILE | sort`; do - DIR="`dirname $FILE`/" - if [ -d $DIR ]; then - info "Entering directory '$DIR'." - (cd $DIR && $PKGMK_COMMAND $ARGS) - info "Leaving directory '$DIR'." - fi - done -} - -clean() { - local FILE LOCAL_FILENAME - - if [ -f $TARGET ]; then - info "Removing $TARGET" - rm -f $TARGET - fi - - for FILE in ${source[@]}; do - LOCAL_FILENAME=`get_filename $FILE` - if [ -e $LOCAL_FILENAME ] && [ "$LOCAL_FILENAME" != "$FILE" ]; then - info "Removing $LOCAL_FILENAME" - rm -f $LOCAL_FILENAME - fi - done -} - -update_footprint() { - if [ ! -f $TARGET ]; then - error "Unable to update footprint. File '$TARGET' not found." - exit 1 - fi - - check_file "$PKGMK_FOOTPRINT" - make_footprint > $PKGMK_FOOTPRINT - touch $TARGET - - info "Footprint updated." -} - -build_needed() { - local FILE RESULT - - RESULT="yes" - if [ -f $TARGET ]; then - RESULT="no" - for FILE in $PKGMK_PKGFILE ${source[@]}; do - FILE=`get_filename $FILE` - if [ ! -e $FILE ] || [ ! $TARGET -nt $FILE ]; then - RESULT="yes" - break - fi - done - fi - - echo $RESULT -} - -interrupted() { - echo "" - error "Interrupted." - - if [ "$PKGMK_KEEP_WORK" = "no" ]; then - rm -rf $PKGMK_WORK_DIR - fi - - exit 1 -} - -print_help() { - echo "usage: `basename $PKGMK_COMMAND` [options]" - echo "options:" - echo " -i, --install build and install package" - echo " -u, --upgrade build and install package (as upgrade)" - echo " -r, --recursive search for and build packages recursively" - echo " -d, --download download missing source file(s)" - echo " -do, --download-only do not build, only download missing source file(s)" - echo " -eo, --extract-only do not build, only extract source file(s)" - echo " -utd, --up-to-date do not build, only check if package is up to date" - echo " -uf, --update-footprint update footprint using result from last build" - echo " -if, --ignore-footprint build package without checking footprint" - echo " -in, --ignore-new build package, ignore new files in a footprint missmatch" - echo " -um, --update-md5sum update md5sum" - echo " -im, --ignore-md5sum build package without checking md5sum" - echo " -cm, --check-md5sum do not build, only check md5sum" - echo " -ns, --no-strip do not strip executable binaries or libraries" - echo " -f, --force build package even if it appears to be up to date" - echo " -c, --clean remove package and downloaded files" - echo " -kw, --keep-work keep temporary working directory" - echo " -cf, --config-file use alternative configuration file" - echo " -v, --version print version and exit " - echo " -h, --help print help and exit" -} - -parse_options() { - while [ "$1" ]; do - case $1 in - -i|--install) - PKGMK_INSTALL="install" ;; - -u|--upgrade) - PKGMK_INSTALL="upgrade" ;; - -r|--recursive) - PKGMK_RECURSIVE="yes" ;; - -d|--download) - PKGMK_DOWNLOAD="yes" ;; - -do|--download-only) - PKGMK_DOWNLOAD="yes" - PKGMK_DOWNLOAD_ONLY="yes" ;; - -eo|--extract-only) - PKGMK_EXTRACT_ONLY="yes" ;; - -utd|--up-to-date) - PKGMK_UP_TO_DATE="yes" ;; - -uf|--update-footprint) - PKGMK_UPDATE_FOOTPRINT="yes" ;; - -if|--ignore-footprint) - PKGMK_IGNORE_FOOTPRINT="yes" ;; - -in|--ignore-new) - PKGMK_IGNORE_NEW="yes" ;; - -um|--update-md5sum) - PKGMK_UPDATE_MD5SUM="yes" ;; - -im|--ignore-md5sum) - PKGMK_IGNORE_MD5SUM="yes" ;; - -cm|--check-md5sum) - PKGMK_CHECK_MD5SUM="yes" ;; - -ns|--no-strip) - PKGMK_NO_STRIP="yes" ;; - -f|--force) - PKGMK_FORCE="yes" ;; - -c|--clean) - PKGMK_CLEAN="yes" ;; - -kw|--keep-work) - PKGMK_KEEP_WORK="yes" ;; - -cf|--config-file) - if [ ! "$2" ]; then - echo "`basename $PKGMK_COMMAND`: option $1 requires an argument" - exit 1 - fi - PKGMK_CONFFILE="$2" - shift ;; - -v|--version) - echo "`basename $PKGMK_COMMAND` (pkgutils) $PKGMK_VERSION" - exit 0 ;; - -h|--help) - print_help - exit 0 ;; - *) - echo "`basename $PKGMK_COMMAND`: invalid option $1" - exit 1 ;; - esac - shift - done -} - -main() { - local FILE TARGET - - parse_options "$@" - - if [ "$PKGMK_RECURSIVE" = "yes" ]; then - recursive "$@" - exit 0 - fi - - for FILE in $PKGMK_PKGFILE $PKGMK_CONFFILE; do - if [ ! -f $FILE ]; then - error "File '$FILE' not found." - exit 1 - fi - . $FILE - done - - check_directory "$PKGMK_SOURCE_DIR" - check_directory "$PKGMK_PACKAGE_DIR" - check_directory "`dirname $PKGMK_WORK_DIR`" - - check_pkgfile - - case $PKGMK_COMPRESSION_MODE in - gz|bz2|xz) - TARGET="$PKGMK_PACKAGE_DIR/$name#$version-$release.pkg.tar.$PKGMK_COMPRESSION_MODE" - ;; - *) - error "Compression mode '$PKGMK_COMPRESSION_MODE' not supported" - exit 1 - ;; - esac - - if [ "$PKGMK_CLEAN" = "yes" ]; then - clean - exit 0 - fi - - if [ "$PKGMK_UPDATE_FOOTPRINT" = "yes" ]; then - update_footprint - exit 0 - fi - - if [ "$PKGMK_UPDATE_MD5SUM" = "yes" ]; then - download_source - check_file "$PKGMK_MD5SUM" - make_md5sum > $PKGMK_MD5SUM - info "Md5sum updated." - exit 0 - fi - - if [ "$PKGMK_DOWNLOAD_ONLY" = "yes" ]; then - download_source - exit 0 - fi - - if [ "$PKGMK_EXTRACT_ONLY" = "yes" ]; then - download_source - make_work_dir - info "Extracting sources of package '$name-$version'." - unpack_source - exit 0 - fi - - if [ "$PKGMK_UP_TO_DATE" = "yes" ]; then - if [ "`build_needed`" = "yes" ]; then - info "Package '$TARGET' is not up to date." - else - info "Package '$TARGET' is up to date." - fi - exit 0 - fi - - if [ "`build_needed`" = "no" ] && [ "$PKGMK_FORCE" = "no" ] && [ "$PKGMK_CHECK_MD5SUM" = "no" ]; then - info "Package '$TARGET' is up to date." - else - download_source - build_package - fi - - if [ "$PKGMK_INSTALL" != "no" ]; then - install_package - fi - - exit 0 -} - -trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM - -export LC_ALL=POSIX - -readonly PKGMK_VERSION="#VERSION#" -readonly PKGMK_COMMAND="$0" -readonly PKGMK_ROOT="$PWD" - -PKGMK_CONFFILE="/etc/pkgmk.conf" -PKGMK_PKGFILE="Pkgfile" -PKGMK_FOOTPRINT=".footprint" -PKGMK_MD5SUM=".md5sum" -PKGMK_NOSTRIP=".nostrip" - -PKGMK_SOURCE_MIRRORS=() -PKGMK_SOURCE_DIR="$PWD" -PKGMK_PACKAGE_DIR="$PWD" -PKGMK_WORK_DIR="$PWD/work" - -PKGMK_COMPRESSION_MODE="gz" - -PKGMK_INSTALL="no" -PKGMK_RECURSIVE="no" -PKGMK_DOWNLOAD="no" -PKGMK_DOWNLOAD_ONLY="no" -PKGMK_EXTRACT_ONLY="no" -PKGMK_UP_TO_DATE="no" -PKGMK_UPDATE_FOOTPRINT="no" -PKGMK_IGNORE_FOOTPRINT="no" -PKGMK_IGNORE_NEW="no" -PKGMK_FORCE="no" -PKGMK_KEEP_WORK="no" -PKGMK_UPDATE_MD5SUM="no" -PKGMK_IGNORE_MD5SUM="no" -PKGMK_CHECK_MD5SUM="no" -PKGMK_NO_STRIP="no" -PKGMK_CLEAN="no" - -main "$@" - -# End of file diff --git a/src/pkgrm.8.in b/src/pkgrm.8.in deleted file mode 100644 index ba78afe..0000000 --- a/src/pkgrm.8.in +++ /dev/null @@ -1,28 +0,0 @@ -.TH pkgrm 8 "" "pkgutils #VERSION#" "" -.SH NAME -pkgrm \- remove software package -.SH SYNOPSIS -\fBpkgrm [options] \fP -.SH DESCRIPTION -\fBpkgrm\fP is a \fIpackage management\fP utility, which -removes/uninstalls a previously installed software packages. -.SH OPTIONS -.TP -.B "\-r, \-\-root " -Specify alternative installation root (default is "/"). This -should be used if you want to remove a package from a temporary -mounted partition, which is "owned" by another system. By using -this option you not only specify where the software is installed, -but you also specify which package database to use. -.TP -.B "\-v, \-\-version" -Print version and exit. -.TP -.B "\-h, \-\-help" -Print help and exit. -.SH SEE ALSO -pkgadd(8), pkginfo(8), pkgmk(8), rejmerge(8) -.SH COPYRIGHT -pkgrm (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -pkgrm (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/pkgrm.cc b/src/pkgrm.cc deleted file mode 100644 index 2a53a26..0000000 --- a/src/pkgrm.cc +++ /dev/null @@ -1,79 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#include "pkgrm.h" -#include - -void pkgrm::run(int argc, char** argv) -{ - // - // Check command line options - // - string o_package; - string o_root; - - for (int i = 1; i < argc; i++) { - string option(argv[i]); - if (option == "-r" || option == "--root") { - assert_argument(argv, argc, i); - o_root = argv[i + 1]; - i++; - } else if (option[0] == '-' || !o_package.empty()) { - throw runtime_error("invalid option " + option); - } else { - o_package = option; - } - } - - if (o_package.empty()) - throw runtime_error("option missing"); - - // - // Check UID - // - if (getuid()) - throw runtime_error("only root can remove packages"); - - // - // Remove package - // - { - db_lock lock(o_root, true); - db_open(o_root); - - if (!db_find_pkg(o_package)) - throw runtime_error("package " + o_package + " not installed"); - - db_rm_pkg(o_package); - ldconfig(); - db_commit(); - } -} - -void pkgrm::print_help() const -{ - cout << "usage: " << utilname << " [options] " << endl - << "options:" << endl - << " -r, --root specify alternative installation root" << endl - << " -v, --version print version and exit" << endl - << " -h, --help print help and exit" << endl; -} diff --git a/src/pkgrm.h b/src/pkgrm.h deleted file mode 100644 index 967c026..0000000 --- a/src/pkgrm.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#ifndef PKGRM_H -#define PKGRM_H - -#include "pkgutil.h" - -class pkgrm : public pkgutil { -public: - pkgrm() : pkgutil("pkgrm") {} - virtual void run(int argc, char** argv); - virtual void print_help() const; -}; - -#endif /* PKGRM_H */ diff --git a/src/pkgutil.cc b/src/pkgutil.cc deleted file mode 100644 index 843c668..0000000 --- a/src/pkgutil.cc +++ /dev/null @@ -1,818 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#include "pkgutil.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define INIT_ARCHIVE(ar) \ - archive_read_support_filter_gzip((ar)); \ - archive_read_support_filter_bzip2((ar)); \ - archive_read_support_filter_xz((ar)); \ - archive_read_support_format_tar((ar)) - -#define DEFAULT_BYTES_PER_BLOCK (20 * 512) - -using __gnu_cxx::stdio_filebuf; - -pkgutil::pkgutil(const string& name) - : utilname(name) -{ - // Ignore signals - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sigaction(SIGHUP, &sa, 0); - sigaction(SIGINT, &sa, 0); - sigaction(SIGQUIT, &sa, 0); - sigaction(SIGTERM, &sa, 0); -} - -void pkgutil::db_open(const string& path) -{ - // Read database - root = trim_filename(path + "/"); - const string filename = root + PKG_DB; - - int fd = open(filename.c_str(), O_RDONLY); - if (fd == -1) - throw runtime_error_with_errno("could not open " + filename); - - stdio_filebuf filebuf(fd, ios::in, getpagesize()); - istream in(&filebuf); - if (!in) - throw runtime_error_with_errno("could not read " + filename); - - while (!in.eof()) { - // Read record - string name; - pkginfo_t info; - getline(in, name); - getline(in, info.version); - for (;;) { - string file; - getline(in, file); - - if (file.empty()) - break; // End of record - - info.files.insert(info.files.end(), file); - } - if (!info.files.empty()) - packages[name] = info; - } - -#ifndef NDEBUG - cerr << packages.size() << " packages found in database" << endl; -#endif -} - -void pkgutil::db_commit() -{ - const string dbfilename = root + PKG_DB; - const string dbfilename_new = dbfilename + ".incomplete_transaction"; - const string dbfilename_bak = dbfilename + ".backup"; - - // Remove failed transaction (if it exists) - if (unlink(dbfilename_new.c_str()) == -1 && errno != ENOENT) - throw runtime_error_with_errno("could not remove " + dbfilename_new); - - // Write new database - int fd_new = creat(dbfilename_new.c_str(), 0444); - if (fd_new == -1) - throw runtime_error_with_errno("could not create " + dbfilename_new); - - stdio_filebuf filebuf_new(fd_new, ios::out, getpagesize()); - ostream db_new(&filebuf_new); - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) { - if (!i->second.files.empty()) { - db_new << i->first << "\n"; - db_new << i->second.version << "\n"; - copy(i->second.files.begin(), i->second.files.end(), ostream_iterator(db_new, "\n")); - db_new << "\n"; - } - } - - db_new.flush(); - - // Make sure the new database was successfully written - if (!db_new) - throw runtime_error("could not write " + dbfilename_new); - - // Synchronize file to disk - if (fsync(fd_new) == -1) - throw runtime_error_with_errno("could not synchronize " + dbfilename_new); - - // Relink database backup - if (unlink(dbfilename_bak.c_str()) == -1 && errno != ENOENT) - throw runtime_error_with_errno("could not remove " + dbfilename_bak); - if (link(dbfilename.c_str(), dbfilename_bak.c_str()) == -1) - throw runtime_error_with_errno("could not create " + dbfilename_bak); - - // Move new database into place - if (rename(dbfilename_new.c_str(), dbfilename.c_str()) == -1) - throw runtime_error_with_errno("could not rename " + dbfilename_new + " to " + dbfilename); - -#ifndef NDEBUG - cerr << packages.size() << " packages written to database" << endl; -#endif -} - -void pkgutil::db_add_pkg(const string& name, const pkginfo_t& info) -{ - packages[name] = info; -} - -bool pkgutil::db_find_pkg(const string& name) -{ - return (packages.find(name) != packages.end()); -} - -void pkgutil::db_rm_pkg(const string& name) -{ - set files = packages[name].files; - packages.erase(name); - -#ifndef NDEBUG - cerr << "Removing package phase 1 (all files in package):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Don't delete files that still have references - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) - for (set::const_iterator j = i->second.files.begin(); j != i->second.files.end(); ++j) - files.erase(*j); - -#ifndef NDEBUG - cerr << "Removing package phase 2 (files that still have references excluded):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Delete the files - for (set::const_reverse_iterator i = files.rbegin(); i != files.rend(); ++i) { - const string filename = root + *i; - if (file_exists(filename) && remove(filename.c_str()) == -1) { - const char* msg = strerror(errno); - cerr << utilname << ": could not remove " << filename << ": " << msg << endl; - } - } -} - -void pkgutil::db_rm_pkg(const string& name, const set& keep_list) -{ - set files = packages[name].files; - packages.erase(name); - -#ifndef NDEBUG - cerr << "Removing package phase 1 (all files in package):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Don't delete files found in the keep list - for (set::const_iterator i = keep_list.begin(); i != keep_list.end(); ++i) - files.erase(*i); - -#ifndef NDEBUG - cerr << "Removing package phase 2 (files that is in the keep list excluded):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Don't delete files that still have references - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) - for (set::const_iterator j = i->second.files.begin(); j != i->second.files.end(); ++j) - files.erase(*j); - -#ifndef NDEBUG - cerr << "Removing package phase 3 (files that still have references excluded):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Delete the files - for (set::const_reverse_iterator i = files.rbegin(); i != files.rend(); ++i) { - const string filename = root + *i; - if (file_exists(filename) && remove(filename.c_str()) == -1) { - if (errno == ENOTEMPTY) - continue; - const char* msg = strerror(errno); - cerr << utilname << ": could not remove " << filename << ": " << msg << endl; - } - } -} - -void pkgutil::db_rm_files(set files, const set& keep_list) -{ - // Remove all references - for (packages_t::iterator i = packages.begin(); i != packages.end(); ++i) - for (set::const_iterator j = files.begin(); j != files.end(); ++j) - i->second.files.erase(*j); - -#ifndef NDEBUG - cerr << "Removing files:" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Don't delete files found in the keep list - for (set::const_iterator i = keep_list.begin(); i != keep_list.end(); ++i) - files.erase(*i); - - // Delete the files - for (set::const_reverse_iterator i = files.rbegin(); i != files.rend(); ++i) { - const string filename = root + *i; - if (file_exists(filename) && remove(filename.c_str()) == -1) { - if (errno == ENOTEMPTY) - continue; - const char* msg = strerror(errno); - cerr << utilname << ": could not remove " << filename << ": " << msg << endl; - } - } -} - -set pkgutil::db_find_conflicts(const string& name, const pkginfo_t& info) -{ - set files; - - // Find conflicting files in database - for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) { - if (i->first != name) { - set_intersection(info.files.begin(), info.files.end(), - i->second.files.begin(), i->second.files.end(), - inserter(files, files.end())); - } - } - -#ifndef NDEBUG - cerr << "Conflicts phase 1 (conflicts in database):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Find conflicting files in filesystem - for (set::iterator i = info.files.begin(); i != info.files.end(); ++i) { - const string filename = root + *i; - if (file_exists(filename) && files.find(*i) == files.end()) - files.insert(files.end(), *i); - } - -#ifndef NDEBUG - cerr << "Conflicts phase 2 (conflicts in filesystem added):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // Exclude directories - set tmp = files; - for (set::const_iterator i = tmp.begin(); i != tmp.end(); ++i) { - if ((*i)[i->length() - 1] == '/') - files.erase(*i); - } - -#ifndef NDEBUG - cerr << "Conflicts phase 3 (directories excluded):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - - // If this is an upgrade, remove files already owned by this package - if (packages.find(name) != packages.end()) { - for (set::const_iterator i = packages[name].files.begin(); i != packages[name].files.end(); ++i) - files.erase(*i); - -#ifndef NDEBUG - cerr << "Conflicts phase 4 (files already owned by this package excluded):" << endl; - copy(files.begin(), files.end(), ostream_iterator(cerr, "\n")); - cerr << endl; -#endif - } - - return files; -} - -pair pkgutil::pkg_open(const string& filename) const -{ - pair result; - unsigned int i; - struct archive* archive; - struct archive_entry* entry; - - // Extract name and version from filename - string basename(filename, filename.rfind('/') + 1); - string name(basename, 0, basename.find(VERSION_DELIM)); - string version(basename, 0, basename.rfind(PKG_EXT)); - version.erase(0, version.find(VERSION_DELIM) == string::npos ? string::npos : version.find(VERSION_DELIM) + 1); - - if (name.empty() || version.empty()) - throw runtime_error("could not determine name and/or version of " + basename + ": Invalid package name"); - - result.first = name; - result.second.version = version; - - archive = archive_read_new(); - INIT_ARCHIVE(archive); - - if (archive_read_open_filename(archive, - filename.c_str(), - DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) - throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); - - for (i = 0; archive_read_next_header(archive, &entry) == - ARCHIVE_OK; ++i) { - - result.second.files.insert(result.second.files.end(), - archive_entry_pathname(entry)); - - mode_t mode = archive_entry_mode(entry); - - if (S_ISREG(mode) && - archive_read_data_skip(archive) != ARCHIVE_OK) - throw runtime_error_with_errno("could not read " + filename, archive_errno(archive)); - } - - if (i == 0) { - if (archive_errno(archive) == 0) - throw runtime_error("empty package"); - else - throw runtime_error("could not read " + filename); - } - - archive_read_free(archive); - - return result; -} - -void pkgutil::pkg_install(const string& filename, const set& keep_list, const set& non_install_list) const -{ - struct archive* archive; - struct archive_entry* entry; - unsigned int i; - char buf[PATH_MAX]; - string absroot; - - archive = archive_read_new(); - INIT_ARCHIVE(archive); - - if (archive_read_open_filename(archive, - filename.c_str(), - DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) - throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); - - chdir(root.c_str()); - absroot = getcwd(buf, sizeof(buf)); - - for (i = 0; archive_read_next_header(archive, &entry) == - ARCHIVE_OK; ++i) { - string archive_filename = archive_entry_pathname(entry); - string reject_dir = trim_filename(absroot + string("/") + string(PKG_REJECTED)); - string original_filename = trim_filename(absroot + string("/") + archive_filename); - string real_filename = original_filename; - - // Check if file is filtered out via INSTALL - if (non_install_list.find(archive_filename) != non_install_list.end()) { - mode_t mode; - - cout << utilname << ": ignoring " << archive_filename << endl; - - mode = archive_entry_mode(entry); - - if (S_ISREG(mode)) - archive_read_data_skip(archive); - - continue; - } - - // Check if file should be rejected - if (file_exists(real_filename) && keep_list.find(archive_filename) != keep_list.end()) - real_filename = trim_filename(reject_dir + string("/") + archive_filename); - - archive_entry_set_pathname(entry, const_cast - (real_filename.c_str())); - - // Extract file - unsigned int flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK; - - if (archive_read_extract(archive, entry, flags) != ARCHIVE_OK) { - // If a file fails to install we just print an error message and - // continue trying to install the rest of the package. - const char* msg = archive_error_string(archive); - cerr << utilname << ": could not install " + archive_filename << ": " << msg << endl; - continue; - } - - // Check rejected file - if (real_filename != original_filename) { - bool remove_file = false; - mode_t mode = archive_entry_mode(entry); - - // Directory - if (S_ISDIR(mode)) - remove_file = permissions_equal(real_filename, original_filename); - // Other files - else - remove_file = permissions_equal(real_filename, original_filename) && - (file_empty(real_filename) || file_equal(real_filename, original_filename)); - - // Remove rejected file or signal about its existence - if (remove_file) - file_remove(reject_dir, real_filename); - else - cout << utilname << ": rejecting " << archive_filename << ", keeping existing version" << endl; - } - } - - if (i == 0) { - if (archive_errno(archive) == 0) - throw runtime_error("empty package"); - else - throw runtime_error("could not read " + filename); - } - - archive_read_free(archive); -} - -void pkgutil::ldconfig() const -{ - // Only execute ldconfig if /etc/ld.so.conf exists - if (file_exists(root + LDCONFIG_CONF)) { - pid_t pid = fork(); - - if (pid == -1) - throw runtime_error_with_errno("fork() failed"); - - if (pid == 0) { - execl(LDCONFIG, LDCONFIG, "-r", root.c_str(), (char *) 0); - const char* msg = strerror(errno); - cerr << utilname << ": could not execute " << LDCONFIG << ": " << msg << endl; - exit(EXIT_FAILURE); - } else { - if (waitpid(pid, 0, 0) == -1) - throw runtime_error_with_errno("waitpid() failed"); - } - } -} - -void pkgutil::pkg_footprint(string& filename) const -{ - unsigned int i; - struct archive* archive; - struct archive_entry* entry; - - map hardlink_target_modes; - - // We first do a run over the archive and remember the modes - // of regular files. - // In the second run, we print the footprint - using the stored - // modes for hardlinks. - // - // FIXME the code duplication here is butt ugly - archive = archive_read_new(); - INIT_ARCHIVE(archive); - - if (archive_read_open_filename(archive, - filename.c_str(), - DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) - throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); - - for (i = 0; archive_read_next_header(archive, &entry) == - ARCHIVE_OK; ++i) { - - mode_t mode = archive_entry_mode(entry); - - if (!archive_entry_hardlink(entry)) { - const char *s = archive_entry_pathname(entry); - - hardlink_target_modes[s] = mode; - } - - if (S_ISREG(mode) && archive_read_data_skip(archive)) - throw runtime_error_with_errno("could not read " + filename, archive_errno(archive)); - } - - archive_read_free(archive); - - // Too bad, there doesn't seem to be a way to reuse our archive - // instance - archive = archive_read_new(); - INIT_ARCHIVE(archive); - - if (archive_read_open_filename(archive, - filename.c_str(), - DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) - throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); - - for (i = 0; archive_read_next_header(archive, &entry) == - ARCHIVE_OK; ++i) { - mode_t mode = archive_entry_mode(entry); - - // Access permissions - if (S_ISLNK(mode)) { - // Access permissions on symlinks differ among filesystems, e.g. XFS and ext2 have different. - // To avoid getting different footprints we always use "lrwxrwxrwx". - cout << "lrwxrwxrwx"; - } else { - const char *h = archive_entry_hardlink(entry); - - if (h) - cout << mtos(hardlink_target_modes[h]); - else - cout << mtos(mode); - } - - cout << '\t'; - - // User - uid_t uid = archive_entry_uid(entry); - struct passwd* pw = getpwuid(uid); - if (pw) - cout << pw->pw_name; - else - cout << uid; - - cout << '/'; - - // Group - gid_t gid = archive_entry_gid(entry); - struct group* gr = getgrgid(gid); - if (gr) - cout << gr->gr_name; - else - cout << gid; - - // Filename - cout << '\t' << archive_entry_pathname(entry); - - // Special cases - if (S_ISLNK(mode)) { - // Symlink - cout << " -> " << archive_entry_symlink(entry); - } else if (S_ISCHR(mode) || - S_ISBLK(mode)) { - // Device - cout << " (" << archive_entry_rdevmajor(entry) - << ", " << archive_entry_rdevminor(entry) - << ")"; - } else if (S_ISREG(mode) && - archive_entry_size(entry) == 0) { - // Empty regular file - cout << " (EMPTY)"; - } - - cout << '\n'; - - if (S_ISREG(mode) && archive_read_data_skip(archive)) - throw runtime_error_with_errno("could not read " + filename, archive_errno(archive)); - } - - if (i == 0) { - if (archive_errno(archive) == 0) - throw runtime_error("empty package"); - else - throw runtime_error("could not read " + filename); - } - - archive_read_free(archive); -} - -void pkgutil::print_version() const -{ - cout << utilname << " (pkgutils) " << VERSION << endl; -} - -db_lock::db_lock(const string& root, bool exclusive) - : dir(0) -{ - const string dirname = trim_filename(root + string("/") + PKG_DIR); - - if (!(dir = opendir(dirname.c_str()))) - throw runtime_error_with_errno("could not read directory " + dirname); - - if (flock(dirfd(dir), (exclusive ? LOCK_EX : LOCK_SH) | LOCK_NB) == -1) { - if (errno == EWOULDBLOCK) - throw runtime_error("package database is currently locked by another process"); - else - throw runtime_error_with_errno("could not lock directory " + dirname); - } -} - -db_lock::~db_lock() -{ - if (dir) { - flock(dirfd(dir), LOCK_UN); - closedir(dir); - } -} - -void assert_argument(char** argv, int argc, int index) -{ - if (argc - 1 < index + 1) - throw runtime_error("option " + string(argv[index]) + " requires an argument"); -} - -string itos(unsigned int value) -{ - static char buf[20]; - sprintf(buf, "%u", value); - return buf; -} - -string mtos(mode_t mode) -{ - string s; - - // File type - switch (mode & S_IFMT) { - case S_IFREG: s += '-'; break; // Regular - case S_IFDIR: s += 'd'; break; // Directory - case S_IFLNK: s += 'l'; break; // Symbolic link - case S_IFCHR: s += 'c'; break; // Character special - case S_IFBLK: s += 'b'; break; // Block special - case S_IFSOCK: s += 's'; break; // Socket - case S_IFIFO: s += 'p'; break; // Fifo - default: s += '?'; break; // Unknown - } - - // User permissions - s += (mode & S_IRUSR) ? 'r' : '-'; - s += (mode & S_IWUSR) ? 'w' : '-'; - switch (mode & (S_IXUSR | S_ISUID)) { - case S_IXUSR: s += 'x'; break; - case S_ISUID: s += 'S'; break; - case S_IXUSR | S_ISUID: s += 's'; break; - default: s += '-'; break; - } - - // Group permissions - s += (mode & S_IRGRP) ? 'r' : '-'; - s += (mode & S_IWGRP) ? 'w' : '-'; - switch (mode & (S_IXGRP | S_ISGID)) { - case S_IXGRP: s += 'x'; break; - case S_ISGID: s += 'S'; break; - case S_IXGRP | S_ISGID: s += 's'; break; - default: s += '-'; break; - } - - // Other permissions - s += (mode & S_IROTH) ? 'r' : '-'; - s += (mode & S_IWOTH) ? 'w' : '-'; - switch (mode & (S_IXOTH | S_ISVTX)) { - case S_IXOTH: s += 'x'; break; - case S_ISVTX: s += 'T'; break; - case S_IXOTH | S_ISVTX: s += 't'; break; - default: s += '-'; break; - } - - return s; -} - -string trim_filename(const string& filename) -{ - string search("//"); - string result = filename; - - for (string::size_type pos = result.find(search); pos != string::npos; pos = result.find(search)) - result.replace(pos, search.size(), "/"); - - return result; -} - -bool file_exists(const string& filename) -{ - struct stat buf; - return !lstat(filename.c_str(), &buf); -} - -bool file_empty(const string& filename) -{ - struct stat buf; - - if (lstat(filename.c_str(), &buf) == -1) - return false; - - return (S_ISREG(buf.st_mode) && buf.st_size == 0); -} - -bool file_equal(const string& file1, const string& file2) -{ - struct stat buf1, buf2; - - if (lstat(file1.c_str(), &buf1) == -1) - return false; - - if (lstat(file2.c_str(), &buf2) == -1) - return false; - - // Regular files - if (S_ISREG(buf1.st_mode) && S_ISREG(buf2.st_mode)) { - ifstream f1(file1.c_str()); - ifstream f2(file2.c_str()); - - if (!f1 || !f2) - return false; - - while (!f1.eof()) { - char buffer1[4096]; - char buffer2[4096]; - f1.read(buffer1, 4096); - f2.read(buffer2, 4096); - if (f1.gcount() != f2.gcount() || - memcmp(buffer1, buffer2, f1.gcount()) || - f1.eof() != f2.eof()) - return false; - } - - return true; - } - // Symlinks - else if (S_ISLNK(buf1.st_mode) && S_ISLNK(buf2.st_mode)) { - char symlink1[MAXPATHLEN]; - char symlink2[MAXPATHLEN]; - - memset(symlink1, 0, MAXPATHLEN); - memset(symlink2, 0, MAXPATHLEN); - - if (readlink(file1.c_str(), symlink1, MAXPATHLEN - 1) == -1) - return false; - - if (readlink(file2.c_str(), symlink2, MAXPATHLEN - 1) == -1) - return false; - - return !strncmp(symlink1, symlink2, MAXPATHLEN); - } - // Character devices - else if (S_ISCHR(buf1.st_mode) && S_ISCHR(buf2.st_mode)) { - return buf1.st_dev == buf2.st_dev; - } - // Block devices - else if (S_ISBLK(buf1.st_mode) && S_ISBLK(buf2.st_mode)) { - return buf1.st_dev == buf2.st_dev; - } - - return false; -} - -bool permissions_equal(const string& file1, const string& file2) -{ - struct stat buf1; - struct stat buf2; - - if (lstat(file1.c_str(), &buf1) == -1) - return false; - - if (lstat(file2.c_str(), &buf2) == -1) - return false; - - return(buf1.st_mode == buf2.st_mode) && - (buf1.st_uid == buf2.st_uid) && - (buf1.st_gid == buf2.st_gid); -} - -void file_remove(const string& basedir, const string& filename) -{ - if (filename != basedir && !remove(filename.c_str())) { - char* path = strdup(filename.c_str()); - file_remove(basedir, dirname(path)); - free(path); - } -} diff --git a/src/pkgutil.h b/src/pkgutil.h deleted file mode 100644 index faebf10..0000000 --- a/src/pkgutil.h +++ /dev/null @@ -1,110 +0,0 @@ -// -// pkgutils -// -// Copyright (c) 2000-2005 Per Liden -// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -// -// 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. -// - -#ifndef PKGUTIL_H -#define PKGUTIL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PKG_EXT ".pkg.tar." -#define PKG_DIR "var/lib/pkg" -#define PKG_DB "var/lib/pkg/db" -#define PKG_REJECTED "var/lib/pkg/rejected" -#define VERSION_DELIM '#' -#define LDCONFIG "/sbin/ldconfig" -#define LDCONFIG_CONF "/etc/ld.so.conf" - -using namespace std; - -class pkgutil { -public: - struct pkginfo_t { - string version; - set files; - }; - - typedef map packages_t; - - explicit pkgutil(const string& name); - virtual ~pkgutil() {} - virtual void run(int argc, char** argv) = 0; - virtual void print_help() const = 0; - void print_version() const; - -protected: - // Database - void db_open(const string& path); - void db_commit(); - void db_add_pkg(const string& name, const pkginfo_t& info); - bool db_find_pkg(const string& name); - void db_rm_pkg(const string& name); - void db_rm_pkg(const string& name, const set& keep_list); - void db_rm_files(set files, const set& keep_list); - set db_find_conflicts(const string& name, const pkginfo_t& info); - - // Tar.gz - pair pkg_open(const string& filename) const; - void pkg_install(const string& filename, const set& keep_list, const set& non_install_files) const; - void pkg_footprint(string& filename) const; - void ldconfig() const; - - string utilname; - packages_t packages; - string root; -}; - -class db_lock { -public: - db_lock(const string& root, bool exclusive); - ~db_lock(); -private: - DIR* dir; -}; - -class runtime_error_with_errno : public runtime_error { -public: - explicit runtime_error_with_errno(const string& msg) throw() - : runtime_error(msg + string(": ") + strerror(errno)) {} - explicit runtime_error_with_errno(const string& msg, int e) throw() - : runtime_error(msg + string(": ") + strerror(e)) {} -}; - -// Utility functions -void assert_argument(char** argv, int argc, int index); -string itos(unsigned int value); -string mtos(mode_t mode); -string trim_filename(const string& filename); -bool file_exists(const string& filename); -bool file_empty(const string& filename); -bool file_equal(const string& file1, const string& file2); -bool permissions_equal(const string& file1, const string& file2); -void file_remove(const string& basedir, const string& filename); - -#endif /* PKGUTIL_H */ diff --git a/src/rejmerge.8.in b/src/rejmerge.8.in deleted file mode 100644 index cc05c4c..0000000 --- a/src/rejmerge.8.in +++ /dev/null @@ -1,78 +0,0 @@ -.TH rejmerge 8 "" "pkgutils #VERSION#" "" -.SH NAME -rejmerge \- merge files that were rejected during package upgrades -.SH SYNOPSIS -\fBrejmerge [options]\fP -.SH DESCRIPTION -\fBrejmerge\fP is a \fIpackage management\fP utility that helps you merge files that were rejected -during package upgrades. For each rejected file found in \fI/var/lib/pkg/rejected/\fP, \fBrejmerge\fP -will display the difference between the installed version and the rejected version. The user can then -choose to keep the installed version, upgrade to the rejected version or perform a merge of the two. - -.SH OPTIONS -.TP -.B "\-r, \-\-root " -Specify alternative root (default is "/"). This should be used -if you want to merge rejected files on a temporary mounted partition, -which is "owned" by another system. -.TP -.B "\-v, \-\-version" -Print version and exit. -.TP -.B "\-h, \-\-help" -Print help and exit. -.SH CONFIGURATION -When \fBrejmerge\fP is started it will source \fI/etc/rejmerge.conf\fP. -This file can be used to alter the way \fBrejmerge\fP displays file differences and performs file -merges. Changing the default behaviour is done by re-defining the shell functions \fBrejmerge_diff()\fP -and/or \fBrejmerge_merge()\fP. -.TP -.B rejmerge_diff() -This function is executed once for each rejected file. Arguments \fB$1\fP and \fB$2\fP contain the paths -to the installed and rejected files. Argument \fB$3\fP contains the path to a temporary file where this -function should write its result. The contents of the temporary file will later be presented to the user -as the difference between the two files. -.TP -.B rejmerge_merge() -This function is executed when the user chooses to merge two files. Arguments \fB$1\fP and \fB$2\fP -contain the paths to the installed and rejected files. Argument \fB$3\fP contains the path to a temporary -file where this function should write its result. The contents of the temporary file will later be -presented to the user as the merge result. -This function also has the option to set the variable \fB$REJMERGE_MERGE_INFO\fP. The contents of this -variable will be displayed as informational text after a merge has been performed. Its purpose is to provide -information about the merge, e.g. "5 merge conflicts found". - -.PP -Example: - -.nf -# -# /etc/rejmerge.conf: rejmerge(8) configuration -# - -rejmerge_diff() { - # Use diff(1) to produce side-by-side output - diff -y $1 $2 > $3 -} - -rejmerge_merge() { - # Use sdiff(1) to merge - sdiff -o $3 $1 $2 -} - -# End of file -.fi - -.SH FILES -.TP -.B "/etc/rejmerge.conf" -Configuration file. -.TP -.B "/var/lib/pkg/rejected/" -Directory where rejected files are stored. -.SH SEE ALSO -pkgadd(8), pkgrm(8), pkginfo(8), pkgmk(8) -.SH COPYRIGHT -rejmerge (pkgutils) is Copyright (c) 2000-2005 Per Liden and Copyright (c) 2006-2010 CRUX team (http://crux.nu). -rejmerge (pkgutils) is licensed through the GNU General Public License. -Read the COPYING file for the complete license. diff --git a/src/rejmerge.conf b/src/rejmerge.conf deleted file mode 100644 index c80af34..0000000 --- a/src/rejmerge.conf +++ /dev/null @@ -1,5 +0,0 @@ -# -# /etc/rejmerge.conf: rejmerge(8) configuration -# - -# End of file diff --git a/src/rejmerge.in b/src/rejmerge.in deleted file mode 100755 index d6b479a..0000000 --- a/src/rejmerge.in +++ /dev/null @@ -1,316 +0,0 @@ -#!/bin/bash -# -# rejmerge (pkgutils) -# -# Copyright (c) 2000-2005 Per Liden -# Copyright (c) 2006-2010 by CRUX team (http://crux.nu) -# -# 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. -# - -info_n() { - echo -n "=======> $1" -} - -info() { - info_n "$1" - echo -} - -interrupted() { - echo "" - info "Aborted." - exit 1 -} - -atexit() { - if [ -e "$TMPFILE" ]; then - rm -f "$TMPFILE" - fi -} - -rejmerge_diff() { - diff -u "$1" "$2" > "$3" -} - -rejmerge_merge() { - diff --old-group-format="%<" \ - --new-group-format="%>" \ - --changed-group-format="<<<<< MERGE CONFLICT $1 >>>>> -%<<<<<< MERGE CONFLICT $2 >>>>> -%><<<<< END MERGE CONFLICT >>>>> -" \ - "$1" "$2" > "$3" - - REJMERGE_MERGE_INFO="$(grep -c '^<<<<< END MERGE CONFLICT >>>>>$' "$3") merge conflict(s)." -} - -permissions_menu() { - while true; do - info "Access permissions $1" - stat -c '%A %U %G %n' "$1" - stat -c '%A %U %G %n' "$2" - while true; do - info_n "[K]eep [U]pgrade [D]iff [S]kip? " - read -n1 CMD - echo - - case "$CMD" in - k|K) chown --reference="$1" "$2" - chmod --reference="$1" "$2" - break 2 - ;; - u|U) chown --reference="$2" "$1" - chmod --reference="$2" "$1" - break 2 - ;; - d|D) break 1 - ;; - s|S) break 2 - ;; - esac - done - done -} - -merge_menu() { - rejmerge_merge "$1" "$2" "$TMPFILE" - - while true; do - info "Merged $1" - cat "$TMPFILE" | more - - if [ "$REJMERGE_MERGE_INFO" ]; then - info "$REJMERGE_MERGE_INFO" - unset REJMERGE_MERGE_INFO - fi - - while true; do - info_n "[I]nstall [E]dit [V]iew [S]kip? " - read -n1 CMD - echo - - case "$CMD" in - i|I) chmod --reference="$1" "$TMPFILE" - mv -f "$TMPFILE" "$1" - rm -f "$2" - break 2 - ;; - e|E) $EDITOR "$TMPFILE" - break 1 - ;; - v|V) break 1 - ;; - s|S) break 2 - ;; - esac - done - done - - : > "$TMPFILE" -} - -diff_menu() { - rejmerge_diff "$1" "$2" "$TMPFILE" - - while true; do - info "$1" - cat "$TMPFILE" | more - while true; do - info_n "[K]eep [U]pgrade [M]erge [D]iff [S]kip? " - read -n1 CMD - echo - - case "$CMD" in - k|K) rm -f "$2" - break 2 - ;; - u|U) mv -f "$2" "$1" - break 2 - ;; - m|M) merge_menu "$1" "$2" - break 2 - ;; - d|D) break 1 - ;; - s|S) break 2 - ;; - esac - done - done - - : > "$TMPFILE" -} - -file_menu() { - while true; do - info "$1" - file "$1" "$2" - while true; do - info_n "[K]eep [U]pgrade [D]iff [S]kip? " - read -n1 CMD - echo - - case "$CMD" in - k|K) rm -f "$2" - break 2 - ;; - u|U) mv -f "$2" "$1" - break 2 - ;; - d|D) break 1 - ;; - s|S) break 2 - ;; - esac - done - done -} - -print_help() { - echo "usage: $REJMERGE_COMMAND [options]" - echo "options:" - echo " -r, --root specify alternative root" - echo " -v, --version print version and exit " - echo " -h, --help print help and exit" -} - -parse_options() { - while [ "$1" ]; do - case $1 in - -r|--root) - if [ ! "$2" ]; then - echo "$REJMERGE_COMMAND: option $1 requires an argument" - exit 1 - fi - REJMERGE_ROOT="$2" - REJMERGE_CONF="$2$REJMERGE_CONF" - REJECTED_DIR="$2$REJECTED_DIR" - shift ;; - -v|--version) - echo "$REJMERGE_COMMAND (pkgutils) $REJMERGE_VERSION" - exit 0 ;; - -h|--help) - print_help - exit 0 ;; - *) - echo "$REJMERGE_COMMAND: invalid option $1" - exit 1 ;; - esac - shift - done - - if [ ! -d "$REJECTED_DIR" ]; then - echo "$REJMERGE_COMMAND: $REJECTED_DIR not found" - exit 1 - fi -} - -files_regular() { - local STAT_FILE1=$(stat -c '%F' "$1") - local STAT_FILE2=$(stat -c '%F' "$2") - - if [ "$STAT_FILE1" != "regular file" ]; then - return 1 - fi - - if [ "$STAT_FILE2" != "regular file" ]; then - return 1 - fi - - return 0 -} - -main() { - parse_options "$@" - - if [ "$UID" != "0" ]; then - echo "$REJMERGE_COMMAND: only root can merge rejected files" - exit 1 - fi - - # Read configuration - if [ -f "$REJMERGE_CONF" ]; then - . "$REJMERGE_CONF" - fi - - REJECTED_FILES_FOUND="no" - - # Check files - for REJECTED_FILE in $(find $REJECTED_DIR ! -type d); do - INSTALLED_FILE="$REJMERGE_ROOT${REJECTED_FILE##$REJECTED_DIR}" - - # Remove rejected file if there is no installed version - if [ ! -e "$INSTALLED_FILE" ]; then - rm -f "$REJECTED_FILE" - continue - fi - - # Check permissions - local STAT_FILE1=$(stat -c '%A %U %G' "$INSTALLED_FILE") - local STAT_FILE2=$(stat -c '%A %U %G' "$REJECTED_FILE") - - if [ "$STAT_FILE1" != "$STAT_FILE2" ]; then - REJECTED_FILES_FOUND="yes" - permissions_menu "$INSTALLED_FILE" "$REJECTED_FILE" - fi - - # Check file types - if files_regular "$INSTALLED_FILE" "$REJECTED_FILE"; then - # Both files are regular - if cmp -s "$INSTALLED_FILE" "$REJECTED_FILE"; then - rm -f "$REJECTED_FILE" - else - REJECTED_FILES_FOUND="yes" - diff_menu "$INSTALLED_FILE" "$REJECTED_FILE" - fi - else - # At least one file is non-regular - REJECTED_FILES_FOUND="yes" - file_menu "$INSTALLED_FILE" "$REJECTED_FILE" - fi - done - - # Remove empty directories - for DIR in $(find $REJECTED_DIR -depth -type d); do - if [ "$DIR" != "$REJECTED_DIR" ]; then - rmdir "$DIR" &> /dev/null - fi - done - - if [ "$REJECTED_FILES_FOUND" = "no" ]; then - echo "Nothing to merge" - fi - - exit 0 -} - -trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM -trap "atexit" EXIT - -export LC_ALL=POSIX - -readonly REJMERGE_VERSION="#VERSION#" -readonly REJMERGE_COMMAND="${0##*/}" -REJMERGE_ROOT="" -REJMERGE_CONF="/etc/rejmerge.conf" -REJECTED_DIR="/var/lib/pkg/rejected" -EDITOR=${EDITOR:-vi} -TMPFILE=$(mktemp) || exit 1 - -main "$@" - -# End of file