Imported from pacman-1.0.tar.gz
This commit is contained in:
commit
d53b2011b1
13 changed files with 1762 additions and 0 deletions
340
COPYING
Normal file
340
COPYING
Normal file
|
@ -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.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 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.
|
5
ChangeLog
Normal file
5
ChangeLog
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
VERSION DESCRIPTION
|
||||||
|
------------------------------------------------------------------
|
||||||
|
- Changed db_find_conflicts() to ignore directories
|
||||||
|
1.0 - Initial Release
|
||||||
|
|
79
Makefile
Normal file
79
Makefile
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#
|
||||||
|
# pacman
|
||||||
|
#
|
||||||
|
# Copyright (c) 2002 by Judd Vinet <jvinet@zeroflux.org>
|
||||||
|
#
|
||||||
|
# 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
|
48
README
Normal file
48
README
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
pacman - Package Management Utility
|
||||||
|
|
||||||
|
by Judd Vinet <jvinet@zeroflux.org>
|
||||||
|
|
||||||
|
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 <jvinet@zeroflux.org> 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 <jvinet@zeroflux.org> 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 <roth@uiuc.edu> (see
|
||||||
|
libtar-X.X.X/COPYRIGHT for further details).
|
24
TODO
Normal file
24
TODO
Normal file
|
@ -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
|
||||||
|
|
25
installworld
Executable file
25
installworld
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$1" = "" ]; then
|
||||||
|
echo "usage: $0 <pkg_directory>"
|
||||||
|
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."
|
BIN
libtar-1.2.4.tar.gz
Normal file
BIN
libtar-1.2.4.tar.gz
Normal file
Binary file not shown.
88
makepkg
Executable file
88
makepkg
Executable file
|
@ -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";
|
8
makepkg.conf
Normal file
8
makepkg.conf
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#
|
||||||
|
# /etc/pkgmake.conf
|
||||||
|
#
|
||||||
|
|
||||||
|
export CFLAGS="-O2 -march=i686 -pipe"
|
||||||
|
export CXXFLAGS="-O2 -march=i686 -pipe"
|
||||||
|
|
||||||
|
# End of file
|
29
makeworld
Executable file
29
makeworld
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
toplevel=`pwd`
|
||||||
|
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "usage: $0 <destdir>"
|
||||||
|
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
|
72
pacman.8.in
Normal file
72
pacman.8.in
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
.TH pacman 8 "Feb 10, 2002" "pacman #VERSION#" ""
|
||||||
|
.SH NAME
|
||||||
|
pacman \- package manager utility
|
||||||
|
.SH SYNOPSIS
|
||||||
|
\fBpacman <operation> [options] <package>\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 <file>"
|
||||||
|
Output the name of the package that owns <file>.
|
||||||
|
.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 <package>. 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 <path>"
|
||||||
|
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 <jvinet@zeroflux.org>
|
||||||
|
.fi
|
980
pacman.c
Normal file
980
pacman.c
Normal file
|
@ -0,0 +1,980 @@
|
||||||
|
/**
|
||||||
|
* pacman
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 by Judd Vinet <jvinet@zeroflux.org>
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <libtar.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
/* 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] <file>\n", myname);
|
||||||
|
printf(" %s {-R --remove} [options] <package>\n", myname);
|
||||||
|
printf(" %s {-U --upgrade} [options] <file>\n", myname);
|
||||||
|
printf(" %s {-Q --query} [options] [package]\n", myname);
|
||||||
|
} else if(op == PM_ADD) {
|
||||||
|
printf("usage: %s {-A --add} [options] <file>\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 <path> set an alternative installation root\n");
|
||||||
|
} else if(op == PM_REMOVE) {
|
||||||
|
printf("usage: %s {-R --remove} [options] <package>\n", myname);
|
||||||
|
printf("options:\n");
|
||||||
|
printf(" -n, --nosave do not save .conf files\n");
|
||||||
|
printf(" -v, --verbose be verbose\n");
|
||||||
|
printf(" -r, --root <path> set an alternative installation root\n");
|
||||||
|
} else if(op == PM_UPGRADE) {
|
||||||
|
printf("usage: %s {-U --upgrade} [options] <file>\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 <path> 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 <path> set an alternative installation root\n");
|
||||||
|
printf(" -o, --owns <file> query the package that owns <file>\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 <jvinet@zeroflux.org>\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: */
|
64
pacman.h
Normal file
64
pacman.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* pacman
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 by Judd Vinet <jvinet@zeroflux.org>
|
||||||
|
*
|
||||||
|
* 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: */
|
Loading…
Add table
Reference in a new issue