From d53b2011b1406a4784995f4043added5c04588ce Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Mon, 25 Feb 2002 19:23:38 +0000 Subject: [PATCH] Imported from pacman-1.0.tar.gz --- COPYING | 340 +++++++++++++++ ChangeLog | 5 + Makefile | 79 ++++ README | 48 +++ TODO | 24 ++ installworld | 25 ++ libtar-1.2.4.tar.gz | Bin 0 -> 73513 bytes makepkg | 88 ++++ makepkg.conf | 8 + makeworld | 29 ++ pacman.8.in | 72 ++++ pacman.c | 980 ++++++++++++++++++++++++++++++++++++++++++++ pacman.h | 64 +++ 13 files changed, 1762 insertions(+) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile create mode 100644 README create mode 100644 TODO create mode 100755 installworld create mode 100644 libtar-1.2.4.tar.gz create mode 100755 makepkg create mode 100644 makepkg.conf create mode 100755 makeworld create mode 100644 pacman.8.in create mode 100644 pacman.c create mode 100644 pacman.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..96e45911 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + 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/ChangeLog b/ChangeLog new file mode 100644 index 00000000..6a9a6b89 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,5 @@ +VERSION DESCRIPTION +------------------------------------------------------------------ + - Changed db_find_conflicts() to ignore directories +1.0 - Initial Release + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..58de8a2a --- /dev/null +++ b/Makefile @@ -0,0 +1,79 @@ +# +# pacman +# +# Copyright (c) 2002 by Judd Vinet +# +# 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. +# + +# NOTE: Since pacman is compiled statically, you will need the static +# libraries for zlib and glibc. + +DESTDIR = +BINDIR = /usr/bin +MANDIR = /usr/man +ETCDIR = /etc + +VERSION = 1.0 +LIBTAR_VERSION = 1.2.4 + +CXX = gcc +CXXFLAGS += -DNDEBUG -O2 -Wall -pedantic -fno-exceptions -fno-rtti \ + -D_GNU_SOURCE -DVERSION=\"$(VERSION)\" -Ilibtar-$(LIBTAR_VERSION)/lib +LDFLAGS += -static -Llibtar-$(LIBTAR_VERSION)/lib -ltar -lz + +OBJECTS = pacman.o + +all: libtar pacman man + +pacman: $(OBJECTS) + $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) + +pacman.o: pacman.c pacman.h + $(CXX) $(CXXFLAGS) -c pacman.c + +man: pacman.8 + +%: %.in + sed -e "s/#VERSION#/$(VERSION)/" $< > $@ + +dist: distclean + (cd ..; tar czvf pacman-$(VERSION).tar.gz pacman-$(VERSION)) + +libtar: + (tar xzf libtar-$(LIBTAR_VERSION).tar.gz; \ + cd libtar-$(LIBTAR_VERSION); \ + LDFLAGS="" ./configure --disable-encap --disable-encap-install; \ + make;) + +install: all + install -D -m0755 pacman $(DESTDIR)$(BINDIR)/pacman + install -D -m0644 pacman.8 $(DESTDIR)$(MANDIR)/man8/pacman.8 + install -D -m0755 makepkg $(DESTDIR)$(BINDIR)/makepkg + install -D -m0755 makeworld $(DESTDIR)$(BINDIR)/makeworld + @echo "" + @echo "*** If this is a first-time install, you should copy makepkg.conf" + @echo "*** to /etc now." + @echo "" + +clean: + rm -f *~ *.o *.8 + +distclean: clean + rm -f pacman + rm -rf libtar-$(LIBTAR_VERSION) + +# End of file diff --git a/README b/README new file mode 100644 index 00000000..26cab790 --- /dev/null +++ b/README @@ -0,0 +1,48 @@ + + pacman - Package Management Utility + + by Judd Vinet + +DESCRIPTION: +------------ + pacman is a utility which manages software packages in Linux. It uses + simple .tar.gz files as a package format, and maintains a text-based + package database, just in case some hand tweaking is necessary. + + pacman does not strive to "do everything." It will add, remove and + upgrade packages in the system, and it will allow you to query the + package database for installed packages, files and owners. + + Plans exist for dependency checking and remote file fetching, as well. + See TODO for more info. + + +INSTALL: +-------- +$ make install +or +$ make DESTDIR=/your/path/here install + +If your man files are located in a directory other than /usr/man, you may +want to edit Makefile and modify the MANDIR line accordingly. + +Note: Since pacman is compiled statically, you will need the static libraries + for glibc and zlib. + + +BUGS: +----- +If you find bugs (which is quite likely at version 1.0), please submit +them to with specific information, such as your +commandline, the nature of the bug, and even the package database, if +it helps. + + +COPYRIGHT: +---------- +pacman is Copyright (c) 2002 Judd vinet and is +licensed through the GNU General Public License (see COPYING). + +pacman uses "libtar", a library for reading/writing tar-files. This +library is Copyright (c) 1998-2001 Mark D. Roth (see +libtar-X.X.X/COPYRIGHT for further details). diff --git a/TODO b/TODO new file mode 100644 index 00000000..a08e2597 --- /dev/null +++ b/TODO @@ -0,0 +1,24 @@ +These are things that should get done at some point. Some are simple, +others are more complex and could be a while in development. + +- add a [sibling] option to .PKGINFO -- used when only one of + the siblings can be installed at a time (eg, bsdinit,sysvinit) +- handle wildcards on the command line +- sort packages by package name in pacman.db +- manage conditional file installs (ie, 'info' pages) +- make sure program consistently returns a non-zero return code on + error, so scripts can rely on it +- maybe add a 'confirm every action' option for doing paranoid installs +- add better directory tracking + - use crux's pkgmk technique. $(make prefix=$PKG/usr install) then just + $(cd $PKG; tar czf $pkg.tar.gz *) +- add a consistency check operation +- change char[xxx] to char[PATH_MAX] +- add file locking to db +- add a --dbpath option +- dependency checking +- fetch files via ftp + - need to manage foreign package lists like apt +- handle .save files better (for more than just .conf files) +- upgrade currently does a double db backup; not really desirable + diff --git a/installworld b/installworld new file mode 100755 index 00000000..fd155622 --- /dev/null +++ b/installworld @@ -0,0 +1,25 @@ +#!/bin/bash + +if [ "$1" = "" ]; then + echo "usage: $0 " + echo "" + echo "call this while in the root of the install tree and" + echo "pass it the path of the directory containing packages" + echo "to be installed" + echo "" + exit +fi + +echo "Initializing pacman database..." +mkdir -p var/lib/pacman && touch var/lib/pacman/pacman.db + +for pkg in `find $1/*`; do + echo "==> $pkg" >>install.log + echo "==> $pkg" + pacman -A -r . $pkg 2>&1 >>install.log +done + +echo "Syncing..." +sync + +echo "Done." diff --git a/libtar-1.2.4.tar.gz b/libtar-1.2.4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..24291e5557765370fe842cf2a3ebeccd92c8a1d4 GIT binary patch literal 73513 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
^7nU^-^A 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 literal 0 HcmV?d00001 diff --git a/makepkg b/makepkg new file mode 100755 index 00000000..b9ad4bcb --- /dev/null +++ b/makepkg @@ -0,0 +1,88 @@ +#!/bin/bash + +me=`basename $0` +myver='1.0' +startdir=`pwd` + +[ -f /etc/makepkg.conf ] && . /etc/makepkg.conf + +strip_url() { + echo $1 | sed 's|^.*://.*/||g' +} + +if [ ! -f $startdir/PKGBUILD ]; then + echo "error: $startdir/PKGBUILD does not exist!" + exit +fi + +. $startdir/PKGBUILD + +# extract source +echo "==> Acquiring/Extracting Sources..." +mkdir -p src pkg +cd $startdir/src +for netfile in ${source[@]}; do + file=`strip_url $netfile` + if [ -f ../$file ]; then + echo "==> Found $file in build dir" + cp ../$file . + elif [ -f /var/cache/pkg/$file ]; then + echo "==> Using local copy of $file" + cp /var/cache/pkg/$file . + else + echo "==> Downloading $file" + wget --passive-ftp --no-directories --tries=3 --waitretry=3 $netfile + if [ ! -f $file ]; then + echo "==> ERROR: Failed to download $file" + echo "==> Aborting..." + exit 1 + fi + mkdir -p /var/cache/pkg && cp $file /var/cache/pkg + fi + case $file in + *.tar.gz|*.tar.Z|*.tgz) + cmd="tar --use-compress-program=gzip -xf $file" ;; + *.tar.bz2) + cmd="tar --use-compress-program=bzip2 -xf $file" ;; + *.zip) + cmd="unzip -qq $file" ;; + *) + cmd="cp ../$file ." ;; + esac + echo "$cmd" + $cmd +done + +# build +echo "==> Building Package..." +build + +# write the .PKGINFO file +echo "==> Generating .PKGINFO file..." +cd $startdir/pkg +echo "# Generated by makepkg $myver" >.PKGINFO +echo -n "# " >>.PKGINFO +date >>.PKGINFO +echo "pkgname = $pkgname" >>.PKGINFO +echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO + +# remove info files +cd $startdir +rm -rf pkg/usr/info pkg/usr/share/info + +# strip binaries +cd $startdir +echo "==> Stripping debugging symbols from libraries..." +find pkg/{,usr,usr/local}/lib -type f \ + -exec /usr/bin/strip --strip-debug '{}' ';' +echo "==> Stripping symbols from binaries..." +find pkg/{,usr,usr/local}/{bin,sbin} -type f \ + -exec /usr/bin/strip '{}' ';' + +# tar it up +echo "==> Compressing package..." +cd $startdir/pkg +tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist + +cd $startdir +echo "==> Finished"; diff --git a/makepkg.conf b/makepkg.conf new file mode 100644 index 00000000..0532f589 --- /dev/null +++ b/makepkg.conf @@ -0,0 +1,8 @@ +# +# /etc/pkgmake.conf +# + +export CFLAGS="-O2 -march=i686 -pipe" +export CXXFLAGS="-O2 -march=i686 -pipe" + +# End of file diff --git a/makeworld b/makeworld new file mode 100755 index 00000000..a6c0b470 --- /dev/null +++ b/makeworld @@ -0,0 +1,29 @@ +#!/bin/bash + +toplevel=`pwd` + +if [ $# -lt 1 ]; then + echo "usage: $0 " + exit 1 +fi + +for port in `find $toplevel -type d -maxdepth 1 -mindepth 1 | sort`; do + cd $port + if [ -f PKGBUILD ]; then + . PKGBUILD + donebuild=0 + if [ ! -f $1/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then + makepkg + rm -rf pkg src + mv -v $pkgname-$pkgver-$pkgrel.pkg.tar.gz $1/ + donebuild=1 + fi + d=`date +"[%b %d %H:%M]"` + echo -n "$d " >>$toplevel/build.log + if [ $donebuild = 1 ]; then + echo "$pkgname was built successfully" >>$toplevel/build.log + else + echo "$pkgname already built -- skipping" >>$toplevel/build.log + fi + fi +done diff --git a/pacman.8.in b/pacman.8.in new file mode 100644 index 00000000..2db57ced --- /dev/null +++ b/pacman.8.in @@ -0,0 +1,72 @@ +.TH pacman 8 "Feb 10, 2002" "pacman #VERSION#" "" +.SH NAME +pacman \- package manager utility +.SH SYNOPSIS +\fBpacman [options] \fP +.SH DESCRIPTION +\fBpacman\fP is a \fIpackage management\fP utility. Package +information is maintained in a basic text format for easy +tweaking, if necessary, and packages are in a standard +\fIgzipped tar\fP format. +.SH OPERATIONS +.TP +.B "\-A, \-\-add" +Add a package to the system. Package will be uncompressed +into the installation root and the database will be updated. +.TP +.B "\-R, \-\-remove" +Remove a package from the system. Files belonging to the +specified package will be deleted, and the database will +be updated. Note that files with \fI.conf\fP extensions will +be renamed with \fI.conf.save\fP extensions. +.TP +.B "\-U, \-\-upgrade" +Upgrade a package. This is essentially a "remove-then-install" +process. Files with \fI.conf\fP extensions will be saved. +.TP +.B "\-Q, \-\-query" +Query the package database. This operation allows you to +view installed packages and their files. See \fBQUERY OPTIONS\fP +below. +.TP +.B "\-V, \-\-version" +Display version and exit. +.TP +.B "\-h, \-\-help" +Display syntax for the given operation. If no operation was +supplied, then the general syntax is shown. +.SH QUERY OPTIONS +.TP +.B "\-o, \-\-owns " +Output the name of the package that owns . +.TP +.B "\-l, \-\-list" +Instead of outputting the package name, output the list of +files owned by the package. +.TP +.B "\-i, \-\-info" +Output the .PKGINFO file contained in . This option +can only be used with the \fB-p\fP option. +.SH OPTIONS +.TP +.B "\-v, \-\-verbose" +Output more status and error messages. +.TP +.B "\-f, \-\-force" +Force installation, overwriting 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. +.SH AUTHOR +.nf +Judd Vinet +.fi diff --git a/pacman.c b/pacman.c new file mode 100644 index 00000000..60c99726 --- /dev/null +++ b/pacman.c @@ -0,0 +1,980 @@ +/** + * pacman + * + * Copyright (c) 2002 by Judd Vinet + * + * 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 "pacman.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* borrowed and modifed from Per Liden's pkgutils (http://crux.nu) */ +static int gzopen_frontend(char *pathname, int oflags, int mode) +{ + char* gzoflags; + int fd; + gzFile gzf; + + switch (oflags & O_ACCMODE) { + case O_WRONLY: + gzoflags = "w"; + break; + case O_RDONLY: + gzoflags = "r"; + break; + case O_RDWR: + default: + errno = EINVAL; + return -1; + } + + if((fd = open(pathname, oflags, mode)) == -1) { + return -1; + } + if((oflags & O_CREAT) && fchmod(fd, mode)) { + return -1; + } + if(!(gzf = gzdopen(fd, gzoflags))) { + errno = ENOMEM; + return -1; + } + + return (int)gzf; +} + +static tartype_t gztype = { + (openfunc_t) gzopen_frontend, + (closefunc_t)gzclose, + (readfunc_t) gzread, + (writefunc_t)gzwrite +}; + +/* + * GLOBALS + * + */ +FILE* dbfp = NULL; +char* dbpath = PKGDB; +char* pkgname = NULL; +char* pkgver = NULL; + +char* pmo_root = NULL; +unsigned short pmo_verbose = 0; +unsigned short pmo_force = 0; +unsigned short pmo_upgrade = 0; +unsigned short pmo_nosave = 0; +unsigned short pmo_nofunc = 0; +unsigned short pmo_q_isfile = 0; +unsigned short pmo_q_info = 0; +unsigned short pmo_q_list = 0; +char* pmo_q_owns = NULL; + +pkginfo_t** packages = NULL; +unsigned int pkgcount = 0; + + +int main(int argc, char* argv[]) +{ + pm_opfunc_t op_func; + char* funcvar = NULL; + int ret = 0; + + /* default root */ + pmo_root = (char*)malloc(2); + strcpy(pmo_root, "/"); + + if(argc < 2) { + usage(PM_MAIN, (char*)basename(argv[0])); + return(0); + } + + /* determine the requested operation and pass off to */ + /* the handler function */ + if(!strcmp(argv[1], "-A") || !strcmp(argv[1], "--add")) { + op_func = pacman_add; + funcvar = parseargs(PM_ADD, argc, argv); + } else if(!strcmp(argv[1], "-R") || !strcmp(argv[1], "--remove")) { + op_func = pacman_remove; + funcvar = parseargs(PM_REMOVE, argc, argv); + } else if(!strcmp(argv[1], "-Q") || !strcmp(argv[1], "--query")) { + op_func = pacman_query; + funcvar = parseargs(PM_QUERY, argc, argv); + } else if(!strcmp(argv[1], "-U") || !strcmp(argv[1], "--upgrade")) { + op_func = pacman_upgrade; + funcvar = parseargs(PM_UPGRADE, argc, argv); + } else if(!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + usage(PM_MAIN, (char*)basename(argv[0])); + return(1); + } else if(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) { + version(); + return(1); + } else { + printf("error: invalid operation\n\n"); + usage(PM_MAIN, (char*)basename(argv[0])); + return(1); + } + + if(funcvar == NULL && op_func != pacman_query) { + return(1); + } + vprint("Installation Root: %s\n", pmo_root); + vprint("Package Name: %s\n", funcvar); + + /* check for db existence */ + if(pmo_root != NULL) { + /* trim the trailing '/' if there is one */ + if((int)rindex(pmo_root, '/') == ((int)pmo_root)+strlen(pmo_root)-1) { + pmo_root[strlen(pmo_root)-1] = '\0'; + } + free(dbpath); + dbpath = (char*)malloc(strlen(pmo_root) + strlen(PKGDB) + 1); + strcpy(dbpath, pmo_root); + dbpath = (char*)strcat(dbpath, PKGDB); + } + vprint("Using package DB: %s\n", dbpath); + + ret = db_open(dbpath); + if(ret == 1) { + printf("error: Could not open package database file!\n"); + printf(" Check to see that %s exists.\n", dbpath); + printf(" If not, you may simply create it by \"touch\"-ing it.\n"); + return(1); + } + if(ret == 2) { + printf("error: Database is corrupt! You may need to use the backup database.\n"); + printf(" I hope you like tweaking... ;-)\n"); + return(1); + } + + /* start the requested operation */ + if(!pmo_nofunc) { + ret = op_func(funcvar); + if(ret) { + printf("There were errors\n"); + } + } + + fclose(dbfp); + return(0); +} + +int pacman_add(char* pkgfile) +{ + int i, errors = 0; + TAR* tar; + char* errmsg = NULL; + char* expath = NULL; + char* newpath = NULL; + fileset_t files = NULL; + unsigned int filecount = 0; + struct stat buf; + + /* Populate the file list */ + filecount = load_pkg(pkgfile, &files, 0); + if(filecount == 0) { + return(1); + } + + /* Now check for conflicts in the db */ + vprint("Looking for DB conflicts...\n"); + if((i = db_find_conflicts(files, filecount)) == 1) { + if(pmo_force) { + printf("\nInstalling package anyway...\n"); + printf(" You might have duplicate entries in your package\n"); + printf(" database now. You may want to edit it and remove\n"); + printf(" one of the copies.\n\n"); + } else { + printf("Aborting...\n"); + printf(" (use -f to override)\n\n"); + return(1); + } + } else if(i == 2) { + return(1); + } else { + vprint("No DB conflicts found\n"); + } + + /* see if this is an upgrade. if so, remove the old package first */ + if(pmo_upgrade) { + vprint("Removing old package first...\n"); + if(pacman_remove(pkgname)) { + printf("\nUpgrade aborted.\n"); + return(1); + } + } + + /* open the .tar.gz package */ + if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + perror("could not open package"); + return(1); + } + vprint("Extracting files...\n"); + for(i = 0; !th_read(tar); i++) { + if(!strcmp(th_get_pathname(tar), ".PKGINFO")) { + tar_skip_regfile(tar); + continue; + } + /* build the new pathname relative to pmo_root */ + expath = (char*)malloc(strlen(th_get_pathname(tar))+strlen(pmo_root)+2); + strcpy(expath, pmo_root); + strcat(expath, "/"); + strcat(expath, th_get_pathname(tar)); + vprint(" %s\n", expath); + if(!stat(expath, &buf)) { + /* if the file ends in .conf, back it up */ + if(!strcmp((char*)(expath+strlen(expath)-5), ".conf")) { + newpath = (char*)realloc(newpath, strlen(expath)+6); + strcpy(newpath, expath); + strcat(newpath, ".save"); + rename(expath, newpath); + printf("%s renamed to %s\n", expath, newpath); + } + } + if(tar_extract_file(tar, expath)) { + errmsg = strerror(errno); + printf("could not extract %s: %s\n", th_get_pathname(tar), errmsg); + errors = 1; + } + free(expath); + } + tar_close(tar); + vprint("Done.\n"); + if(errors) { + printf("There were errors. No database update was performed.\n"); + } else { + vprint("Updating database...\n"); + if(db_update(files, filecount)) { + printf("error: Could not update database! The database may not\n"); + printf(" be in a sane state!\n"); + return(1); + } + vprint("Done.\n"); + } + return(0); +} + +int pacman_remove(char* pkgfile) +{ + int found = 0, done = 0; + int i; + char line[255]; + fileset_t files = NULL; + unsigned int filecount = 0; + struct stat buf; + char* newpath = NULL; + + if(pkgfile == NULL) { + return(0); + } + + /* find the package's filelist in the db */ + rewind(dbfp); + while(!found && !feof(dbfp)) { + fgets(line, 255, dbfp); + strcpy(line, trim(line)); + if(!strcmp(line, pkgfile)) { + /* read the version */ + fgets(line, 255, dbfp); + found = 1; + } + } + if(!found) { + printf("Cannot remove %s: Package was not found.\n", pkgfile); + return(1); + } + + while(!done) { + fgets(line, 255, dbfp); + strcpy(line, trim(line)); + if(strlen(line)) { + /* add the path to the list */ + files = (fileset_t)realloc(files, (++filecount) * sizeof(char*)); + files[filecount-1] = (char*)malloc(strlen(line)+1); + strcpy(files[filecount-1], line); + } else { + done = 1; + } + } + /* iterate through the list backwards, unlinking files */ + for(i = filecount-1; i >= 0; i--) { + if(lstat(files[i], &buf)) { + vprint("file %s does not exist\n", files[i]); + continue; + } + if(S_ISDIR(buf.st_mode)) { + vprint(" removing directory %s\n", files[i]); + if(rmdir(files[i])) { + /* this is okay, other packages are probably using it. */ + /* perror("cannot remove directory"); */ + } + } else { + /* if the file ends in .conf, back it up */ + if(!pmo_nosave && !strcmp((char*)(files[i]+strlen(files[i])-5), ".conf")) { + newpath = (char*)realloc(newpath, strlen(files[i])+6); + strcpy(newpath, files[i]); + strcat(newpath, ".save"); + rename(files[i], newpath); + printf("%s renamed to %s\n", files[i], newpath); + } else { + vprint(" unlinking %s\n", files[i]); + if(unlink(files[i])) { + perror("cannot remove file"); + } + } + } + } + + /* now splice this name out of the packages list */ + found = 0; + for(i = 0; i < pkgcount-1; i++) { + if(found) { + packages[i] = packages[i+1]; + } else { + if(!strcmp(packages[i]->name, pkgfile)) { + found = 1; + if(i < pkgcount-1) { + packages[i] = packages[i+1]; + } + } + } + } + /* drop the last item */ + packages = (pkginfo_t**)realloc(packages, (--pkgcount)*sizeof(pkginfo_t*)); + + /* and commit the db */ + return(db_update(NULL, 0)); +} + +int pacman_query(char* pkgfile) +{ + char *str = NULL; + char name[255]; + char ver[255]; + char line[255]; + int found = 0; + int done = 0; + int i; + unsigned int filecount = 0; + fileset_t files = NULL; + + /* output info for a .tar.gz package */ + if(pmo_q_isfile) { + filecount = load_pkg(pkgfile, &files, pmo_q_info); + if(pmo_q_list) { + for(i = 0; i < filecount; i++) { + if(strcmp(files[i], ".PKGINFO")) { + printf("%s\n", files[i]); + } + } + } else { + printf("%s %s\n", pkgname, pkgver); + } + + return(0); + } + + /* determine the owner of a file */ + if(pmo_q_owns != NULL) { + rewind(dbfp); + while(!found && !feof(dbfp)) { + fgets(name, 255, dbfp); + strcpy(name, trim(name)); + fgets(ver, 255, dbfp); + strcpy(ver, trim(ver)); + strcpy(line, " "); + while(strlen(line) && !feof(dbfp)) { + fgets(line, 255, dbfp); + strcpy(line, trim(line)); + str = line; + str += strlen(pmo_root); + if(!strcmp(line, pmo_q_owns)) { + printf("%s %s\n", name, ver); + return(0); + } + } + } + printf("No package owns this file.\n"); + return(0); + } + + /* find packages in the db */ + rewind(dbfp); + while(!done) { + found = 0; + while(!found && !feof(dbfp)) { + fgets(name, 255, dbfp); + strcpy(name, trim(name)); + if(pkgfile == NULL || (pkgfile != NULL && !strcmp(name, pkgfile))) { + /* read the version */ + fgets(ver, 255, dbfp); + strcpy(ver, trim(ver)); + found = 1; + if(pkgfile != NULL) { + done = 1; + } + } + } + if(feof(dbfp)) { + if(pkgfile != NULL && !found) { + printf("Package was not found in database.\n"); + } + break; + } + found = 0; + while(!found) { + fgets(line, 255, dbfp); + strcpy(line, trim(line)); + if(strlen(line)) { + if(pmo_q_list) { + printf("%s%s\n", pmo_root, line); + } + } else { + found = 1; + } + } + if(!pmo_q_list) { + printf("%s %s\n", name, ver); + } + if(feof(dbfp)) { + done = 1; + } + } + + return(0); +} + +int pacman_upgrade(char* pkgfile) +{ + /* this is basically just a remove,add process. pacman_add() will */ + /* handle it */ + pmo_upgrade = 1; + pacman_add(pkgfile); + return(0); +} + +/* + * Populate the package file list + * pkgfile: filename of package + * listptr: this will be set to the new fileset_t + * + * Returns: the number of filenames read in the package, or 0 on error + * + */ +int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output) +{ + char* expath; + char* descfile; + int i; + TAR* tar; + unsigned int filecount = 0; + fileset_t files = NULL; + + descfile = (char*)malloc(strlen("/tmp/pacman_XXXXXX")+1); + strcpy(descfile, "/tmp/pacman_XXXXXX"); + + if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + perror("could not open package"); + return(0); + } + vprint("Loading filelist from package...\n"); + for(i = 0; !th_read(tar); i++) { + if(!strcmp(th_get_pathname(tar), ".PKGINFO")) { + /* extract this file into /tmp. it has info for us */ + vprint("Found package description file.\n"); + mkstemp(descfile); + tar_extract_file(tar, descfile); + parse_descfile(descfile, output); + continue; + } + /* build the new pathname relative to pmo_root */ + expath = (char*)malloc(strlen(th_get_pathname(tar))+strlen(pmo_root)+2); + strcpy(expath, pmo_root); + strcat(expath, "/"); + strcat(expath, th_get_pathname(tar)); + /* add the path to the list */ + files = (fileset_t)realloc(files, (++filecount) * sizeof(char*)); + files[filecount-1] = expath; + + if(TH_ISREG(tar) && tar_skip_regfile(tar)) { + perror("bad package file"); + return(0); + } + expath = NULL; + } + tar_close(tar); + + if(pkgname == NULL || pkgver == NULL) { + printf("The current version of Pacman requires a .PKGINFO file\n"); + printf("present in the .tar.gz archive. This package does not\n"); + printf("have one.\n"); + return(0); + } + + (*listptr) = files; + return(filecount); +} + +/* Open the database file + * path: the full pathname of the file + */ +int db_open(char* path) +{ + char line[255]; + pkginfo_t* info; + dbfp = fopen(path, "r"); + if(dbfp == NULL) { + return(1); + } + while(!feof(dbfp)) { + info = (pkginfo_t*)malloc(sizeof(pkginfo_t)); + fgets(line, 64, dbfp); + if(feof(dbfp)) { + break; + } + strcpy(info->name, trim(line)); + fgets(line, 32, dbfp); + strcpy(info->version, trim(line)); + /* add to the collective */ + packages = (pkginfo_t**)realloc(packages, (++pkgcount) * sizeof(pkginfo_t*)); + packages[pkgcount-1] = info; + for(;;) { + fgets(line, 255, dbfp); + if(feof(dbfp)) { + return(2); + } + if(strlen(trim(line)) == 0) { + break; + } + } + } + + return(0); +} + +/* Copy the old database file to a backup and build the + * new copy in its place. + * files: list of files in the new package, can be null + * filecount: number of entries in files + * + * Returns: 0 on success + * + */ +int db_update(fileset_t files, unsigned int filecount) +{ + FILE* olddb; + char* newpath = NULL; + char* str = NULL; + char name[64]; + char ver[32]; + char line[255]; + int i = 0, found = 0, done = 0; + + /* build the backup pathname */ + newpath = (char*)malloc(strlen(dbpath)+5); + strcpy(newpath, dbpath); + strcat(newpath, ".bak"); + + /* rename the existing db */ + fclose(dbfp); + rename(dbpath, newpath); + + olddb = fopen(newpath, "r"); + free(newpath); + dbfp = fopen(dbpath, "w"); + if(olddb == NULL || dbfp == NULL) { + return(1); + } + + rewind(olddb); + while(!feof(olddb)) { + if(!fgets(name, 64, olddb)) { + break; + } + strcpy(name, trim(name)); + fgets(ver, 32, olddb); + found = 0; + for(i = 0; i < pkgcount && !found; i++) { + if(!strcmp(packages[i]->name, name)) { + /* it's there... copy the entries over */ + found = 1; + fputs(name, dbfp); + fputc('\n', dbfp); + fputs(ver, dbfp); + for(done = 0; !done;) { + fgets(line, 255, olddb); + if(found) { + fputs(line, dbfp); + } + if(strlen(trim(line)) == 0 || feof(olddb)) { + done = 1; + } + } + } + } + if(!found) { + /* skip through filelist for this package */ + for(done = 0; !done;) { + fgets(line, 255, olddb); + if(strlen(trim(line)) == 0 || feof(olddb)) { + done = 1; + } + } + } + } + fclose(olddb); + + /* write the current info */ + if(files != NULL) { + fputs(pkgname, dbfp); + fputc('\n', dbfp); + fputs(pkgver, dbfp); + fputc('\n', dbfp); + for(i = 0; i < filecount; i++) { + str = files[i]; + str += strlen(pmo_root); + fputs(str, dbfp); + fputc('\n', dbfp); + } + fputs("\n", dbfp); + } + fclose(dbfp); + db_open(dbpath); + + return(0); +} + +/* Check the database for conflicts + * files: list of files in the new package + * filecount: number of entries in files + * + * Returns: 0 if no conflicts were found, 1 otherwise + * + */ +int db_find_conflicts(fileset_t files, unsigned int filecount) +{ + int i; + char line[255]; + char name[255]; + struct stat buf; + int conflicts = 0; + + /* CHECK 1: checking db conflicts */ + rewind(dbfp); + while(!feof(dbfp)) { + fgets(name, 255, dbfp); + strcpy(name, trim(name)); + if(!pmo_upgrade && !strcmp(name, pkgname)) { + printf("error: This package is already installed.\n"); + printf(" Maybe you should be using --upgrade.\n"); + return(2); + } + fgets(line, 255, dbfp); + while(!feof(dbfp)) { + fgets(line, 255, dbfp); + strcpy(line, trim(line)); + if(!strlen(line)) { + break; + } + if(index(line, '/') == (char*)line && (!pmo_upgrade || strcmp(name,pkgname))) { + for(i = 0; i < filecount; i++) { + if(!strcmp(line, files[i])) { + if(rindex(files[i], '/') == files[i]+strlen(files[i])-1) { + /* this filename has a trailing '/', so it's a directory -- skip it. */ + continue; + } + printf("conflict: %s already exists in package \"%s\"\n", line, name); + conflicts = 1; + } + } + } + } + } + + /* CHECK 2: checking filesystem conflicts */ + /* TODO: run filesystem checks for upgrades */ + for(i = 0; i < filecount && !pmo_upgrade; i++) { + if(!stat(files[i], &buf) && !S_ISDIR(buf.st_mode)) { + printf("conflict: %s already exists in filesystem\n", files[i]); + conflicts = 1; + } + } + + return(conflicts); +} + +/* Parses the package description file for the current package + * descfile: the full pathname of the description file + * + * Returns: 0 on success, 1 on error + * + */ +int parse_descfile(char* descfile, unsigned short output) +{ + FILE* fp; + char line[255]; + char* ptr = NULL; + char* key = NULL; + int linenum = 0; + + if((fp = fopen(descfile, "r")) == NULL) { + perror(descfile); + return(1); + } + + while(!feof(fp)) { + fgets(line, 255, fp); + if(output) { + printf("%s", line); + } + linenum++; + strcpy(line, trim(line)); + if(index(line, '#') == (char*)line) { + continue; + } + if(strlen(line) == 0) { + continue; + } + ptr = line; + key = strsep(&ptr, "="); + if(key == NULL || ptr == NULL) { + printf("Syntax error in description file line %d\n", linenum); + } else { + key = trim(key); + key = strtoupper(key); + ptr = trim(ptr); + if(!strcmp(key, "PKGNAME")) { + pkgname = (char*)malloc(strlen(ptr)+1); + strcpy(pkgname, ptr); + } else if(!strcmp(key, "PKGVER")) { + pkgver = (char*)malloc(strlen(ptr)+1); + strcpy(pkgver, ptr); + } else if(!strcmp(key, "PKGDESC")) { + /* Not used yet */ + } else { + printf("Syntax error in description file line %d\n", linenum); + } + } + line[0] = '\0'; + } + fclose(fp); + unlink(descfile); + return(0); +} + +/* Parse command-line arguments for each operation + * op: the operation code requested + * argc: argc + * argv: argv + * + * Returns: the functional variable for that operation + * (eg, the package file name for PM_ADD) + */ +char* parseargs(int op, int argc, char** argv) +{ + char* pkg = NULL; + int i; + + for(i = 2; i < argc; i++) { + if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + pmo_nofunc = 1; + usage(op, (char*)basename(argv[0])); + return(NULL); + } else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) { + pmo_verbose = 1; + } else if(!strcmp(argv[i], "-f") || !strcmp(argv[i], "--force")) { + pmo_force = 1; + } else if(!strcmp(argv[i], "-r") || !strcmp(argv[i], "--root")) { + i++; + if(i >= argc) { + printf("error: missing argument for %s\n", argv[i-1]); + return(NULL); + } + free(pmo_root); + pmo_root = (char*)malloc(PATH_MAX); + if(realpath(argv[i], pmo_root) == NULL) { + perror("bad root path"); + return(NULL); + } + } else if(!strcmp(argv[i], "-n") || !strcmp(argv[i], "--nosave")) { + pmo_nosave = 1; + } else if(!strcmp(argv[i], "-o") || !strcmp(argv[i], "--owns")) { + /* PM_QUERY only */ + i++; + if(i >= argc) { + printf("error: missing argument for %s\n", argv[i-1]); + return(NULL); + } + free(pmo_q_owns); + pmo_q_owns = (char*)malloc(PATH_MAX); + if(realpath(argv[i], pmo_q_owns) == NULL) { + perror("bad path specified for --owns"); + pmo_nofunc = 1; + return(NULL); + } + } else if(!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) { + /* PM_QUERY only */ + pmo_q_list = 1; + } else if(!strcmp(argv[i], "-p") || !strcmp(argv[i], "--file")) { + /* PM_QUERY only */ + pmo_q_isfile = 1; + } else if(!strcmp(argv[i], "-i") || !strcmp(argv[i], "--info")) { + /* PM_QUERY only */ + pmo_q_info = 1; + } else { + pkg = argv[i]; + } + } + + if(op != PM_QUERY && pkg == NULL) { + printf("error: no package specified\n\n"); + usage(op, (char*)basename(argv[0])); + return(NULL); + } + if(op == PM_QUERY && pmo_q_isfile && pkg == NULL) { + printf("error: no package file specified\n\n"); + return(NULL); + } + return(pkg); +} + +/* Display usage/syntax for the specified operation. + * op: the operation code requested + * myname: basename(argv[0]) + */ +void usage(int op, char* myname) +{ + if(op == PM_MAIN) { + printf("usage: %s {-h --help}\n", myname); + printf(" %s {-V --version}\n", myname); + printf(" %s {-A --add} [options] \n", myname); + printf(" %s {-R --remove} [options] \n", myname); + printf(" %s {-U --upgrade} [options] \n", myname); + printf(" %s {-Q --query} [options] [package]\n", myname); + } else if(op == PM_ADD) { + printf("usage: %s {-A --add} [options] \n", myname); + printf("options:\n"); + printf(" -f, --force force install, overwrite conflicting files\n"); + printf(" -n, --nosave do not save .conf files\n"); + printf(" -v, --verbose be verbose\n"); + printf(" -r, --root set an alternative installation root\n"); + } else if(op == PM_REMOVE) { + printf("usage: %s {-R --remove} [options] \n", myname); + printf("options:\n"); + printf(" -n, --nosave do not save .conf files\n"); + printf(" -v, --verbose be verbose\n"); + printf(" -r, --root set an alternative installation root\n"); + } else if(op == PM_UPGRADE) { + printf("usage: %s {-U --upgrade} [options] \n", myname); + printf("options:\n"); + printf(" -f, --force force install, overwrite conflicting files\n"); + printf(" -n, --nosave do not save .conf files\n"); + printf(" -v, --verbose be verbose\n"); + printf(" -r, --root set an alternative installation root\n"); + } else if(op == PM_QUERY) { + printf("usage: %s {-Q --query} [options] [package]\n", myname); + printf("options:\n"); + printf(" -r, --root set an alternative installation root\n"); + printf(" -o, --owns query the package that owns \n"); + printf(" -l, --list list the contents of the queried package\n"); + printf(" -i, --info output the .PKGINFO file (only used with -p)\n"); + printf(" -p, --file if used, then [package] will be the path\n"); + printf(" to an (uninstalled) package to query\n"); + } +} + +/* Version + */ +void version(void) +{ + printf("\n"); + printf(" .--. Pacman v%s\n", VERSION); + printf("/ _.-' .-. .-. .-. Copyright (C) 2002 Judd Vinet \n"); + printf("\\ '-. '-' '-' '-' \n"); + printf(" '--' This program may be freely redistributed under\n"); + printf(" the terms of the GNU GPL\n\n"); +} + +/* Check verbosity option and, if set, print the + * string to stdout + */ +int vprint(char* fmt, ...) +{ + va_list args; + if(pmo_verbose) { + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + fflush(stdout); + } + return(0); +} + +/* Convert a string to uppercase + */ +char* strtoupper(char* str) +{ + char* ptr = str; + + while(*ptr) { + (*ptr) = toupper(*ptr); + ptr++; + } + return str; +} + +/* Trim whitespace and newlines from a string + */ +char* trim(char* str) +{ + char* start = str; + char* end = str + strlen(str); + int mid = 0; + char ch; + + while(mid < 2) { + if(!mid) { + ch = *start; + if(ch == 10 || ch == 13 || ch == 9 || ch == 32) { + start++; + } else { + mid = 1; + } + } else { + end--; + ch = *end; + if(ch == 10 || ch == 13 || ch == 9 || ch == 32) { + *end = '\0'; + } else { + mid = 2; + } + } + } + return(start); +} + +/* vim: set ts=2 noet: */ diff --git a/pacman.h b/pacman.h new file mode 100644 index 00000000..c9f4fdb0 --- /dev/null +++ b/pacman.h @@ -0,0 +1,64 @@ +/* + * pacman + * + * Copyright (c) 2002 by Judd Vinet + * + * 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 PACMAN_H +#define PACMAN_H + +#define VERSION "1.0" + +#define PKGEXT ".tar.gz" +#define PKGDB "/var/lib/pacman/pacman.db" + +/* Operations */ +#define PM_MAIN 0 +#define PM_ADD 1 +#define PM_REMOVE 2 +#define PM_QUERY 3 +#define PM_UPGRADE 4 + +typedef int (*pm_opfunc_t)(char*); +typedef char** fileset_t; +typedef struct __pkginfo_t { + char version[32]; + char name[64]; +} pkginfo_t; + +int pacman_add(char* pkgfile); +int pacman_remove(char* pkgfile); +int pacman_query(char* pkgfile); +int pacman_upgrade(char* pkgfile); + +int db_open(char* path); +int db_update(fileset_t files, unsigned int filecount); +int db_find_conflicts(fileset_t files, unsigned int filecount); +int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output); + +int vprint(char* fmt, ...); +void usage(int op, char* myname); +void version(void); +char* parseargs(int op, int argc, char** argv); +int parse_descfile(char* descfile, unsigned short output); +char* trim(char* str); +char* strtoupper(char* str); +static int gzopen_frontend(char *pathname, int oflags, int mode); + +#endif /* PACMAN_H */ + +/* vim: set ts=2 noet: */