Imported from pacman-2.0.tar.gz
This commit is contained in:
parent
20b7462293
commit
62a783a6bd
50 changed files with 15380 additions and 2069 deletions
|
@ -1,5 +1,14 @@
|
|||
VERSION DESCRIPTION
|
||||
------------------------------------------------------------------
|
||||
- Improved dependency resolution and sorting
|
||||
2.0 - Added dependency functionality
|
||||
- Completely new database format, similar to FreeBSD
|
||||
- Better internal data structures
|
||||
- Merged pacsync functionality into pacman
|
||||
- Now uses libftp for all file retrieval (currently only ftp)
|
||||
- Automatic dependency resolution, a la apt-get
|
||||
- Moved config stuff from /etc/pacsync.conf to /etc/pacman.conf
|
||||
- Much better backup file handling, now uses md5 hashes a la rpm
|
||||
1.23 - Added install/upgrade/remove scripting control
|
||||
1.22 - Some manpage typo fixes
|
||||
- Added --root switch to pacsync
|
||||
|
|
82
Makefile
82
Makefile
|
@ -1,82 +0,0 @@
|
|||
#
|
||||
# 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.23
|
||||
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 pacsync.8 makepkg.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 -m0644 pacsync.8 $(DESTDIR)$(MANDIR)/man8/pacsync.8
|
||||
install -D -m0644 makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
|
||||
install -D -m0755 makepkg $(DESTDIR)$(BINDIR)/makepkg
|
||||
install -D -m0755 makeworld $(DESTDIR)$(BINDIR)/makeworld
|
||||
install -D -m0755 pacsync $(DESTDIR)$(BINDIR)/pacsync
|
||||
@echo ""
|
||||
@echo "*** If this is a first-time install, you should copy makepkg.conf"
|
||||
@echo "*** and pacsync.conf to /etc now."
|
||||
@echo ""
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o *.8
|
||||
|
||||
distclean: clean
|
||||
rm -f pacman
|
||||
rm -rf libtar-$(LIBTAR_VERSION)
|
||||
|
||||
# End of file
|
122
Makefile.in
Normal file
122
Makefile.in
Normal file
|
@ -0,0 +1,122 @@
|
|||
#
|
||||
# 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 =
|
||||
prefix = @prefix@
|
||||
exec_prefix = @prefix@
|
||||
|
||||
BINDIR = @bindir@
|
||||
MANDIR = @mandir@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
|
||||
PACVER = 2.0
|
||||
LIBTAR_VERSION = 1.2.5
|
||||
|
||||
TOPDIR = @srcdir@
|
||||
SRCDIR = $(TOPDIR)/src/
|
||||
OBJDIR = $(TOPDIR)/src/
|
||||
MANSRC = $(TOPDIR)/doc/
|
||||
SCRDIR = $(TOPDIR)/scripts/
|
||||
|
||||
CXX = @CC@
|
||||
CXXFLAGS += @CFLAGS@ -Wall -pedantic -fno-exceptions -fno-rtti \
|
||||
-D_GNU_SOURCE -DPACVER=\"$(PACVER)\" -I. \
|
||||
-Ilibtar-$(LIBTAR_VERSION)/lib -Ilibftp
|
||||
LDFLAGS += @LDFLAGS@ -static -Llibtar-$(LIBTAR_VERSION)/lib -Llibftp \
|
||||
-lftp -ltar -lz
|
||||
|
||||
SRCS = $(SRCDIR)pacman.c \
|
||||
$(SRCDIR)db.c \
|
||||
$(SRCDIR)util.c \
|
||||
$(SRCDIR)list.c \
|
||||
$(SRCDIR)package.c \
|
||||
$(SRCDIR)pacsync.c \
|
||||
$(SRCDIR)rpmvercmp.c \
|
||||
$(SRCDIR)md5.c \
|
||||
$(SRCDIR)md5driver.c
|
||||
|
||||
OBJECTS = $(OBJDIR)pacman.o \
|
||||
$(OBJDIR)db.o \
|
||||
$(OBJDIR)util.o \
|
||||
$(OBJDIR)list.o \
|
||||
$(OBJDIR)package.o \
|
||||
$(OBJDIR)pacsync.o \
|
||||
$(OBJDIR)rpmvercmp.o \
|
||||
$(OBJDIR)md5.o \
|
||||
$(OBJDIR)md5driver.o
|
||||
|
||||
all: libtar ftplib pacman convertdb man
|
||||
|
||||
pacman: $(OBJECTS)
|
||||
$(CXX) $(OBJECTS) -o $@ $(LDFLAGS)
|
||||
|
||||
convertdb: $(SRCDIR)convertdb.c $(SRCDIR)list.c
|
||||
$(CXX) -o convertdb $(SRCDIR)convertdb.c $(SRCDIR)list.c $(CXXFLAGS)
|
||||
|
||||
.c.o: $(SRCS)
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
man: $(MANSRC)pacman.8 \
|
||||
$(MANSRC)makepkg.8
|
||||
|
||||
%.8: %.8.in
|
||||
sed -e "s/#VERSION#/$(PACVER)/" $< > $@
|
||||
|
||||
dist: distclean
|
||||
(cd ..; tar czvf pacman-$(PACVER).tar.gz pacman-$(PACVER))
|
||||
|
||||
ftplib:
|
||||
(cd libftp; make libftp.a)
|
||||
|
||||
libtar:
|
||||
(tar xzf libtar-$(LIBTAR_VERSION).tar.gz; \
|
||||
cd libtar-$(LIBTAR_VERSION); \
|
||||
LDFLAGS="" ./configure --disable-encap --disable-encap-install; \
|
||||
make;)
|
||||
|
||||
install: pacman convertdb man
|
||||
$(INSTALL) -D -m0755 pacman $(DESTDIR)$(BINDIR)/pacman
|
||||
$(INSTALL) -D -m0755 convertdb $(DESTDIR)$(BINDIR)/convertdb
|
||||
$(INSTALL) -D -m0755 $(SCRDIR)makepkg $(DESTDIR)$(BINDIR)/makepkg
|
||||
$(INSTALL) -D -m0755 $(SCRDIR)makeworld $(DESTDIR)$(BINDIR)/makeworld
|
||||
$(INSTALL) -D -m0755 $(SCRDIR)abs $(DESTDIR)$(BINDIR)/abs
|
||||
$(INSTALL) -D -m0644 $(MANSRC)pacman.8 $(DESTDIR)$(MANDIR)/man8/pacman.8
|
||||
$(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
|
||||
$(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf
|
||||
$(INSTALL) -D -m0644 etc/makepkg.conf $(DESTDIR)/etc/makepkg.conf
|
||||
$(INSTALL) -D -m0644 etc/supfile $(DESTDIR)/etc/abs/supfile
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJDIR)*.o $(MANSRC)*.8
|
||||
(cd libftp; make clobber)
|
||||
|
||||
distclean: clean
|
||||
rm -f pacman convertdb
|
||||
rm -rf libtar-$(LIBTAR_VERSION)
|
||||
|
||||
# End of file
|
21
README
21
README
|
@ -7,24 +7,23 @@ 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.
|
||||
package database (more of a hierarchy), 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.
|
||||
package database for installed packages, files and owners. It also
|
||||
attempts to handle dependencies automatically and can
|
||||
|
||||
Although the package manager itself is quite simple, the pacman tarball
|
||||
also comes with scripts that help automate building and installing
|
||||
packages. These are used extensively in the Arch Build System (ABS),
|
||||
used in Arch Linux <http://www.archlinux.org>. See ABS.txt for more
|
||||
information.
|
||||
used in Arch Linux <http://www.archlinux.org>.
|
||||
|
||||
As of version 1.2, pacsync is included as well. This performs an
|
||||
apt-like function, keeping your system's packages in sync with the
|
||||
packages on a remote server.
|
||||
|
||||
Plans exist for dependency checking as I approach version 2.0.
|
||||
See TODO for more info.
|
||||
As of version 2.0, pacman can also keep your system's packages in
|
||||
sync with a master server. You can follow CURRENT and STABLE trees,
|
||||
or lock yourself into a specific version. See the pacman manpage
|
||||
for more info on this (--sync operation).
|
||||
|
||||
|
||||
INSTALL:
|
||||
|
@ -44,7 +43,7 @@ BUGS:
|
|||
-----
|
||||
If you find bugs (which is quite likely), 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
|
||||
commandline, the nature of the bug, and even the package database if
|
||||
it helps.
|
||||
|
||||
|
||||
|
|
31
TODO
31
TODO
|
@ -1,11 +1,22 @@
|
|||
- add a [sibling] option to .PKGINFO -- used when only one of
|
||||
the siblings can be installed at a time (eg, bsdinit,sysvinit)
|
||||
- sort packages by package name in pacman.db
|
||||
? manage conditional file installs (ie, 'info' pages)
|
||||
- maybe add a 'confirm every action' option for doing paranoid installs
|
||||
- add a consistency check operation
|
||||
- add file locking to db
|
||||
- check $PACCONF env var
|
||||
- ftp transfer progress bar breaks after ~42000 K
|
||||
- use a 'trust pacman' config option for downgrading?
|
||||
- use a provides tag (instead of an OR operator in depends)
|
||||
- instead of 'conflicts' use a ! operator in depends
|
||||
- add a --pretend option
|
||||
- add a consistency/sanity check operation
|
||||
- add a --dbpath option
|
||||
+ dependency checking
|
||||
- upgrade currently does a double db backup; not really desirable
|
||||
|
||||
- build-time (source) dependencies in makepkg
|
||||
- auto-resolve dependencies in makepkg
|
||||
- use package caches more for performance
|
||||
+ add an "ignore package" option in either pacman.conf or in each package
|
||||
record. this will prevent it from being upgraded from the sync set
|
||||
- duplicate dep checks occur with sync (one in sync, one in add)
|
||||
- clean up output a bit (message queue?)
|
||||
- add an OR operator to dependencies or allow a sibling tag (ie, mawk, gawk)
|
||||
- run ldd on every executable in a newly built package to find required so's
|
||||
- add a freshen operation
|
||||
- allow multiple ftp servers to be defined and fallback to backups on failure
|
||||
- use a files.cache gdbm (or whatever) for --owns and db_find_conflicts
|
||||
- things like 'groupadd' and 'useradd' in the install scriptlets will affect
|
||||
the real root, not the one specified with -r
|
||||
|
|
0
acconfig.h
Normal file
0
acconfig.h
Normal file
1321
config.guess
vendored
Executable file
1321
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
153
config.h.in
Normal file
153
config.h.in
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `getpass' function. */
|
||||
#undef HAVE_GETPASS
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if `lstat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
#undef HAVE_LSTAT_EMPTY_STRING_BUG
|
||||
|
||||
/* Define to 1 if your system has a working `malloc' function. */
|
||||
#undef HAVE_MALLOC
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#undef HAVE_MKDIR
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the `realpath' function. */
|
||||
#undef HAVE_REALPATH
|
||||
|
||||
/* Define to 1 if you have the `rmdir' function. */
|
||||
#undef HAVE_RMDIR
|
||||
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
#undef HAVE_STAT_EMPTY_STRING_BUG
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
/* Define to 1 if you have the `strverscmp' function. */
|
||||
#undef HAVE_STRVERSCMP
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
1443
config.sub
vendored
Executable file
1443
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
35
configure.in
Normal file
35
configure.in
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
||||
AC_CONFIG_SRCDIR([acconfig.h])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CXX
|
||||
|
||||
# Checks for libraries.
|
||||
# AC_CHECK_LIB([tar], [tar_open])
|
||||
AC_CHECK_LIB([z], [gzread])
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_LSTAT
|
||||
AC_FUNC_MALLOC
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_STAT
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS([getpass memmove mkdir realpath rmdir strdup strerror strstr strverscmp])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
|
@ -1,4 +1,4 @@
|
|||
.TH makepkg 8 "Mar 17, 2002" "makepkg #VERSION#" ""
|
||||
.TH makepkg 8 "July 18, 2002" "makepkg #VERSION#" ""
|
||||
.SH NAME
|
||||
makepkg \- package build utility
|
||||
.SH SYNOPSIS
|
||||
|
@ -8,9 +8,10 @@ makepkg \- package build utility
|
|||
a build-capable linux platform, wget, and some build scripts. The advantage
|
||||
to a script-based build is that you only really do the work once. Once you
|
||||
have the build script for a package, you just need to run makepkg and it
|
||||
will do the rest: download source files, configure the buildtime settings,
|
||||
build the package, install the package into a temporary root, make
|
||||
customizations, and package the whole thing up for pacman to use.
|
||||
will do the rest: download source files, check dependencies,
|
||||
configure the buildtime settings, build the package, install the package
|
||||
into a temporary root, make customizations, generate meta-info, and package
|
||||
the whole thing up for \fBpacman\fP to use.
|
||||
|
||||
\fBmakeworld\fP can be used to rebuild an entire package group, or the
|
||||
entire build tree.
|
||||
|
@ -19,6 +20,11 @@ Start in an isolated directory (ie, it's not used for anything other
|
|||
than building this package). The build script should be called PKGBUILD
|
||||
and it should bear resemblance to the example below.
|
||||
|
||||
\fBNOTE:\fP If you have a local copy of the Arch Build System (ABS) tree
|
||||
on your computer, you can copy the PKGBUILD.proto file to your new package
|
||||
build directory and edit it from there. To acquire/sync the ABS tree, use
|
||||
the \fBabs\fP script included with pacman/makepkg.
|
||||
|
||||
.TP
|
||||
.TP
|
||||
.SH PKGBUILD Example:
|
||||
|
@ -27,7 +33,9 @@ and it should bear resemblance to the example below.
|
|||
pkgname=modutils
|
||||
pkgver=2.4.13
|
||||
pkgrel=1
|
||||
pkgdesc="Utilities for inserting and removing modules from the linux kernel"
|
||||
backup=(etc/modules.conf)
|
||||
depends=('glibc>=2.2.5' 'bash' 'zlib')
|
||||
source=(ftp://ftp.server.com/$pkgname-$pkgver.tar.gz modules.conf)
|
||||
|
||||
build() {
|
||||
|
@ -43,11 +51,26 @@ build() {
|
|||
.RE
|
||||
|
||||
As you can see, the setup is fairly simple. The first three lines define
|
||||
the package name and version info. They also define the final package name,
|
||||
which will be of the form $pkgname-$pkgver-$pkgrel.pkg.tar.gz
|
||||
the package name and version info. They also define the final package name
|
||||
which will be of the form \fI$pkgname-$pkgver-$pkgrel.pkg.tar.gz\fP. The fourth
|
||||
line provides a brief description of the package. These four lines should
|
||||
be present in every PKGBUILD script.
|
||||
|
||||
The sources are then decompressed (if necessary) into a directory called ./src.
|
||||
Then the \fIbuild\fP function is called. This is where all package configuration,
|
||||
The line with \fIbackup=\fP specifies files that should be treated specially
|
||||
when removing or upgrading packages. See \fBHANDLING CONFIG FILES\fP in
|
||||
the \fIpacman\fP manpage for more information on this.
|
||||
|
||||
The sixth line lists the dependencies for this package. In order to build/run
|
||||
the package, all dependencies must be satisifed first. makepkg will check this
|
||||
before attempting to build the package.
|
||||
|
||||
Once your PKGBUILD is created, you can run \fImakepkg\fP from the build directory.
|
||||
makepkg will then check dependencies and look for the source files required to
|
||||
build. If some are missing it will attempt to download them, provided there is
|
||||
a fully-qualified URL in the \fIsource\fP array.
|
||||
|
||||
The sources are then extracted into a directory called ./src and
|
||||
the \fIbuild\fP function is called. This is where all package configuration,
|
||||
building, and installing should be done. Any customization will likely take
|
||||
place here.
|
||||
|
||||
|
@ -65,13 +88,14 @@ make prefix=$startdir/pkg/usr install
|
|||
|
||||
.fi
|
||||
.RE
|
||||
Notice that the "/usr" portion should be present with "prefix", but not "DESTDIR."
|
||||
Notice that the "/usr" portion should be present with "prefix", but not "DESTDIR".
|
||||
|
||||
Once the package is successfully installed into the package root, \fImakepkg\fP
|
||||
will remove some directories (as per Arch Linux package guidelines; if you use
|
||||
this elsewhere, feel free to change it) like /usr/doc and /usr/info. It will
|
||||
then strip debugging info from libraries and binaries and compress everything
|
||||
into a .pkg.tar.gz file in the directory you ran \fBmakepkg\fP from.
|
||||
then strip debugging info from libraries and binaries and generate a meta-info
|
||||
file. Finally, it will compress everything into a .pkg.tar.gz file and leave it
|
||||
in the directory you ran \fBmakepkg\fP from.
|
||||
|
||||
At this point you should have a package file in the current directory, named
|
||||
something like name-version-release.pkg.tar.gz. Done!
|
||||
|
@ -95,11 +119,15 @@ script is run after all files have been upgraded.
|
|||
script is run right before files are removed.
|
||||
|
||||
.RE
|
||||
In order to use this feature, your build function should put the script in
|
||||
$startdir/pkg/var/lib/pacman/scripts and it must be named exactly the same
|
||||
as the \fI$pkgname\fP variable in the PKGBUILD script. For example, an
|
||||
install script for grep will be $startdir/pkg/var/lib/pacman/scripts/grep.
|
||||
Note that the scripts should be 644, not 755 (we don't need execute permission).
|
||||
To use this feature, just create a file (eg, pkgname.install) and put it in
|
||||
the same directory as the PKGBUILD script. Then use the \fIinstall\fP directive:
|
||||
.RS
|
||||
.nf
|
||||
install=pkgname.install
|
||||
.fi
|
||||
.RE
|
||||
|
||||
The install script does not need to be specified in the \fIsource\fP array.
|
||||
|
||||
.TP
|
||||
.TP
|
||||
|
@ -111,6 +139,7 @@ post_install() {
|
|||
#
|
||||
# do post-install stuff here
|
||||
#
|
||||
/bin/true
|
||||
}
|
||||
|
||||
# arg 1: the new package version
|
||||
|
@ -119,6 +148,7 @@ post_upgrade() {
|
|||
#
|
||||
# do post-upgrade stuff here
|
||||
#
|
||||
/bin/true
|
||||
}
|
||||
|
||||
# arg 1: the old package version
|
||||
|
@ -126,6 +156,7 @@ pre_remove() {
|
|||
#
|
||||
# do pre-remove stuff here
|
||||
#
|
||||
/bin/true
|
||||
}
|
||||
|
||||
op=$1
|
||||
|
@ -151,12 +182,39 @@ This is the version of the software as released from the author (eg, 2.7.1).
|
|||
.B pkgrel
|
||||
This is the release number specific to Arch Linux packages.
|
||||
|
||||
.TP
|
||||
.B pkgdesc
|
||||
This should be a brief description of the package and its functionality.
|
||||
|
||||
.TP
|
||||
.B backup
|
||||
A space-delimited array of filenames (without a preceding slash). The
|
||||
\fIbackup\fP line will be propagated to the package meta-info file for
|
||||
pacman. This will designate all files listed there to be backed up if this
|
||||
package is ever removed from a system.
|
||||
package is ever removed from a system. See \fBHANDLING CONFIG FILES\fP in
|
||||
the \fIpacman\fP manpage for more information.
|
||||
|
||||
.TP
|
||||
.B install
|
||||
Specified a special install script that is to be included in the package.
|
||||
This file should reside in the same directory as the PKGBUILD, and will be
|
||||
copied into the package by makepkg. It does not need to be included in the
|
||||
\fIsource\fP array. (eg, install=modutils.install)
|
||||
|
||||
.TP
|
||||
.B depends
|
||||
An array of packages that this package depends on to build and run. Packages
|
||||
in this list should be surrounded with single quotes and contain at least the
|
||||
package name. They can also include a version requirement of the form
|
||||
\fBname<>version\fP, where <> is one of these three comparisons: \fB>=\fP
|
||||
(greater than equal to), \fB<=\fP (less than or equal to), or \fB=\fP (equal to).
|
||||
See the PKGBUILD example above for an example of the \fIdepends\fP directive.
|
||||
|
||||
.TP
|
||||
.B conflicts
|
||||
An array of packages that will conflict with this package (ie, they cannot both
|
||||
be installed at the same time). This directive follows the same format as
|
||||
\fIdepends\fP except you cannot specify versions here, only package names.
|
||||
|
||||
.TP
|
||||
.B source
|
||||
|
@ -166,14 +224,27 @@ file, unless they have a fully-qualified URL. Then if the source file
|
|||
does not already exist in /var/cache/pacman/src, the file is downloaded
|
||||
by wget.
|
||||
|
||||
.SH MAKEPKG OPTIONS
|
||||
.TP
|
||||
.B "\-c, \-\-clean"
|
||||
Clean up leftover work files/directories after a successful build.
|
||||
.TP
|
||||
.B "\-i, \-\-install"
|
||||
Install/Upgrade the package after a successful build.
|
||||
|
||||
.SH CONFIGURATION
|
||||
Configuration options are stored in /etc/makepkg.conf. This file is parsed
|
||||
Configuration options are stored in \fI/etc/makepkg.conf\fP. This file is parsed
|
||||
as a bash script, so you can export any special compiler flags you wish
|
||||
to use. This is helpful for building for different architectures, or with
|
||||
different optimizations.
|
||||
|
||||
\fBNOTE:\fP This does not guarantee that all package Makefiles will use
|
||||
your exported variables. Some of them are flaky...
|
||||
.SH SEE ALSO
|
||||
\fBpacman\fP is the package manager that uses packages built by makepkg.
|
||||
|
||||
See the Arch Linux Documentation for package-building guidelines if you wish
|
||||
to contribute packages to the Arch Linux project.
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Judd Vinet <jvinet@zeroflux.org>
|
172
doc/pacman.8.in
Normal file
172
doc/pacman.8.in
Normal file
|
@ -0,0 +1,172 @@
|
|||
.TH pacman 8 "July 18, 2002" "pacman #VERSION#" ""
|
||||
.SH NAME
|
||||
pacman \- package manager utility
|
||||
.SH SYNOPSIS
|
||||
\fBpacman <operation> [options] <package> [package] ...\fP
|
||||
.SH DESCRIPTION
|
||||
\fBpacman\fP is a \fIpackage management\fP utility that tracks installed
|
||||
packages on a linux system. It has simple dependency support and the ability
|
||||
to connect to a remote ftp server and automatically upgrade packages on
|
||||
the local system. pacman package are \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. Most configuration files will be saved with a
|
||||
\fI.pacsave\fP extension unless the \fB--nosave\fP option was
|
||||
used.
|
||||
.TP
|
||||
.B "\-U, \-\-upgrade"
|
||||
Upgrade a package. This is essentially a "remove-then-add"
|
||||
process. See \fBHANDLING CONFIG FILES\fP for an explanation
|
||||
on how pacman takes care of config files.
|
||||
.TP
|
||||
.B "\-Q, \-\-query"
|
||||
Query the package database. This operation allows you to
|
||||
view installed packages and their files, as well as meta-info
|
||||
about individual packages (dependencies, conflicts, install date,
|
||||
build date, size). This can be run against the local package
|
||||
database or can be used on individual .tar.gz packages. See
|
||||
\fBQUERY OPTIONS\fP below.
|
||||
.TP
|
||||
.B "\-S, \-\-sync"
|
||||
Synchronize packages. With this function you can install packages
|
||||
directly from the ftp servers, complete with all dependencies required
|
||||
to run the packages. For example, \fBpacman -S qt\fP will download
|
||||
qt and all the packages it depends on and install them. You could also use
|
||||
\fBpacman -Su\fP to upgrade all packages that are out of date (see 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 OPTIONS
|
||||
.TP
|
||||
.B "\-v, \-\-verbose"
|
||||
Output more status and error messages.
|
||||
.TP
|
||||
.B "\-f, \-\-force"
|
||||
Bypass file conflict checks,, 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, ideally not at all.
|
||||
.TP
|
||||
.B "\-d, \-\-nodeps"
|
||||
Skips all dependency checks. Normally, pacman will always check
|
||||
a package's dependency fields to ensure that all dependencies are
|
||||
installed and there are no package conflicts in the system. This
|
||||
switch disables these checks.
|
||||
.TP
|
||||
.B "\-n, \-\-nosave"
|
||||
(only used with \fB--remove\fP)
|
||||
Instructs pacman to ignore file backup designations. Normally, when
|
||||
a file is about to be \fIremoved\fP from the system the database is first
|
||||
checked to see if the file should be renamed to a .pacsave extension. If
|
||||
\fB--nosave\fP is used, these designations are ignored and the files are
|
||||
removed.
|
||||
.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 SYNC OPTIONS
|
||||
.TP
|
||||
.B "\-y, \-\-refresh"
|
||||
Download a fresh copy of the master package list from the ftp server
|
||||
defined in \fI/etc/pacman.conf\fP. This should typically be used each
|
||||
time you use \fB--sysupgrade\fP.
|
||||
.TP
|
||||
.B "\-u, \-\-sysupgrade"
|
||||
Upgrades all packages that are out of date. pacman will examine every
|
||||
package installed on the system, and if a newer package exists on the
|
||||
server it will upgrade. pacman will present a report of all packages
|
||||
it wants to upgrade and will not proceed without user confirmation.
|
||||
Dependencies are automatically resolved at this level and will be
|
||||
installed/upgraded if necessary.
|
||||
.TP
|
||||
.B "\-s, \-\-search <string>"
|
||||
This will search each package in the package list for names or descriptions
|
||||
that contains <string>.
|
||||
.TP
|
||||
.B "\-c, \-\-clean"
|
||||
Remove packages from the cache. When pacman downloads packages,
|
||||
it saves them in \fI/var/cache/pacman/pkg\fP. If you need to free up
|
||||
diskspace, you can remove these packages by using the --clean option.
|
||||
.SH QUERY OPTIONS
|
||||
.TP
|
||||
.B "\-o, \-\-owns <file>"
|
||||
Search for the package that owns <file>.
|
||||
.TP
|
||||
.B "\-l, \-\-list"
|
||||
List all files owned by <package>. Multiple packages can be specified on
|
||||
the command line.
|
||||
.TP
|
||||
.B "\-i, \-\-info"
|
||||
Display information on a given package. If it is used with the \fB-p\fP
|
||||
option then the .PKGINFO file will be printed.
|
||||
.TP
|
||||
.B "\-p, \-\-file"
|
||||
Tells pacman that the package supplied on the command line is a
|
||||
file, not an entry in the database. Pacman will decompress the
|
||||
file and query it. This is useful with \fB--info\fP and \fB--list\fP.
|
||||
.SH HANDLING CONFIG FILES
|
||||
pacman uses the same logic as rpm to determine action against files
|
||||
that are designated to be backed up. During an upgrade, it uses 3
|
||||
md5 hashes for each backup file to determine the required action:
|
||||
one for the original file installed, one for the new file that's about
|
||||
to be installed, and one for the actual file existing on the filesystem.
|
||||
After comparing these 3 hashes, the follow scenarios can result:
|
||||
.TP
|
||||
original=\fBX\fP, current=\fBX\fP, new=\fBX\fP
|
||||
All three files are the same, so we win either way. Install the new file.
|
||||
.TP
|
||||
original=\fBX\fP, current=\fBX\fP, new=\fBY\fP
|
||||
The current file is un-altered from the original but the new one is
|
||||
different. Since the user did not ever modify the file, and the new
|
||||
one may contain improvements/bugfixes, we install the new file.
|
||||
.TP
|
||||
original=\fBX\fP, current=\fBY\fP, new=\fBX\fP
|
||||
Both package versions contain the exact same file, but the one
|
||||
on the filesystem has been modified since. In this case, we leave
|
||||
the current file in place.
|
||||
.TP
|
||||
original=\fBX\fP, current=\fBY\fP, new=\fBY\fP
|
||||
The new one is identical to the current one. Win win. Install the new file.
|
||||
.TP
|
||||
original=\fBX\fP, current=\fBY\fP, new=\fBZ\fP
|
||||
All three files are different. So we install the new file, but back up the
|
||||
old one to a .pacsave extension. This way the user can move the old configuration
|
||||
file back into place if he wishes.
|
||||
.SH CONFIGURATION
|
||||
pacman will attempt to read \fI/etc/pacman.conf\fP each time it is invoked. Currently
|
||||
the only options in it are for the --sync operation, but more may be added later.
|
||||
.TP
|
||||
.B "Sync_Tree_Name"
|
||||
Sets the name of the package set you wish to follow. The common choices are \fIcurrent\fP
|
||||
and \fIstable\fP. You could also specify a specific package version, eg, 0.3.
|
||||
.TP
|
||||
.B "Sync_Server"
|
||||
This is the hostname of the ftp server that will be used for downloading lists and
|
||||
packages. eg, \fIftp.ibiblio.org\fP.
|
||||
.TP
|
||||
.B "Sync_Tree_Path"
|
||||
This is the full path name (on the ftp server) to the package tree you are following.
|
||||
So if you are following \fIcurrent\fP, on \fIftp.ibiblio.org\fP, you would use
|
||||
\fI/pub/linux/distributions/archlinux/current\fP.
|
||||
.SH SEE ALSO
|
||||
\fBmakepkg\fP is the package-building tool that comes with pacman.
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Judd Vinet <jvinet@zeroflux.org>
|
||||
.fi
|
|
@ -1,8 +1,9 @@
|
|||
#
|
||||
# /etc/pkgmake.conf
|
||||
# /etc/makepkg.conf
|
||||
#
|
||||
|
||||
export CFLAGS="-O2 -march=i686 -pipe"
|
||||
export CXXFLAGS="-O2 -march=i686 -pipe"
|
||||
|
||||
# End of file
|
||||
#export MAKEFLAGS="-j 2"
|
||||
|
35
etc/pacman.conf
Normal file
35
etc/pacman.conf
Normal file
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# /etc/pacman.conf
|
||||
#
|
||||
|
||||
# name of the tree you want to follow (eg: stable, current, 0.2, 0.3, ...)
|
||||
Sync_Tree_Name = current
|
||||
|
||||
# ftp server
|
||||
Sync_Server = ftp.ibiblio.org
|
||||
|
||||
# full path to sync tree
|
||||
Sync_Tree_Path = /pub/linux/distributions/archlinux/current
|
||||
|
||||
###
|
||||
### MIRRORS
|
||||
#########################
|
||||
|
||||
# Sync_Server = ftp.mpi-sb.mpg.de
|
||||
# Sync_Tree_Path = /pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current
|
||||
|
||||
# Sync_Server = ftp2.archlinux.org
|
||||
# Sync_Tree_Path = /current
|
||||
|
||||
# Sync_Server = ftp.oit.unc.edu
|
||||
# Sync_Tree_Path = /pub/Linux/distributions/archlinux/current
|
||||
|
||||
# Sync_Server = ftp.tu-chemnitz.de
|
||||
# Sync_Tree_Path = /pub/linux/sunsite.unc-mirror/distributions/archlinux/current
|
||||
|
||||
# Sync_Server = ftp.archlinux.org
|
||||
# Sync_Tree_Path = /current
|
||||
|
||||
# Sync_Server = ftp.oit.unc.edu
|
||||
# Sync_Tree_Path = /pub/Linux/distributions/archlinux/current
|
||||
|
23
etc/supfile
Normal file
23
etc/supfile
Normal file
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# /etc/abs/supfile
|
||||
#
|
||||
|
||||
# this is the host containing the master ABS files
|
||||
*default host=archlinux.org
|
||||
|
||||
*default base=/usr/abs
|
||||
*default prefix=/usr/abs
|
||||
*default release=cvs
|
||||
*default delete
|
||||
*default use-rel-suffix
|
||||
*default compress
|
||||
|
||||
#
|
||||
# Set tag equal to the package tree you wish to follow. CURRENT and
|
||||
# STABLE are the most commonly used, but you can specify specific
|
||||
# versions or tag names. Examples are RELEASE_0_2, VEGA, RELEASE_0_3,
|
||||
# FIREFLY, etc.
|
||||
#
|
||||
*default tag=CURRENT
|
||||
|
||||
abs
|
251
install-sh
Executable file
251
install-sh
Executable file
|
@ -0,0 +1,251 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
chmodcmd=""
|
||||
else
|
||||
instcmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
68
libftp/Makefile
Normal file
68
libftp/Makefile
Normal file
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# This makefile contains modifications submitted by Richard Braakman
|
||||
# (dark@xs4all.nl) for the shared library generation.
|
||||
#
|
||||
|
||||
# By default, ftplib uses PASV. If you need it to use PORT
|
||||
# instead, uncomment the next line
|
||||
DEFINES = -DFTPLIB_DEFMODE=FTPLIB_PORT
|
||||
|
||||
SONAME = 3
|
||||
SOVERSION = $(SONAME).1
|
||||
|
||||
TARGETS = qftp libftp.a libftp.so
|
||||
OBJECTS = qftp.o ftplib.o
|
||||
SOURCES = qftp.c ftplib.c
|
||||
|
||||
CFLAGS = -Wall $(DEBUG) -I. $(INCLUDES) $(DEFINES)
|
||||
LDFLAGS = -L.
|
||||
DEPFLAGS =
|
||||
|
||||
all : $(TARGETS)
|
||||
|
||||
clean :
|
||||
rm -f $(OBJECTS) core *.bak
|
||||
rm -rf unshared
|
||||
|
||||
clobber : clean
|
||||
rm -f $(TARGETS) .depend
|
||||
rm -f libftp.so.*
|
||||
|
||||
install : all
|
||||
install qftp /usr/local/bin
|
||||
install -m 644 libftp.so.$(SOVERSION) /usr/local/lib
|
||||
install -m 644 ftplib.h /usr/local/include
|
||||
(cd /usr/local/lib && \
|
||||
ln -sf libftp.so.$(SOVERSION) libftp.so.$(SONAME) && \
|
||||
ln -sf libftp.so.$(SONAME) libftp.so)
|
||||
-(cd /usr/local/bin && \
|
||||
for f in ftpdir ftpget ftplist ftprm ftpsend; \
|
||||
do ln -s qftp $$f; done)
|
||||
|
||||
depend :
|
||||
$(CC) $(CFLAGS) -M $(SOURCES) > .depend
|
||||
|
||||
# build without -fPIC
|
||||
unshared/ftplib.o: ftplib.c ftplib.h
|
||||
-mkdir unshared
|
||||
$(CC) -c $(CFLAGS) -D_REENTRANT $< -o $@
|
||||
|
||||
ftplib.o: ftplib.c ftplib.h
|
||||
$(CC) -c $(CFLAGS) -fPIC -D_REENTRANT $< -o $@
|
||||
|
||||
libftp.a: unshared/ftplib.o
|
||||
ar -rcs $@ $<
|
||||
|
||||
libftp.so.$(SOVERSION): ftplib.o
|
||||
$(CC) -shared -Wl,-soname,libftp.so.$(SONAME) -lc -o $@ $<
|
||||
|
||||
libftp.so: libftp.so.$(SOVERSION)
|
||||
ln -sf $< libftp.so.$(SONAME)
|
||||
ln -sf $< $@
|
||||
|
||||
qftp : qftp.o libftp.so ftplib.h
|
||||
$(CC) $(LDFLAGS) -o $@ $< -lftp
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
1295
libftp/ftplib.c
Normal file
1295
libftp/ftplib.c
Normal file
File diff suppressed because it is too large
Load diff
125
libftp/ftplib.h
Normal file
125
libftp/ftplib.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftplib.h - header file for callable ftp access routines */
|
||||
/* Copyright (C) 1996, 1997 Thomas Pfau, pfau@cnj.digex.net */
|
||||
/* 73 Catherine Street, South Bound Brook, NJ, 08880 */
|
||||
/* */
|
||||
/* This library is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public */
|
||||
/* License as published by the Free Software Foundation; either */
|
||||
/* version 2 of the License, or (at your option) any later version. */
|
||||
/* */
|
||||
/* This library 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 */
|
||||
/* Library General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU Library General Public */
|
||||
/* License along with this progam; if not, write to the */
|
||||
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
|
||||
/* Boston, MA 02111-1307, USA. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
#if !defined(__FTPLIB_H)
|
||||
#define __FTPLIB_H
|
||||
|
||||
#if defined(__unix__) || defined(VMS)
|
||||
#define GLOBALDEF
|
||||
#define GLOBALREF extern
|
||||
#elif defined(_WIN32)
|
||||
#if defined BUILDING_LIBRARY
|
||||
#define GLOBALDEF __declspec(dllexport)
|
||||
#define GLOBALREF __declspec(dllexport)
|
||||
#else
|
||||
#define GLOBALREF __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* FtpAccess() type codes */
|
||||
#define FTPLIB_DIR 1
|
||||
#define FTPLIB_DIR_VERBOSE 2
|
||||
#define FTPLIB_FILE_READ 3
|
||||
#define FTPLIB_FILE_WRITE 4
|
||||
|
||||
/* FtpAccess() mode codes */
|
||||
#define FTPLIB_ASCII 'A'
|
||||
#define FTPLIB_IMAGE 'I'
|
||||
#define FTPLIB_TEXT FTPLIB_ASCII
|
||||
#define FTPLIB_BINARY FTPLIB_IMAGE
|
||||
|
||||
/* connection modes */
|
||||
#define FTPLIB_PASSIVE 1
|
||||
#define FTPLIB_PORT 2
|
||||
|
||||
/* connection option names */
|
||||
#define FTPLIB_CONNMODE 1
|
||||
#define FTPLIB_CALLBACK 2
|
||||
#define FTPLIB_IDLETIME 3
|
||||
#define FTPLIB_CALLBACKARG 4
|
||||
#define FTPLIB_CALLBACKBYTES 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct NetBuf netbuf;
|
||||
typedef int (*FtpCallback)(netbuf *nControl, int xfered, void *arg);
|
||||
|
||||
/* v1 compatibility stuff */
|
||||
#if !defined(_FTPLIB_NO_COMPAT)
|
||||
netbuf *DefaultNetbuf;
|
||||
|
||||
#define ftplib_lastresp FtpLastResponse(DefaultNetbuf)
|
||||
#define ftpInit FtpInit
|
||||
#define ftpOpen(x) FtpConnect(x, &DefaultNetbuf)
|
||||
#define ftpLogin(x,y) FtpLogin(x, y, DefaultNetbuf)
|
||||
#define ftpSite(x) FtpSite(x, DefaultNetbuf)
|
||||
#define ftpMkdir(x) FtpMkdir(x, DefaultNetbuf)
|
||||
#define ftpChdir(x) FtpChdir(x, DefaultNetbuf)
|
||||
#define ftpRmdir(x) FtpRmdir(x, DefaultNetbuf)
|
||||
#define ftpNlst(x, y) FtpNlst(x, y, DefaultNetbuf)
|
||||
#define ftpDir(x, y) FtpDir(x, y, DefaultNetbuf)
|
||||
#define ftpGet(x, y, z) FtpGet(x, y, z, DefaultNetbuf)
|
||||
#define ftpPut(x, y, z) FtpPut(x, y, z, DefaultNetbuf)
|
||||
#define ftpRename(x, y) FtpRename(x, y, DefaultNetbuf)
|
||||
#define ftpDelete(x) FtpDelete(x, DefaultNetbuf)
|
||||
#define ftpQuit() FtpQuit(DefaultNetbuf)
|
||||
#endif /* (_FTPLIB_NO_COMPAT) */
|
||||
/* end v1 compatibility stuff */
|
||||
|
||||
GLOBALREF int ftplib_debug;
|
||||
GLOBALREF void FtpInit(void);
|
||||
GLOBALREF char *FtpLastResponse(netbuf *nControl);
|
||||
GLOBALREF int FtpConnect(const char *host, netbuf **nControl);
|
||||
GLOBALREF int FtpOptions(int opt, long val, netbuf *nControl);
|
||||
GLOBALREF int FtpLogin(const char *user, const char *pass, netbuf *nControl);
|
||||
GLOBALREF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
|
||||
netbuf **nData);
|
||||
GLOBALREF int FtpRead(void *buf, int max, netbuf *nData);
|
||||
GLOBALREF int FtpWrite(void *buf, int len, netbuf *nData);
|
||||
GLOBALREF int FtpClose(netbuf *nData);
|
||||
GLOBALREF int FtpSite(const char *cmd, netbuf *nControl);
|
||||
GLOBALREF int FtpSysType(char *buf, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpMkdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpChdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpCDUp(netbuf *nControl);
|
||||
GLOBALREF int FtpRmdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpPwd(char *path, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpNlst(const char *output, const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpDir(const char *output, const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpSize(const char *path, int *size, char mode, netbuf *nControl);
|
||||
GLOBALREF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpGet(const char *output, const char *path, char mode,
|
||||
netbuf *nControl);
|
||||
GLOBALREF int FtpPut(const char *input, const char *path, char mode,
|
||||
netbuf *nControl);
|
||||
GLOBALREF int FtpRename(const char *src, const char *dst, netbuf *nControl);
|
||||
GLOBALREF int FtpDelete(const char *fnm, netbuf *nControl);
|
||||
GLOBALREF void FtpQuit(netbuf *nControl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __FTPLIB_H */
|
Binary file not shown.
BIN
libtar-1.2.5.tar.gz
Normal file
BIN
libtar-1.2.5.tar.gz
Normal file
Binary file not shown.
140
makepkg
140
makepkg
|
@ -1,140 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
myver='1.23'
|
||||
startdir=`pwd`
|
||||
|
||||
[ -f /etc/makepkg.conf ] && . /etc/makepkg.conf
|
||||
|
||||
strip_url() {
|
||||
echo $1 | sed 's|^.*://.*/||g'
|
||||
}
|
||||
|
||||
if [ "$1" = "--help" -o "$1" = "-h" ]; then
|
||||
shift
|
||||
echo "makepkg version $myver"
|
||||
echo "usage: $0 [build_script]"
|
||||
echo
|
||||
echo " if build_script is not specified, makepkg will look for a PKGBUILD"
|
||||
echo " file in the current directory."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILDSCRIPT="`pwd`/PKGBUILD"
|
||||
if [ "$1" != "" ]; then
|
||||
BUILDSCRIPT=$1
|
||||
fi
|
||||
|
||||
if [ ! -f $BUILDSCRIPT ]; then
|
||||
echo "==> ERROR: $BUILDSCRIPT does not exist!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. $BUILDSCRIPT
|
||||
|
||||
# check for no-no's
|
||||
if [ `echo $pkgver | grep '-'` ]; then
|
||||
echo "==> ERROR: pkgver is not allowed to contain hyphens." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
d=`date`
|
||||
echo "==> Building package $pkgname ($d)" >&2
|
||||
|
||||
# extract source
|
||||
echo "==> Acquiring/Extracting Sources..." >&2
|
||||
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" >&2
|
||||
cp ../$file .
|
||||
elif [ -f /var/cache/pacman/src/$file ]; then
|
||||
echo "==> Using local copy of $file" >&2
|
||||
cp /var/cache/pacman/src/$file .
|
||||
else
|
||||
proto=`echo $netfile | sed 's|://.*||'`
|
||||
if [ "$proto" != "ftp" -a "$proto" != "http" ]; then
|
||||
echo "==> ERROR: $netfile was not found in the build directory and is not a proper URL."
|
||||
echo "==> Aborting..." >&2
|
||||
exit 1
|
||||
fi
|
||||
# check for a download utility
|
||||
if [ -x /usr/bin/snarf ]; then
|
||||
ftpagent="/usr/bin/snarf"
|
||||
elif [ -x /usr/bin/lftpget -a "$proto" = "ftp" ]; then
|
||||
ftpagent="/usr/bin/lftpget"
|
||||
elif [ -x /usr/bin/wget ]; then
|
||||
ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3"
|
||||
else
|
||||
echo "==> ERROR: You need an ftp client installed (snarf/lftp/wget) in /usr/bin" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "==> Downloading $file" >&2
|
||||
$ftpagent $netfile 2>&1
|
||||
if [ ! -f $file ]; then
|
||||
echo "==> ERROR: Failed to download $file" >&2
|
||||
echo "==> Aborting..." >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p /var/cache/pacman/src && cp $file /var/cache/pacman/src
|
||||
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" >&2
|
||||
$cmd
|
||||
done
|
||||
|
||||
# build
|
||||
echo "==> Building Package..." >&2
|
||||
build 2>&1
|
||||
if [ $? -gt 0 ]; then
|
||||
echo "==> Build Failed. Aborting..." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# write the .PKGINFO file
|
||||
echo "==> Generating .PKGINFO file..." >&2
|
||||
cd $startdir/pkg
|
||||
echo "# Generated by makepkg $myver" >.PKGINFO
|
||||
echo -n "# " >>.PKGINFO
|
||||
date >>.PKGINFO
|
||||
echo "pkgname = $pkgname" >>.PKGINFO
|
||||
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
|
||||
for bakfile in "${backup[@]}"; do
|
||||
echo "backup = $bakfile" >>.PKGINFO
|
||||
done
|
||||
|
||||
# remove info/doc files
|
||||
cd $startdir
|
||||
rm -rf pkg/usr/info pkg/usr/share/info
|
||||
rm -rf pkg/usr/doc pkg/usr/share/doc
|
||||
|
||||
# strip binaries
|
||||
cd $startdir
|
||||
echo "==> Stripping debugging symbols from libraries..." >&2
|
||||
find pkg/{,usr,usr/local}/lib -type f \
|
||||
-exec /usr/bin/strip --strip-debug '{}' ';' 2>&1
|
||||
echo "==> Stripping symbols from binaries..." >&2
|
||||
find pkg/{,usr,usr/local}/{bin,sbin} -type f \
|
||||
-exec /usr/bin/strip '{}' ';' 2>&1
|
||||
|
||||
# tar it up
|
||||
echo "==> Compressing package..." >&2
|
||||
cd $startdir/pkg
|
||||
tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
|
||||
|
||||
cd $startdir
|
||||
d=`date`
|
||||
echo "==> Finished ($d)" >&2
|
||||
exit 0
|
87
pacman.8.in
87
pacman.8.in
|
@ -1,87 +0,0 @@
|
|||
.TH pacman 8 "Mar 17, 2002" "pacman #VERSION#" ""
|
||||
.SH NAME
|
||||
pacman \- package manager utility
|
||||
.SH SYNOPSIS
|
||||
\fBpacman <operation> [options] <package> [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 most configuration files will be
|
||||
be renamed with \fI.pacsave\fP extensions.
|
||||
.TP
|
||||
.B "\-U, \-\-upgrade"
|
||||
Upgrade a package. This is essentially a "remove-then-install"
|
||||
process. Most configuration files will be not be overwritten.
|
||||
.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.
|
||||
.TP
|
||||
.B "\-p, \-\-file"
|
||||
Tells pacman that the package supplied on the command line is a
|
||||
file, not an entry in the database. Pacman will decompress the
|
||||
file and query it. This is useful with \fB--info\fP and \fB--list\fP.
|
||||
.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 "\-n, \-\-nosave"
|
||||
Instructs pacman to ignore file backup designations. Normally, when
|
||||
a file is about to be \fIremoved\fP from the system the database is first
|
||||
checked to see if the file should be renamed to a .pacsave extension
|
||||
(indicated by a '\fB*\fP' prefix in the pacman database). The \fB--nosave\fP
|
||||
will turn off these file backups. Normally, when a file is about to be \fIadded\fP
|
||||
or \fIupgraded\fP and a starred file already exists, pacman will write
|
||||
the new file to a .pacnew extension and keep the old one in place. In this
|
||||
case, \fB--nosave\fP instructs pacman to overwrite the existing file.
|
||||
.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
|
69
pacman.h
69
pacman.h
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* 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.23"
|
||||
|
||||
#define PKGEXT ".tar.gz"
|
||||
#define PKGDIR "/var/lib/pacman"
|
||||
#define PKGDB "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[64];
|
||||
char name[256];
|
||||
} 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 parseargs(int op, int argc, char** argv);
|
||||
int parse_descfile(char* descfile, unsigned short output, fileset_t* bakptr,
|
||||
unsigned int* bakct);
|
||||
|
||||
int vprint(char* fmt, ...);
|
||||
void usage(int op, char* myname);
|
||||
void version(void);
|
||||
int is_in(char* needle, fileset_t haystack, unsigned int hayct);
|
||||
int needbackup(char* file, fileset_t files, unsigned int filect);
|
||||
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: */
|
332
pacsync
332
pacsync
|
@ -1,332 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
version="1.23"
|
||||
tanpath="/var/lib/pacman"
|
||||
tandb="pacsync.db"
|
||||
errors=0
|
||||
upgrade=0
|
||||
INSTALL_ROOT="/"
|
||||
IGNORE_PKG=
|
||||
|
||||
message() {
|
||||
echo "==> $1" >&2
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "pacsync version $version"
|
||||
echo "usage: $0 [--root <root>] [--ignore <pkg>] <operation> [package]"
|
||||
echo ""
|
||||
echo "operations:"
|
||||
echo " sync Download a fresh package list from the server"
|
||||
echo " install <pkg> Download and install <pkg>"
|
||||
echo " upgrade <pkg> Download and upgrade <pkg>"
|
||||
echo " report Generate a report of all packages that could be upgraded"
|
||||
echo " sysupgrade Same as \"report\", but actually do the upgrades"
|
||||
echo " clean Removes all files from package cache to clear up diskspace"
|
||||
echo ""
|
||||
echo "options:"
|
||||
echo " --root <root> Set installation root to <root>"
|
||||
echo " --ignore <pkg> Ignore packages that have <pkg> in their names when doing"
|
||||
echo " sysupgrades. (--ignore can be used multiple times)"
|
||||
echo ""
|
||||
}
|
||||
|
||||
checkdb() {
|
||||
if [ ! -f $INSTALL_ROOT/$tanpath/$tandb ]; then
|
||||
message "missing package list. (use \"sync\" first)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download() {
|
||||
targ=$1
|
||||
shift
|
||||
cl=
|
||||
for file in $*; do
|
||||
# snarf returns a nonzero error code when the file already exists, which
|
||||
# confuses pacsync, so for now, no resume action...
|
||||
rm -f $file
|
||||
|
||||
cl="$cl $SYNC_SERVER/$file"
|
||||
done
|
||||
message "Downloading $targ"
|
||||
$ftpagent $cl 2>&1
|
||||
if [ $? -gt 0 ]; then
|
||||
message "error: could not download $targ"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
dosync() {
|
||||
download "package list" pacsync/$tandb
|
||||
if [ $? -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
rm -f $INSTALL_ROOT/$tanpath/$tandb
|
||||
mv $tandb $INSTALL_ROOT/$tanpath/$tandb
|
||||
message "Done."
|
||||
}
|
||||
|
||||
doinstall() {
|
||||
pkg2dl=
|
||||
pkg2inst=
|
||||
for pkgname in $*; do
|
||||
line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $INSTALL_ROOT/$tanpath/$tandb`
|
||||
if [ $? -gt 0 ]; then
|
||||
message "package $pkgname not found"
|
||||
exit 1
|
||||
fi
|
||||
pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
|
||||
if [ $? -eq 0 ]; then
|
||||
message "$pkgname is already installed (try using \"upgrade\")"
|
||||
exit 1
|
||||
fi
|
||||
filename=`echo $line | sed 's|^[a-z]*/||g'`
|
||||
pkg2inst="$pkg2inst $filename"
|
||||
if [ ! -f $INSTALL_ROOT/var/cache/pacman/pkg/$filename ]; then
|
||||
pkg2dl="$pkg2dl $filename"
|
||||
fi
|
||||
done
|
||||
|
||||
# download packages that aren't already cached
|
||||
if [ "$pkg2dl" != "" ]; then
|
||||
download "packages" $pkg2dl
|
||||
if [ $? -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
if [ `pwd` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
|
||||
# move downloaded files into cache
|
||||
mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
|
||||
mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
|
||||
fi
|
||||
fi
|
||||
|
||||
# install packages
|
||||
message "Installing packages"
|
||||
cd $INSTALL_ROOT/var/cache/pacman/pkg
|
||||
pacman -A -r $INSTALL_ROOT $pkg2inst
|
||||
if [ $? -gt 0 ]; then
|
||||
message "error: some packages failed to install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
message "Done"
|
||||
exit 0
|
||||
}
|
||||
|
||||
doupgrade() {
|
||||
pkg2dl=
|
||||
pkg2up=
|
||||
for pkgname in $*; do
|
||||
line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $INSTALL_ROOT/$tanpath/$tandb`
|
||||
if [ $? -gt 0 ]; then
|
||||
message "package $pkgname not found"
|
||||
exit 1
|
||||
fi
|
||||
pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
|
||||
if [ $? -gt 0 ]; then
|
||||
message "$pkgname is not installed (use \"install\" first)"
|
||||
exit 1
|
||||
fi
|
||||
pkgver=`echo $pacman | awk '{print $2}'`
|
||||
package="$pkgname-$pkgver"
|
||||
filename=`echo $line | sed 's|^[a-z]*/||g'`
|
||||
# compare filename and package. if they are at all different, we
|
||||
# assume that the newer version is on the server and do the upgrade
|
||||
if [ "$filename" = "$package.pkg.tar.gz" ]; then
|
||||
message "$pkgname is already up to date (skipping)"
|
||||
else
|
||||
pkg2up="$pkg2up $filename"
|
||||
if [ ! -f $INSTALL_ROOT/var/cache/pacman/pkg/$filename ]; then
|
||||
pkg2dl="$pkg2dl $filename"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# download packages that aren't already cached
|
||||
if [ "$pkg2dl" != "" ]; then
|
||||
download "packages" $pkg2dl
|
||||
if [ $? -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
if [ `pwd` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
|
||||
# move downloaded files into cache
|
||||
mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
|
||||
mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
|
||||
fi
|
||||
fi
|
||||
|
||||
# install packages
|
||||
if [ "$pkg2up" != "" ]; then
|
||||
message "Upgrading packages"
|
||||
cd $INSTALL_ROOT/var/cache/pacman/pkg
|
||||
pacman -U -r $INSTALL_ROOT $pkg2up
|
||||
if [ $? -gt 0 ]; then
|
||||
message "error: some packages failed to upgrade"
|
||||
exit 1
|
||||
fi
|
||||
message "Done"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
doreport() {
|
||||
headers=0
|
||||
newkernel=0
|
||||
pkg2up=
|
||||
for pkgfile in `cat $INSTALL_ROOT/$tanpath/$tandb | sed "s|^[a-z]*/||g"`; do
|
||||
pkgname=`echo $pkgfile | sed 's|-[a-zA-Z0-9\.]*-[0-9]*\.pkg\.tar\.gz||g'`
|
||||
pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
|
||||
if [ $? -gt 0 ]; then
|
||||
# skip this one, it's not installed
|
||||
continue
|
||||
fi
|
||||
pkgver=`echo $pacman | awk '{print $2}'`
|
||||
locfile="$pkgname-$pkgver"
|
||||
remfile=`echo $pkgfile | sed 's|^[a-zA-Z]*/||g' | sed 's|\.pkg\.tar\.gz||g'`
|
||||
# compare locfile and remfile
|
||||
if [ "$locfile" = "$remfile" ]; then
|
||||
# this package is up to date
|
||||
continue
|
||||
else
|
||||
if [ `echo "$locfile" | egrep '^kernel-[a-zA-Z0-9\.]+-[0-9]+$'` ]; then
|
||||
# this is the kernel pacakge -- we handle this one specially
|
||||
newkernel=1
|
||||
continue
|
||||
fi
|
||||
if [ "$IGNORE_PKG" != "" ]; then
|
||||
if [ `echo "$locfile" | egrep "$IGNORE_PKG"` ]; then
|
||||
# ignore this package as per user's request
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if [ "$headers" = "0" ]; then
|
||||
echo "+--------------------------------------+--------------------------------------+"
|
||||
echo "| LOCAL | REMOTE |"
|
||||
echo "+--------------------------------------+--------------------------------------+"
|
||||
headers=1
|
||||
fi
|
||||
echo -n "| $locfile"
|
||||
awk "BEGIN { for (j=length(\"$locfile\"); j<36; j++) printf \" \" }"
|
||||
echo -n " | "
|
||||
awk "BEGIN { for (j=length(\"$remfile\"); j<36; j++) printf \" \" }"
|
||||
echo "$remfile |"
|
||||
pkg2up="$pkg2up $pkgname"
|
||||
fi
|
||||
done
|
||||
if [ "$headers" = "1" ]; then
|
||||
echo "+--------------------------------------+--------------------------------------+"
|
||||
fi
|
||||
|
||||
if [ "$newkernel" = "1" ]; then
|
||||
echo
|
||||
echo "NOTICE: A new kernel is available for upgrade, but this process will not"
|
||||
echo " upgrade it for you. If you wish to upgrade, you must explicitly"
|
||||
echo " request it by running 'pacsync upgrade kernel'. If you choose to"
|
||||
echo " upgrade, make sure you re-run 'lilo' as well!"
|
||||
echo
|
||||
fi
|
||||
|
||||
# do we upgrade?
|
||||
if [ "$upgrade" = "1" -a "$pkg2up" != "" ]; then
|
||||
echo ""
|
||||
echo -n "Do you want to upgrade these packages? [Y/n] "
|
||||
read answer
|
||||
echo ""
|
||||
if [ "$answer" = "y" -o "$answer" = "Y" -o "$answer" = "" ]; then
|
||||
doupgrade $pkg2up
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
cd /tmp
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "--root" ]; then
|
||||
shift
|
||||
INSTALL_ROOT=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
while [ "$1" = "--ignore" ]; do
|
||||
shift
|
||||
if [ "$IGNORE_PKG" = "" ]; then
|
||||
IGNORE_PKG="$1"
|
||||
else
|
||||
IGNORE_PKG="$IGNORE_PKG|$1"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -f /etc/pacsync.conf ]; then
|
||||
. /etc/pacsync.conf
|
||||
else
|
||||
message "error: Missing /etc/pacsync.conf configuration file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
proto=`echo $SYNC_SERVER | sed 's|://.*||'`
|
||||
# check for a download utility
|
||||
if [ -x /usr/bin/snarf ]; then
|
||||
ftpagent="/usr/bin/snarf"
|
||||
elif [ -x /usr/bin/lftpget -a "$proto" = "ftp" ]; then
|
||||
ftpagent="/usr/bin/lftpget"
|
||||
elif [ -x /usr/bin/wget ]; then
|
||||
ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3"
|
||||
else
|
||||
message "error: you need an ftp client installed (snarf/lftp/wget) in /usr/bin"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
op=$1
|
||||
shift
|
||||
if [ "$1" = "-v" ]; then
|
||||
verbose=1
|
||||
shift
|
||||
fi
|
||||
case $op in
|
||||
sync)
|
||||
dosync
|
||||
;;
|
||||
install)
|
||||
checkdb
|
||||
if [ "$1" = "" ]; then
|
||||
message "error: no package specified"
|
||||
exit 1
|
||||
fi
|
||||
doinstall $*
|
||||
;;
|
||||
upgrade)
|
||||
checkdb
|
||||
if [ "$1" = "" ]; then
|
||||
message "error: no package specified"
|
||||
exit 1
|
||||
fi
|
||||
doupgrade $*
|
||||
;;
|
||||
report)
|
||||
checkdb
|
||||
doreport
|
||||
;;
|
||||
sysupgrade)
|
||||
checkdb
|
||||
upgrade=1
|
||||
doreport
|
||||
;;
|
||||
clean)
|
||||
message "Removing packages from cache"
|
||||
rm -f $INSTALL_ROOT/var/cache/pacman/pkg/*
|
||||
;;
|
||||
*)
|
||||
message "error: invalid operation"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
53
pacsync.8.in
53
pacsync.8.in
|
@ -1,53 +0,0 @@
|
|||
.TH pacsync 8 "Mar 17, 2002" "pacsync #VERSION#" ""
|
||||
.SH NAME
|
||||
pacsync \- package update frontend for pacman
|
||||
.SH SYNOPSIS
|
||||
\fBpacsync [--root <root>] <operation> [package] [package] ...\fP
|
||||
.SH DESCRIPTION
|
||||
\fBpacsync\fP is a \fIpackage update\fP frontend for the
|
||||
\fIpacman\fP package manager. It keeps track of the versions
|
||||
of packages installed on the local system and the versions of
|
||||
packages on a remote server. This allows you to issue a single
|
||||
command and have you system's packages brought into sync.
|
||||
.SH OPERATIONS
|
||||
.TP
|
||||
.B "sync"
|
||||
Download a new copy of the package list from the server. This
|
||||
should be done regularly, usually before an "install", "upgrade"
|
||||
or "sysupgrade" command.
|
||||
.TP
|
||||
.B "install <package>"
|
||||
Install a new package. \fBpacsync\fP will first look for the package
|
||||
in the cache directory. If it is not there, it will attempt to
|
||||
download the file from the server. On success, the package will
|
||||
be installed. (Note that the downloaded file is also copied to
|
||||
a cache directory on your filesystem. You can delete it with
|
||||
"clean").
|
||||
.TP
|
||||
.B "upgrade <package>"
|
||||
Upgrade a package. This is the same as \fIinstall\fP, except a package
|
||||
is upgraded (ie, it is already installed in the system).
|
||||
.TP
|
||||
.B "report"
|
||||
Generate an upgrade report. This operation will compare all local
|
||||
package versions to remote versions, and then show you a report of
|
||||
the differences.
|
||||
.TP
|
||||
.B "sysupgrade"
|
||||
Full system upgrade. This is the same as report except after confirmation,
|
||||
\fBpacsync\fP will upgrade all packages that are not up to date.
|
||||
.TP
|
||||
.B "clean"
|
||||
This will remove all downloaded packages from the cache directory. This
|
||||
can/should be used regularly to free up diskspace.
|
||||
.SH CONFIGURATION
|
||||
Configuration options are stored in /etc/pacsync.conf. Currently there is only
|
||||
one directive.
|
||||
.TP
|
||||
.B "SYNC_SERVER"
|
||||
This should be set to the full URL of the download server closest to you.
|
||||
FTP is preferred, but HTTP is supported also, provided you have wget.
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Judd Vinet <jvinet@zeroflux.org>
|
||||
.fi
|
58
pacsync.conf
58
pacsync.conf
|
@ -1,58 +0,0 @@
|
|||
#
|
||||
# /etc/pacsync.conf
|
||||
#
|
||||
#
|
||||
# From here you can configure pacsync to follow a certain package tree.
|
||||
# Typically this is either 'stable' or 'current', but you can pick
|
||||
# specific versions as well (eg, '0.2'). Read below for the structure.
|
||||
#
|
||||
|
||||
# Arch Linux servers follow this directory structure:
|
||||
#
|
||||
# 0.1
|
||||
# |- iso
|
||||
# | |- i686
|
||||
# |- os
|
||||
# | |- i686
|
||||
# 0.2
|
||||
# |- iso
|
||||
# | |- i686
|
||||
# |- os
|
||||
# | |- i686
|
||||
# 0.3
|
||||
# |- iso
|
||||
# | |- i686
|
||||
# |- os
|
||||
# | |- i686
|
||||
# current -> 0.3/os/i686
|
||||
# stable -> 0.2/os/i686
|
||||
#
|
||||
#
|
||||
# Set your SYNC_SERVER according to the version you wish to follow. For
|
||||
# example, if you simply wish to follow the stable branch (whatever version
|
||||
# it may be), then you can set SYNC_SERVER as follows:
|
||||
#
|
||||
# SYNC_SERVER="ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/stable"
|
||||
#
|
||||
# Other examples:
|
||||
# SYNC_SERVER="ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/0.2/os/i686"
|
||||
# SYNC_SERVER="ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/0.3/os/i686"
|
||||
# SYNC_SERVER="ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current"
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# SYNC_SERVER: the full location of the package repository (ftp or http)
|
||||
#
|
||||
SYNC_SERVER="ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current"
|
||||
|
||||
|
||||
#
|
||||
# OTHER LOCATIONS (MIRRORS)
|
||||
#
|
||||
# Note: ibiblio.org will typically be fastest. Please stick with them unless
|
||||
# you've got a good reason to change.
|
||||
#
|
||||
#SYNC_SERVER="http://www.ibiblio.org/pub/linux/distributions/archlinux/current"
|
||||
#SYNC_SERVER="ftp://ftp2.archlinux.org/current"
|
||||
#SYNC_SERVER="ftp://ftp.archlinux.org/current"
|
54
scripts/abs
Executable file
54
scripts/abs
Executable file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
myver='2.0'
|
||||
ABS_ROOT=/usr/abs
|
||||
|
||||
usage() {
|
||||
echo "abs $myver"
|
||||
echo "usage: $0"
|
||||
echo
|
||||
echo "abs will synchronize PKGBUILD scripts from the CVS repository"
|
||||
echo "into /usr/abs. You can follow different package trees by editing"
|
||||
echo "/etc/abs/supfile"
|
||||
echo
|
||||
exit 0
|
||||
}
|
||||
|
||||
update() {
|
||||
if [ ! `type -p cvsup` ]; then
|
||||
echo "abs: cvsup was not found in PATH. Install cvsup"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$ABS_ROOT" ]; then
|
||||
echo "abs: directory $ABS_ROOT does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -r /etc/abs/supfile ]; then
|
||||
echo "abs: missing config file /etc/abs/supfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "`id -u`" != "0" ]; then
|
||||
echo "abs: you must be root to update your ABS tree"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $ABS_ROOT && cvsup -L 1 -r 0 -g -c .sup /etc/abs/supfile
|
||||
}
|
||||
|
||||
for opt in "$@"; do
|
||||
case $opt in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0 ;;
|
||||
*)
|
||||
echo "abs: invalid option \"$opt\""
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
update
|
||||
|
||||
exit 0
|
252
scripts/makepkg
Executable file
252
scripts/makepkg
Executable file
|
@ -0,0 +1,252 @@
|
|||
#!/bin/bash
|
||||
|
||||
myver='2.0'
|
||||
startdir=`pwd`
|
||||
|
||||
[ -f /etc/makepkg.conf ] && source /etc/makepkg.conf
|
||||
|
||||
strip_url() {
|
||||
echo $1 | sed 's|^.*://.*/||g'
|
||||
}
|
||||
|
||||
msg() {
|
||||
echo $* >&2
|
||||
}
|
||||
|
||||
if [ "$1" = "--help" -o "$1" = "-h" ]; then
|
||||
shift
|
||||
echo "makepkg version $myver"
|
||||
echo "usage: $0 [options] [build_script]"
|
||||
echo "options:"
|
||||
echo " -c, --clean Clean up work files after build"
|
||||
echo " -i, --install Install package after successful build"
|
||||
echo " -h, --help This help"
|
||||
echo
|
||||
echo " if build_script is not specified, makepkg will look for a PKGBUILD"
|
||||
echo " file in the current directory."
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CLEANUP=0
|
||||
INSTALL=0
|
||||
|
||||
if [ "$1" = "-c" -o "$1" = "--clean" ]; then
|
||||
shift
|
||||
CLEANUP=1
|
||||
fi
|
||||
if [ "$1" = "-i" -o "$1" = "--install" ]; then
|
||||
shift
|
||||
INSTALL=1
|
||||
fi
|
||||
|
||||
unset pkgname pkgver pkgrel pkgdesc
|
||||
unset depends conflicts backup source install build
|
||||
umask 0022
|
||||
|
||||
|
||||
# check for a download utility
|
||||
if [ -x /usr/bin/wget ]; then
|
||||
ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3"
|
||||
elif [ -x /usr/bin/snarf ]; then
|
||||
ftpagent="/usr/bin/snarf"
|
||||
elif [ -x /usr/bin/lftpget -a "$proto" = "ftp" ]; then
|
||||
ftpagent="/usr/bin/lftpget"
|
||||
else
|
||||
msg "==> ERROR: You need an ftp client installed (snarf/lftp/wget) in /usr/bin"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILDSCRIPT="./PKGBUILD"
|
||||
if [ "$1" != "" ]; then
|
||||
BUILDSCRIPT=$1
|
||||
fi
|
||||
|
||||
if [ ! -f $BUILDSCRIPT ]; then
|
||||
msg "==> ERROR: $BUILDSCRIPT does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source $BUILDSCRIPT
|
||||
|
||||
# check for no-no's
|
||||
if [ `echo $pkgver | grep '-'` ]; then
|
||||
msg "==> ERROR: pkgver is not allowed to contain hyphens."
|
||||
exit 1
|
||||
fi
|
||||
if [ `echo $pkgrel | grep '-'` ]; then
|
||||
msg "==> ERROR: pkgrel is not allowed to contain hyphens."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ `type -p pacman` ]; then
|
||||
msg "==> Checking Dependencies..."
|
||||
missdep=`pacman -T ${depends[@]}`
|
||||
ret=$?
|
||||
if [ "$ret" != "0" ]; then
|
||||
if [ "$ret" = "127" ]; then
|
||||
msg "==> ERROR: Dependency Check Failed:"
|
||||
msg ""
|
||||
nl=0
|
||||
for dep in $missdep; do
|
||||
echo -ne "$dep " >&2
|
||||
if [ "$nl" = "1" ]; then
|
||||
nl=0
|
||||
echo -ne "\n" >&2
|
||||
continue
|
||||
fi
|
||||
nl=1
|
||||
done
|
||||
msg ""
|
||||
else
|
||||
msg "==> ERROR: pacman returned a fatal error."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
msg "==> WARNING: pacman was not found in PATH. skipping dependency checks."
|
||||
fi
|
||||
|
||||
d=`date`
|
||||
msg "==> Making package $pkgname ($d)"
|
||||
|
||||
# extract source
|
||||
msg "==> Acquiring/Extracting Sources..."
|
||||
mkdir -p src
|
||||
cd $startdir/src
|
||||
for netfile in ${source[@]}; do
|
||||
file=`strip_url $netfile`
|
||||
if [ -f ../$file ]; then
|
||||
msg "==> Found $file in build dir"
|
||||
cp ../$file .
|
||||
elif [ -f /var/cache/pacman/src/$file ]; then
|
||||
msg "==> Using local copy of $file"
|
||||
cp /var/cache/pacman/src/$file .
|
||||
else
|
||||
proto=`echo $netfile | sed 's|://.*||'`
|
||||
if [ "$proto" != "ftp" -a "$proto" != "http" ]; then
|
||||
msg "==> ERROR: $netfile was not found in the build directory and is not a proper URL."
|
||||
msg "==> Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
msg "==> Downloading $file"
|
||||
$ftpagent $netfile 2>&1
|
||||
if [ ! -f $file ]; then
|
||||
msg "==> ERROR: Failed to download $file"
|
||||
msg "==> Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p /var/cache/pacman/src && cp $file /var/cache/pacman/src
|
||||
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" ;;
|
||||
*.tar)
|
||||
cmd="tar -xf $file" ;;
|
||||
*.zip)
|
||||
cmd="unzip -qq $file" ;;
|
||||
*)
|
||||
cmd="cp ../$file ." ;;
|
||||
esac
|
||||
msg "==> $cmd"
|
||||
$cmd
|
||||
done
|
||||
|
||||
# check for existing pkg directory
|
||||
if [ -d $startdir/pkg ]; then
|
||||
msg "==> Removing existing pkg directory..."
|
||||
rm -rf $startdir/pkg
|
||||
fi
|
||||
mkdir -p $startdir/pkg
|
||||
|
||||
# build
|
||||
msg "==> Building Package..."
|
||||
build 2>&1
|
||||
if [ $? -gt 0 ]; then
|
||||
msg "==> Build Failed. Aborting..."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# get some package meta info
|
||||
builddate=`date -u "+%a %b %d %k:%M:%S %Y"`
|
||||
if [ "$PACKAGER" != "" ]; then
|
||||
packager="$PACKAGER"
|
||||
else
|
||||
packager="Arch Linux (http://www.archlinux.org)"
|
||||
fi
|
||||
size=`du -cb $startdir/pkg | tail -1 | awk '{print $1}'`
|
||||
|
||||
# write the .PKGINFO file
|
||||
msg "==> 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
|
||||
echo "pkgdesc = $pkgdesc" >>.PKGINFO
|
||||
echo "builddate = $builddate" >>.PKGINFO
|
||||
echo "packager = $packager" >>.PKGINFO
|
||||
echo "size = $size" >>.PKGINFO
|
||||
|
||||
for depend in "${depends[@]}"; do
|
||||
echo "depend = $depend" >>.PKGINFO
|
||||
done
|
||||
for conflict in "${conflicts[@]}"; do
|
||||
echo "conflict = $conflict" >>.PKGINFO
|
||||
done
|
||||
for bakfile in "${backup[@]}"; do
|
||||
echo "backup = $bakfile" >>.PKGINFO
|
||||
done
|
||||
|
||||
# check for an install script
|
||||
if [ "$install" != "" ]; then
|
||||
msg "==> Copying install script..."
|
||||
cp $startdir/$install $startdir/pkg/._install
|
||||
fi
|
||||
|
||||
# remove info/doc files
|
||||
cd $startdir
|
||||
rm -rf pkg/usr/info pkg/usr/share/info
|
||||
rm -rf pkg/usr/doc pkg/usr/share/doc
|
||||
|
||||
# move /usr/share/man files to /usr/man
|
||||
if [ -d pkg/usr/share/man ]; then
|
||||
mkdir -p pkg/usr/man
|
||||
cp -a pkg/usr/share/man/* pkg/usr/man/
|
||||
rm -rf pkg/usr/share/man
|
||||
fi
|
||||
|
||||
# strip binaries
|
||||
cd $startdir
|
||||
msg "==> Stripping debugging symbols from libraries..."
|
||||
find pkg/{,usr,usr/local}/lib -type f -exec /usr/bin/strip --strip-debug '{}' ';' 2>&1
|
||||
msg "==> Stripping symbols from binaries..."
|
||||
find pkg/{,usr,usr/local}/{bin,sbin} -type f -exec /usr/bin/strip '{}' ';' 2>&1
|
||||
|
||||
# tar it up
|
||||
msg "==> Compressing package..."
|
||||
cd $startdir/pkg
|
||||
if [ -f $startdir/pkg/._install ]; then
|
||||
tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO ._install * >../filelist
|
||||
else
|
||||
tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
|
||||
fi
|
||||
|
||||
cd $startdir
|
||||
if [ "$CLEANUP" = "1" ]; then
|
||||
msg "==> Cleaning up"
|
||||
rm -rf src pkg
|
||||
fi
|
||||
|
||||
d=`date`
|
||||
msg "==> Finished making $pkgname ($d)"
|
||||
|
||||
if [ "$INSTALL" = "1" ]; then
|
||||
msg "==> Running pacman --upgrade"
|
||||
pacman --upgrade $pkgname-$pkgver-$pkgrel.pkg.tar.gz
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -1,11 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
toplevel=`pwd`
|
||||
version="1.23"
|
||||
version="2.0"
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "makepkg version $version"
|
||||
echo "usage: $0 <destdir> <category> [category] ..."
|
||||
if [ $# -lt 2 -o "$1" = "--help" -o "$1" = "-h" ]; then
|
||||
echo "makeworld version $version"
|
||||
echo "usage: $0 [options] <destdir> <category> [category] ..."
|
||||
echo "options:"
|
||||
echo " -c, --clean Clean up work files after build"
|
||||
echo " -i, --install Install package after successful build"
|
||||
echo " -h, --help This help"
|
||||
echo
|
||||
echo " where <category> is one or more of base, opt, contrib"
|
||||
echo " eg: makeworld /packages base opt"
|
||||
echo
|
||||
|
@ -13,6 +18,16 @@ if [ $# -lt 2 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
MAKEPKG_OPTS=
|
||||
if [ "$1" = "-c" -o "$1" = "--clean" ]; then
|
||||
shift
|
||||
MAKEPKG_OPTS="$MAKEPKG_OPTS -c"
|
||||
fi
|
||||
if [ "$1" = "-i" -o "$1" = "--install" ]; then
|
||||
shift
|
||||
MAKEPKG_OPTS="$MAKEPKG_OPTS -i"
|
||||
fi
|
||||
|
||||
dest=$1
|
||||
shift
|
||||
|
||||
|
@ -25,7 +40,7 @@ for category in $*; do
|
|||
. PKGBUILD
|
||||
buildstatus=0
|
||||
if [ ! -f $dest/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then
|
||||
makepkg
|
||||
makepkg $MAKEPKG_OPTS 2>>$toplevel/makepkg.log
|
||||
if [ $? -gt 0 ]; then
|
||||
buildstatus=2
|
||||
else
|
6
scripts/pacsync
Executable file
6
scripts/pacsync
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo
|
||||
echo "Pacman 2.0 no longer comes with pacsync. Use 'pacman -S' instead."
|
||||
echo " (see 'pacman -S --help' or the manpage for syntax)"
|
||||
echo
|
163
src/convertdb.c
Normal file
163
src/convertdb.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "list.h"
|
||||
|
||||
char* trim(char *str);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE* db = NULL;
|
||||
FILE* fp = NULL;
|
||||
char* ptr = NULL;
|
||||
char* dbdir = "/var/lib/pacman/pacman.db";
|
||||
char name[256];
|
||||
char ver[256];
|
||||
char line[PATH_MAX+1];
|
||||
char topdir[PATH_MAX+1];
|
||||
char path[PATH_MAX+1];
|
||||
mode_t oldumask;
|
||||
struct stat buf;
|
||||
|
||||
if(argc < 2) {
|
||||
printf("converts a pacman 1.x database to a pacman 2.0 format\n");
|
||||
printf("usage: %s <target_dir>\n\n", basename(argv[0]));
|
||||
printf("convertdb will convert all package data from /var/lib/pacman/pacman.db\n");
|
||||
printf("to a 2.0 format and place it in target_dir.\n\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
db = fopen(dbdir, "r");
|
||||
if(db == NULL) {
|
||||
perror(dbdir);
|
||||
return(1);
|
||||
}
|
||||
|
||||
oldumask = umask(0000);
|
||||
while(fgets(name, 255, db)) {
|
||||
PMList *backup = NULL;
|
||||
PMList *lp;
|
||||
|
||||
if(!fgets(ver, 255, db)) {
|
||||
perror(dbdir);
|
||||
return(1);
|
||||
}
|
||||
trim(name);
|
||||
trim(ver);
|
||||
fprintf(stderr, "converting %s\n", name);
|
||||
/* package directory */
|
||||
snprintf(topdir, PATH_MAX, "%s/%s-%s", argv[1], name, ver);
|
||||
mkdir(topdir, 0755);
|
||||
|
||||
/* DESC */
|
||||
snprintf(path, PATH_MAX, "%s/desc", topdir);
|
||||
if(!(fp = fopen(path, "w"))) {
|
||||
perror(path);
|
||||
return(1);
|
||||
}
|
||||
fputs("%NAME%\n", fp);
|
||||
fprintf(fp, "%s\n\n", name);
|
||||
fputs("%VERSION%\n", fp);
|
||||
fprintf(fp, "%s\n\n", ver);
|
||||
fputs("%DESC%\n\n", fp);
|
||||
fclose(fp);
|
||||
|
||||
/* DEPENDS */
|
||||
snprintf(path, PATH_MAX, "%s/depends", topdir);
|
||||
if(!(fp = fopen(path, "w"))) {
|
||||
perror(path);
|
||||
return(1);
|
||||
}
|
||||
fputs("%DEPENDS%\n\n", fp);
|
||||
fputs("%REQUIREDBY%\n\n", fp);
|
||||
fputs("%CONFLICTS%\n\n", fp);
|
||||
fclose(fp);
|
||||
|
||||
/* FILES */
|
||||
snprintf(path, PATH_MAX, "%s/files", topdir);
|
||||
if(!(fp = fopen(path, "w"))) {
|
||||
perror(path);
|
||||
return(1);
|
||||
}
|
||||
fputs("%FILES%\n", fp);
|
||||
while(fgets(line, 255, db) && strcmp(trim(line), "")) {
|
||||
trim(line);
|
||||
ptr = line;
|
||||
|
||||
/* check for backup designation and frontslashes that shouldn't be there */
|
||||
if(line[0] == '*') ptr++;
|
||||
if(*ptr == '/') ptr++;
|
||||
if(line[0] == '*') backup = list_add(backup, strdup(ptr));
|
||||
|
||||
fprintf(fp, "%s\n", ptr);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fputs("%BACKUP%\n", fp);
|
||||
for(lp = backup; lp; lp = lp->next) {
|
||||
/* print the filename and a bad md5 hash. we just use 32 f's cuz we can't
|
||||
* md5 the original file since we don't have it
|
||||
*/
|
||||
fprintf(fp, "%s\tffffffffffffffffffffffffffffffff\n", (char*)lp->data);
|
||||
}
|
||||
fputs("\n", fp);
|
||||
fclose(fp);
|
||||
snprintf(path, PATH_MAX, "/var/lib/pacman/scripts/%s", name);
|
||||
if(!stat(path, &buf)) {
|
||||
snprintf(line, PATH_MAX, "/bin/cp %s %s/install", path, topdir);
|
||||
system(line);
|
||||
}
|
||||
list_free(backup);
|
||||
}
|
||||
umask(oldumask);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Trim whitespace and newlines from a string
|
||||
*/
|
||||
char* trim(char *str)
|
||||
{
|
||||
char *pch = str;
|
||||
while(isspace(*pch)) {
|
||||
pch++;
|
||||
}
|
||||
if(pch != str) {
|
||||
memmove(str, pch, (strlen(pch) + 1));
|
||||
}
|
||||
|
||||
pch = (char*)(str + (strlen(str) - 1));
|
||||
while(isspace(*pch)) {
|
||||
pch--;
|
||||
}
|
||||
*++pch = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
508
src/db.c
Normal file
508
src/db.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "list.h"
|
||||
#include "package.h"
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
#include "pacman.h"
|
||||
|
||||
extern PMList *pm_packages;
|
||||
extern char *pmo_root;
|
||||
extern unsigned short pmo_upgrade;
|
||||
|
||||
extern int errno;
|
||||
|
||||
/* Verify database integrity and build a list of
|
||||
* installed packages
|
||||
*
|
||||
* returns: 0 on success
|
||||
* 1 if db is not initialized
|
||||
* 2 if db is corrupt
|
||||
*/
|
||||
pacdb_t* db_open(char *dbpath, char *treename)
|
||||
{
|
||||
pacdb_t *db = NULL;
|
||||
char path[PATH_MAX];
|
||||
|
||||
MALLOC(db, sizeof(pacdb_t));
|
||||
snprintf(path, PATH_MAX-1, "%s/%s", dbpath, treename);
|
||||
db->dir = opendir(path);
|
||||
if(db->dir == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
strncpy(db->treename, treename, 128);
|
||||
|
||||
return(db);
|
||||
}
|
||||
|
||||
void db_close(pacdb_t* db)
|
||||
{
|
||||
closedir(db->dir);
|
||||
return;
|
||||
}
|
||||
|
||||
/* frees pkgcache if necessary and returns a new package
|
||||
* cache from db
|
||||
*/
|
||||
PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache)
|
||||
{
|
||||
pkginfo_t *info;
|
||||
PMList *lp;
|
||||
pkginfo_t **arr = NULL;
|
||||
unsigned int arrct = 0;
|
||||
int i;
|
||||
PMList *cache = NULL;
|
||||
|
||||
/* if pm_packages already contains data, free it first */
|
||||
for(lp = pkgcache; lp; lp = lp->next) {
|
||||
if(lp->data) {
|
||||
freepkg(lp->data);
|
||||
lp->data = NULL;
|
||||
}
|
||||
}
|
||||
list_free(pkgcache);
|
||||
|
||||
rewinddir(db->dir);
|
||||
while((info = db_scan(db, NULL, INFRQ_DESC)) != NULL) {
|
||||
/* add to the collective */
|
||||
/* we load all package names into a linear array first, so qsort can handle it */
|
||||
if(arr == NULL) {
|
||||
arr = (pkginfo_t**)malloc(sizeof(pkginfo_t*));
|
||||
arrct++;
|
||||
} else {
|
||||
arr = (pkginfo_t**)realloc(arr, (++arrct)*sizeof(pkginfo_t*));
|
||||
}
|
||||
if(arr == NULL) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
arr[arrct-1] = info;
|
||||
}
|
||||
|
||||
/* sort the package list */
|
||||
qsort(arr, (size_t)arrct, sizeof(pkginfo_t*), pkgcmp);
|
||||
|
||||
/* now load them into the proper PMList */
|
||||
for(i = 0; i < arrct; i++) {
|
||||
cache = list_add(cache, arr[i]);
|
||||
}
|
||||
|
||||
return(cache);
|
||||
}
|
||||
|
||||
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
||||
{
|
||||
struct dirent *ent = NULL;
|
||||
char name[256];
|
||||
char *ptr = NULL;
|
||||
int found = 0;
|
||||
|
||||
if(target != NULL) {
|
||||
/* search for a specific package (by name only) */
|
||||
rewinddir(db->dir);
|
||||
/* read the . and .. first */
|
||||
ent = readdir(db->dir);
|
||||
ent = readdir(db->dir);
|
||||
|
||||
ent = readdir(db->dir);
|
||||
while(!found && ent != NULL) {
|
||||
strncpy(name, ent->d_name, 255);
|
||||
/* truncate the string at the second-to-last hyphen, */
|
||||
/* which will give us the package name */
|
||||
if((ptr = rindex(name, '-'))) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
if((ptr = rindex(name, '-'))) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
if(!strcmp(name, target)) {
|
||||
found = 1;
|
||||
continue;
|
||||
}
|
||||
ent = readdir(db->dir);
|
||||
}
|
||||
if(!found) {
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
/* normal iteration */
|
||||
ent = readdir(db->dir);
|
||||
if(ent && !strcmp(ent->d_name, ".")) {
|
||||
ent = readdir(db->dir);
|
||||
}
|
||||
if(ent && !strcmp(ent->d_name, "..")) {
|
||||
ent = readdir(db->dir);
|
||||
}
|
||||
if(ent == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
return(db_read(db, ent, inforeq));
|
||||
}
|
||||
|
||||
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
struct stat buf;
|
||||
pkginfo_t *info = NULL;
|
||||
char path[PATH_MAX];
|
||||
char topdir[PATH_MAX];
|
||||
char line[512];
|
||||
|
||||
if(ent == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
snprintf(topdir, PATH_MAX, "%s%s/%s", pmo_root, PKGDIR, db->treename);
|
||||
info = newpkg();
|
||||
|
||||
/* we always load DESC */
|
||||
inforeq |= INFRQ_DESC;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s/%s", topdir, ent->d_name);
|
||||
if(stat(path, &buf)) {
|
||||
/* directory doesn't exist or can't be opened */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* DESC */
|
||||
if(inforeq & INFRQ_DESC) {
|
||||
snprintf(path, PATH_MAX, "%s/%s/desc", topdir, ent->d_name);
|
||||
fp = fopen(path, "r");
|
||||
if(fp == NULL) {
|
||||
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
|
||||
return(NULL);
|
||||
}
|
||||
while(!feof(fp)) {
|
||||
if(fgets(line, 256, fp) == NULL) {
|
||||
break;
|
||||
}
|
||||
trim(line);
|
||||
if(!strcmp(line, "%NAME%")) {
|
||||
if(fgets(info->name, 256, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->name);
|
||||
} else if(!strcmp(line, "%VERSION%")) {
|
||||
if(fgets(info->version, 64, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->version);
|
||||
} else if(!strcmp(line, "%DESC%")) {
|
||||
if(fgets(info->desc, 512, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->desc);
|
||||
} else if(!strcmp(line, "%BUILDDATE%")) {
|
||||
if(fgets(info->builddate, 32, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->builddate);
|
||||
} else if(!strcmp(line, "%INSTALLDATE%")) {
|
||||
if(fgets(info->installdate, 32, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->installdate);
|
||||
} else if(!strcmp(line, "%PACKAGER%")) {
|
||||
if(fgets(info->packager, 64, fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(info->packager);
|
||||
} else if(!strcmp(line, "%SIZE%")) {
|
||||
char tmp[32];
|
||||
if(fgets(tmp, sizeof(tmp), fp) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
trim(tmp);
|
||||
info->size = atol(tmp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* FILES */
|
||||
if(inforeq & INFRQ_FILES) {
|
||||
snprintf(path, PATH_MAX, "%s/%s/files", topdir, ent->d_name);
|
||||
fp = fopen(path, "r");
|
||||
if(fp == NULL) {
|
||||
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
|
||||
return(NULL);
|
||||
}
|
||||
while(fgets(line, 256, fp)) {
|
||||
trim(line);
|
||||
if(!strcmp(line, "%FILES%")) {
|
||||
while(fgets(line, 512, fp) && strlen(trim(line))) {
|
||||
char *s = strdup(line);
|
||||
info->files = list_add(info->files, s);
|
||||
}
|
||||
}
|
||||
if(!strcmp(line, "%BACKUP%")) {
|
||||
while(fgets(line, 512, fp) && strlen(trim(line))) {
|
||||
char *s = strdup(line);
|
||||
info->backup = list_add(info->backup, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* DEPENDS */
|
||||
if(inforeq & INFRQ_DEPENDS) {
|
||||
snprintf(path, PATH_MAX, "%s/%s/depends", topdir, ent->d_name);
|
||||
fp = fopen(path, "r");
|
||||
if(fp == NULL) {
|
||||
fprintf(stderr, "db_read: error: %s: %s\n", path, strerror(errno));
|
||||
return(NULL);
|
||||
}
|
||||
while(!feof(fp)) {
|
||||
fgets(line, 255, fp);
|
||||
trim(line);
|
||||
if(!strcmp(line, "%DEPENDS%")) {
|
||||
while(fgets(line, 512, fp) && strlen(trim(line))) {
|
||||
char *s = strdup(line);
|
||||
info->depends = list_add(info->depends, s);
|
||||
}
|
||||
}
|
||||
if(!strcmp(line, "%REQUIREDBY%")) {
|
||||
while(fgets(line, 512, fp) && strlen(trim(line))) {
|
||||
char *s = strdup(line);
|
||||
info->requiredby = list_add(info->requiredby, s);
|
||||
}
|
||||
}
|
||||
if(!strcmp(line, "%CONFLICTS%")) {
|
||||
while(fgets(line, 512, fp) && strlen(trim(line))) {
|
||||
char *s = strdup(line);
|
||||
info->conflicts = list_add(info->conflicts, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* INSTALL */
|
||||
snprintf(path, PATH_MAX, "%s/%s/install", topdir, ent->d_name);
|
||||
if(!stat(path, &buf)) {
|
||||
info->scriptlet = 1;
|
||||
}
|
||||
|
||||
return(info);
|
||||
}
|
||||
|
||||
int db_write(pacdb_t *db, pkginfo_t *info)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char topdir[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
mode_t oldmask;
|
||||
PMList *lp = NULL;
|
||||
|
||||
if(info == NULL) {
|
||||
return(1);
|
||||
}
|
||||
snprintf(topdir, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, PKGDIR, db->treename,
|
||||
info->name, info->version);
|
||||
|
||||
oldmask = umask(0000);
|
||||
mkdir(topdir, 0755);
|
||||
umask(oldmask);
|
||||
|
||||
/* DESC */
|
||||
snprintf(path, PATH_MAX, "%s/desc", topdir);
|
||||
fp = fopen(path, "w");
|
||||
if(fp == NULL) {
|
||||
perror("db_write");
|
||||
return(1);
|
||||
}
|
||||
fputs("%NAME%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->name);
|
||||
fputs("%VERSION%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->version);
|
||||
fputs("%DESC%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->desc);
|
||||
fputs("%BUILDDATE%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->builddate);
|
||||
fputs("%INSTALLDATE%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->installdate);
|
||||
fputs("%PACKAGER%\n", fp);
|
||||
fprintf(fp, "%s\n\n", info->packager);
|
||||
fputs("%SIZE%\n", fp);
|
||||
fprintf(fp, "%ld\n\n", info->size);
|
||||
fclose(fp);
|
||||
|
||||
/* FILES */
|
||||
snprintf(path, PATH_MAX, "%s/files", topdir);
|
||||
fp = fopen(path, "w");
|
||||
if(fp == NULL) {
|
||||
perror("db_write");
|
||||
return(1);
|
||||
}
|
||||
fputs("%FILES%\n", fp);
|
||||
for(lp = info->files; lp; lp = lp->next) {
|
||||
fprintf(fp, "%s\n", (char*)lp->data);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fputs("%BACKUP%\n", fp);
|
||||
for(lp = info->backup; lp; lp = lp->next) {
|
||||
fprintf(fp, "%s\n", (char*)lp->data);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fclose(fp);
|
||||
|
||||
/* DEPENDS */
|
||||
snprintf(path, PATH_MAX, "%s/depends", topdir);
|
||||
fp = fopen(path, "w");
|
||||
if(fp == NULL) {
|
||||
perror("db_write");
|
||||
return(1);
|
||||
}
|
||||
fputs("%DEPENDS%\n", fp);
|
||||
for(lp = info->depends; lp; lp = lp->next) {
|
||||
fprintf(fp, "%s\n", (char*)lp->data);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fputs("%REQUIREDBY%\n", fp);
|
||||
for(lp = info->requiredby; lp; lp = lp->next) {
|
||||
fprintf(fp, "%s\n", (char*)lp->data);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fputs("%CONFLICTS%\n", fp);
|
||||
for(lp = info->conflicts; lp; lp = lp->next) {
|
||||
fprintf(fp, "%s\n", (char*)lp->data);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fclose(fp);
|
||||
|
||||
/* INSTALL */
|
||||
/* nothing needed here (script is automatically extracted) */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
PMList* db_find_conflicts(pacdb_t *db, PMList *targets)
|
||||
{
|
||||
PMList *i, *j, *k;
|
||||
char *filestr = NULL;
|
||||
char path[PATH_MAX+1];
|
||||
char *str = NULL;
|
||||
struct stat buf;
|
||||
PMList *conflicts = NULL;
|
||||
|
||||
/* CHECK 1: check every db package against every target package */
|
||||
/* XXX: I've disabled the database-against-targets check for now, as the
|
||||
* many many strcmp() calls slow it down heavily and most of the
|
||||
* checking is redundant to the targets-against-filesystem check.
|
||||
* This will be re-enabled if I can improve performance significantly.
|
||||
*
|
||||
pkginfo_t *info = NULL;
|
||||
char *dbstr = NULL;
|
||||
vprint("Checking database against targets...\n");
|
||||
rewinddir(db->dir);
|
||||
while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL) {
|
||||
for(i = info->files; i; i = i->next) {
|
||||
if(i->data == NULL) continue;
|
||||
dbstr = (char*)i->data;
|
||||
for(j = targets; j; j = j->next) {
|
||||
pkginfo_t *targ = (pkginfo_t*)j->data;
|
||||
if(strcmp(info->name, targ->name)) {
|
||||
for(k = targ->files; k; k = k->next) {
|
||||
filestr = (char*)k->data;
|
||||
if(!strcmp(dbstr, filestr)) {
|
||||
if(rindex(k->data, '/') == filestr+strlen(filestr)-1) {
|
||||
continue;
|
||||
}
|
||||
MALLOC(str, 512);
|
||||
snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (installed)", dbstr,
|
||||
targ->name, info->name);
|
||||
conflicts = list_add(conflicts, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/* CHECK 2: check every target against every target */
|
||||
vprint("Checking targets against targets...\n");
|
||||
for(i = targets; i; i = i->next) {
|
||||
pkginfo_t *p1 = (pkginfo_t*)i->data;
|
||||
for(j = i; j; j = j->next) {
|
||||
pkginfo_t *p2 = (pkginfo_t*)j->data;
|
||||
if(strcmp(p1->name, p2->name)) {
|
||||
for(k = p1->files; k; k = k->next) {
|
||||
filestr = k->data;
|
||||
if(!strcmp(filestr, "._install")) {
|
||||
continue;
|
||||
}
|
||||
if(rindex(filestr, '/') == filestr+strlen(filestr)-1) {
|
||||
/* this filename has a trailing '/', so it's a directory -- skip it. */
|
||||
continue;
|
||||
}
|
||||
if(is_in(filestr, p2->files)) {
|
||||
MALLOC(str, 512);
|
||||
snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (target)",
|
||||
filestr, p1->name, p2->name);
|
||||
conflicts = list_add(conflicts, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CHECK 3: check every target against the filesystem */
|
||||
vprint("Checking targets against filesystem...\n");
|
||||
for(i = targets; i; i = i->next) {
|
||||
pkginfo_t *p = (pkginfo_t*)i->data;
|
||||
pkginfo_t *dbpkg = NULL;
|
||||
for(j = p->files; j; j = j->next) {
|
||||
filestr = (char*)j->data;
|
||||
snprintf(path, PATH_MAX, "%s%s", pmo_root, filestr);
|
||||
if(!stat(path, &buf) && !S_ISDIR(buf.st_mode)) {
|
||||
int ok = 0;
|
||||
if(dbpkg == NULL) {
|
||||
dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES);
|
||||
}
|
||||
if(dbpkg && is_in(j->data, dbpkg->files)) {
|
||||
ok = 1;
|
||||
}
|
||||
if(!ok) {
|
||||
MALLOC(str, 512);
|
||||
snprintf(str, 512, "%s: exists in filesystem", path);
|
||||
conflicts = list_add(conflicts, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
freepkg(dbpkg);
|
||||
dbpkg = NULL;
|
||||
}
|
||||
|
||||
return(conflicts);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
46
src/db.h
Normal file
46
src/db.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 _PAC_DB_H
|
||||
#define _PAC_DB_H
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
/* info requests for db_read */
|
||||
#define INFRQ_DESC 0x01
|
||||
#define INFRQ_DEPENDS 0x02
|
||||
#define INFRQ_FILES 0x04
|
||||
#define INFRQ_ALL 0xFF
|
||||
|
||||
typedef struct __pacdb_t {
|
||||
char treename[128];
|
||||
DIR* dir;
|
||||
} pacdb_t;
|
||||
|
||||
pacdb_t* db_open(char *dbpath, char *treename);
|
||||
void db_close(pacdb_t *db);
|
||||
PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache);
|
||||
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
|
||||
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
|
||||
int db_write(pacdb_t *db, pkginfo_t *info);
|
||||
PMList* db_find_conflicts(pacdb_t *db, PMList* targets);
|
||||
|
||||
#endif
|
||||
/* vim: set ts=2 sw=2 noet: */
|
122
src/list.c
Normal file
122
src/list.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "list.h"
|
||||
|
||||
PMList* list_new()
|
||||
{
|
||||
PMList *list = NULL;
|
||||
|
||||
list = (PMList*)malloc(sizeof(PMList));
|
||||
if(list == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
list->data = NULL;
|
||||
list->prev = NULL;
|
||||
list->next = NULL;
|
||||
return(list);
|
||||
}
|
||||
|
||||
void list_free(PMList *list)
|
||||
{
|
||||
if(list == NULL) {
|
||||
return;
|
||||
}
|
||||
if(list->data != NULL) {
|
||||
free(list->data);
|
||||
list->data = NULL;
|
||||
}
|
||||
if(list->next != NULL) {
|
||||
list_free(list->next);
|
||||
}
|
||||
free(list);
|
||||
return;
|
||||
}
|
||||
|
||||
PMList* list_add(PMList *list, void *data)
|
||||
{
|
||||
PMList *ptr, *lp;
|
||||
|
||||
ptr = list;
|
||||
if(ptr == NULL) {
|
||||
ptr = list_new();
|
||||
}
|
||||
|
||||
lp = list_last(ptr);
|
||||
if(lp == ptr && lp->data == NULL) {
|
||||
/* nada */
|
||||
} else {
|
||||
lp->next = list_new();
|
||||
if(lp->next == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
lp->next->prev = lp;
|
||||
lp = lp->next;
|
||||
}
|
||||
lp->data = data;
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
int list_count(PMList *list)
|
||||
{
|
||||
int i;
|
||||
PMList *lp;
|
||||
|
||||
for(lp = list, i = 0; lp; lp = lp->next, i++);
|
||||
return(i);
|
||||
}
|
||||
|
||||
/* List one is extended and returned
|
||||
* List two is freed (but not its data)
|
||||
*/
|
||||
PMList* list_merge(PMList *one, PMList *two)
|
||||
{
|
||||
PMList *lp;
|
||||
|
||||
for(lp = two; lp; lp = lp->next) {
|
||||
if(lp->data) {
|
||||
list_add(one, lp->data);
|
||||
lp->data = NULL;
|
||||
}
|
||||
}
|
||||
list_free(two);
|
||||
|
||||
return(one);
|
||||
}
|
||||
|
||||
PMList* list_last(PMList *list)
|
||||
{
|
||||
PMList *ptr;
|
||||
|
||||
for(ptr = list; ptr && ptr->next; ptr = ptr->next);
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
20
src/list.h
Normal file
20
src/list.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef _PAC_LIST_H
|
||||
#define _PAC_LIST_H
|
||||
|
||||
/* your average linked list */
|
||||
typedef struct __pmlist_t {
|
||||
void* data;
|
||||
struct __pmlist_t* prev;
|
||||
struct __pmlist_t* next;
|
||||
} PMList;
|
||||
|
||||
PMList* list_new();
|
||||
void list_free(PMList* list);
|
||||
PMList* list_add(PMList* list, void* data);
|
||||
int list_count(PMList* list);
|
||||
PMList* list_merge(PMList *one, PMList *two);
|
||||
PMList* list_last(PMList* list);
|
||||
|
||||
#endif
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
338
src/md5.c
Normal file
338
src/md5.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/* Constants for MD5Transform routine.
|
||||
*/
|
||||
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
static void MD5Transform(UINT4 [4], unsigned char [64]);
|
||||
static void Encode(unsigned char *, UINT4 *, unsigned int);
|
||||
static void Decode(UINT4 *, unsigned char *, unsigned int);
|
||||
static void MD5_memcpy(POINTER, POINTER, unsigned int);
|
||||
static void MD5_memset(POINTER, int, unsigned int);
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||
*/
|
||||
void MD5Init (context)
|
||||
MD5_CTX *context; /* context */
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
*/
|
||||
void MD5Update (context, input, inputLen)
|
||||
MD5_CTX *context; /* context */
|
||||
unsigned char *input; /* input block */
|
||||
unsigned int inputLen; /* length of input block */
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||
|
||||
< ((UINT4)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((UINT4)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible.
|
||||
*/
|
||||
if (inputLen >= partLen) {
|
||||
MD5_memcpy
|
||||
((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||
MD5Transform (context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD5Transform (context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
MD5_memcpy
|
||||
((POINTER)&context->buffer[index], (POINTER)&input[i],
|
||||
inputLen-i);
|
||||
}
|
||||
|
||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
*/
|
||||
void MD5Final (digest, context)
|
||||
unsigned char digest[16]; /* message digest */
|
||||
MD5_CTX *context; /* context */
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode (bits, context->count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64.
|
||||
*/
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
MD5Update (context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD5Update (context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode (digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
MD5_memset ((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block.
|
||||
*/
|
||||
static void MD5Transform (state, block)
|
||||
UINT4 state[4];
|
||||
unsigned char block[64];
|
||||
{
|
||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
|
||||
*/
|
||||
MD5_memset ((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Encode (output, input, len)
|
||||
unsigned char *output;
|
||||
UINT4 *input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Decode (output, input, len)
|
||||
UINT4 *output;
|
||||
unsigned char *input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
/* Note: Replace "for loop" with standard memcpy if possible.
|
||||
*/
|
||||
|
||||
static void MD5_memcpy (output, input, len)
|
||||
POINTER output;
|
||||
POINTER input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
|
||||
output[i] = input[i];
|
||||
}
|
||||
|
||||
/* Note: Replace "for loop" with standard memset if possible.
|
||||
*/
|
||||
static void MD5_memset (output, value, len)
|
||||
POINTER output;
|
||||
int value;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
((char *)output)[i] = (char)value;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
48
src/md5.h
Normal file
48
src/md5.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* MD5.H - header file for MD5C.C
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
|
||||
/* POINTER defines a generic pointer type */
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
/* UINT2 defines a two byte word */
|
||||
typedef unsigned short int UINT2;
|
||||
|
||||
/* UINT4 defines a four byte word */
|
||||
typedef unsigned long int UINT4;
|
||||
|
||||
|
||||
/* MD5 context. */
|
||||
typedef struct {
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX *);
|
||||
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
|
||||
void MD5Final(unsigned char [16], MD5_CTX *);
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
83
src/md5driver.c
Normal file
83
src/md5driver.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* MD5DRIVER.C - taken and modified from MDDRIVER.C (license below) */
|
||||
/* for use in pacman. */
|
||||
/*********************************************************************/
|
||||
|
||||
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
|
||||
rights reserved.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
/* The following makes MD default to MD5 if it has not already been
|
||||
defined with C compiler flags.
|
||||
*/
|
||||
#define MD MD5
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
/* Length of test block, number of test blocks.
|
||||
*/
|
||||
#define TEST_BLOCK_LEN 1000
|
||||
#define TEST_BLOCK_COUNT 1000
|
||||
|
||||
char* MDFile(char *);
|
||||
void MDPrint(unsigned char [16]);
|
||||
|
||||
#define MD_CTX MD5_CTX
|
||||
#define MDInit MD5Init
|
||||
#define MDUpdate MD5Update
|
||||
#define MDFinal MD5Final
|
||||
|
||||
char* MDFile(char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
MD_CTX context;
|
||||
int len;
|
||||
unsigned char buffer[1024], digest[16];
|
||||
|
||||
if((file = fopen(filename, "rb")) == NULL) {
|
||||
printf ("%s can't be opened\n", filename);
|
||||
} else {
|
||||
char *ret;
|
||||
int i;
|
||||
|
||||
MDInit(&context);
|
||||
while((len = fread(buffer, 1, 1024, file))) {
|
||||
MDUpdate(&context, buffer, len);
|
||||
}
|
||||
MDFinal(digest, &context);
|
||||
fclose(file);
|
||||
/*printf("MD5 (%s) = ", filename);
|
||||
MDPrint(digest);
|
||||
printf("\n");*/
|
||||
|
||||
ret = (char*)malloc(33);
|
||||
ret[0] = '\0';
|
||||
for(i = 0; i < 16; i++) {
|
||||
sprintf(ret, "%s%02x", ret, digest[i]);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Prints a message digest in hexadecimal.
|
||||
*/
|
||||
void MDPrint(unsigned char digest[16])
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
printf ("%02x", digest[i]);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
228
src/package.c
Normal file
228
src/package.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "list.h"
|
||||
#include "package.h"
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
#include "pacman.h"
|
||||
|
||||
extern tartype_t gztype;
|
||||
|
||||
pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
|
||||
{
|
||||
char *expath;
|
||||
char *descfile;
|
||||
int i;
|
||||
TAR *tar;
|
||||
pkginfo_t *info = NULL;
|
||||
PMList *backup = NULL;
|
||||
PMList *lp;
|
||||
|
||||
info = newpkg();
|
||||
descfile = strdup("/tmp/pacman_XXXXXX");
|
||||
|
||||
if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
|
||||
perror("could not open package");
|
||||
return(NULL);
|
||||
}
|
||||
vprint("load_pkg: 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("load_pkg: found package description file.\n");
|
||||
mkstemp(descfile);
|
||||
tar_extract_file(tar, descfile);
|
||||
/* parse the info file */
|
||||
parse_descfile(descfile, info, &backup, output);
|
||||
if(!strlen(info->name)) {
|
||||
fprintf(stderr, "error: missing package name in description file.\n");
|
||||
return(NULL);
|
||||
}
|
||||
if(!strlen(info->version)) {
|
||||
fprintf(stderr, "error: missing package version in description file.\n");
|
||||
return(NULL);
|
||||
}
|
||||
for(lp = backup; lp; lp = lp->next) {
|
||||
if(lp->data) {
|
||||
info->backup = list_add(info->backup, lp->data);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(th_get_pathname(tar), "._install")) {
|
||||
info->scriptlet = 1;
|
||||
} else {
|
||||
expath = strdup(th_get_pathname(tar));
|
||||
/* add the path to the list */
|
||||
info->files = list_add(info->files, expath);
|
||||
}
|
||||
|
||||
if(TH_ISREG(tar) && tar_skip_regfile(tar)) {
|
||||
perror("bad package file");
|
||||
return(NULL);
|
||||
}
|
||||
expath = NULL;
|
||||
}
|
||||
tar_close(tar);
|
||||
FREE(descfile);
|
||||
|
||||
if(!strlen(info->name) || !strlen(info->version)) {
|
||||
fprintf(stderr, "Error: Missing .PKGINFO file in %s\n", pkgfile);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return(info);
|
||||
}
|
||||
|
||||
/* Parses the package description file for the current package
|
||||
*
|
||||
* Returns: 0 on success, 1 on error
|
||||
*
|
||||
*/
|
||||
int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
char line[PATH_MAX+1];
|
||||
char* ptr = NULL;
|
||||
char* key = NULL;
|
||||
int linenum = 0;
|
||||
PMList* bak = NULL;
|
||||
|
||||
if((fp = fopen(descfile, "r")) == NULL) {
|
||||
perror(descfile);
|
||||
return(1);
|
||||
}
|
||||
|
||||
while(!feof(fp)) {
|
||||
fgets(line, PATH_MAX, fp);
|
||||
if(output) {
|
||||
printf("%s", line);
|
||||
}
|
||||
linenum++;
|
||||
trim(line);
|
||||
if(line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
if(strlen(line) == 0) {
|
||||
continue;
|
||||
}
|
||||
ptr = line;
|
||||
key = strsep(&ptr, "=");
|
||||
if(key == NULL || ptr == NULL) {
|
||||
fprintf(stderr, "Syntax error in description file line %d\n", linenum);
|
||||
} else {
|
||||
trim(key);
|
||||
key = strtoupper(key);
|
||||
trim(ptr);
|
||||
if(!strcmp(key, "PKGNAME")) {
|
||||
strncpy(info->name, ptr, sizeof(info->name));
|
||||
} else if(!strcmp(key, "PKGVER")) {
|
||||
strncpy(info->version, ptr, sizeof(info->version));
|
||||
} else if(!strcmp(key, "PKGDESC")) {
|
||||
strncpy(info->desc, ptr, sizeof(info->desc));
|
||||
} else if(!strcmp(key, "BUILDDATE")) {
|
||||
strncpy(info->builddate, ptr, sizeof(info->builddate));
|
||||
} else if(!strcmp(key, "INSTALLDATE")) {
|
||||
strncpy(info->installdate, ptr, sizeof(info->installdate));
|
||||
} else if(!strcmp(key, "PACKAGER")) {
|
||||
strncpy(info->packager, ptr, sizeof(info->packager));
|
||||
} else if(!strcmp(key, "SIZE")) {
|
||||
char tmp[32];
|
||||
strncpy(tmp, ptr, sizeof(tmp));
|
||||
info->size = atol(tmp);
|
||||
} else if(!strcmp(key, "DEPEND")) {
|
||||
char *s = strdup(ptr);
|
||||
info->depends = list_add(info->depends, s);
|
||||
} else if(!strcmp(key, "CONFLICT")) {
|
||||
char *s = strdup(ptr);
|
||||
info->conflicts = list_add(info->conflicts, s);
|
||||
} else if(!strcmp(key, "BACKUP")) {
|
||||
char *s = strdup(ptr);
|
||||
bak = list_add(bak, s);
|
||||
} else {
|
||||
fprintf(stderr, "Syntax error in description file line %d\n", linenum);
|
||||
}
|
||||
}
|
||||
line[0] = '\0';
|
||||
}
|
||||
fclose(fp);
|
||||
unlink(descfile);
|
||||
|
||||
*backup = bak;
|
||||
return(0);
|
||||
}
|
||||
|
||||
pkginfo_t* newpkg()
|
||||
{
|
||||
pkginfo_t* pkg = NULL;
|
||||
MALLOC(pkg, sizeof(pkginfo_t));
|
||||
|
||||
pkg->name[0] = '\0';
|
||||
pkg->version[0] = '\0';
|
||||
pkg->desc[0] = '\0';
|
||||
pkg->builddate[0] = '\0';
|
||||
pkg->installdate[0] = '\0';
|
||||
pkg->packager[0] = '\0';
|
||||
pkg->size = 0;
|
||||
pkg->scriptlet = 0;
|
||||
pkg->requiredby = NULL;
|
||||
pkg->conflicts = NULL;
|
||||
pkg->files = NULL;
|
||||
pkg->backup = NULL;
|
||||
pkg->depends = NULL;
|
||||
|
||||
return(pkg);
|
||||
}
|
||||
|
||||
void freepkg(pkginfo_t *pkg)
|
||||
{
|
||||
if(pkg == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_free(pkg->files);
|
||||
list_free(pkg->backup);
|
||||
list_free(pkg->depends);
|
||||
list_free(pkg->conflicts);
|
||||
list_free(pkg->requiredby);
|
||||
FREE(pkg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Helper function for sorting packages
|
||||
*/
|
||||
int pkgcmp(const void *p1, const void *p2)
|
||||
{
|
||||
pkginfo_t **pkg1 = (pkginfo_t**)p1;
|
||||
pkginfo_t **pkg2 = (pkginfo_t**)p2;
|
||||
|
||||
return(strcmp(pkg1[0]->name, pkg2[0]->name));
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
67
src/package.h
Normal file
67
src/package.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 _PAC_PACKAGE_H
|
||||
#define _PAC_PACKAGE_H
|
||||
|
||||
/* mods for depend_t.mod */
|
||||
#define DEP_ANY 0
|
||||
#define DEP_EQ 1
|
||||
#define DEP_GE 2
|
||||
#define DEP_LE 3
|
||||
|
||||
/* Package Structures */
|
||||
typedef char** fileset_t;
|
||||
typedef struct __pkginfo_t {
|
||||
char name[256];
|
||||
char version[64];
|
||||
char desc[512];
|
||||
char builddate[32];
|
||||
char installdate[32];
|
||||
char packager[64];
|
||||
unsigned long size;
|
||||
unsigned short scriptlet;
|
||||
PMList *files;
|
||||
PMList *backup;
|
||||
PMList *depends;
|
||||
PMList *requiredby;
|
||||
PMList *conflicts;
|
||||
} pkginfo_t;
|
||||
|
||||
typedef struct __depend_t {
|
||||
unsigned short mod;
|
||||
char name[256];
|
||||
char version[64];
|
||||
} depend_t;
|
||||
|
||||
typedef struct __depmissing_t {
|
||||
enum {DEPEND, REQUIRED, CONFLICT} type;
|
||||
char target[256];
|
||||
depend_t depend;
|
||||
} depmissing_t;
|
||||
|
||||
pkginfo_t* load_pkg(char *pkgfile, unsigned short output);
|
||||
int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output);
|
||||
pkginfo_t* newpkg();
|
||||
void freepkg(pkginfo_t *pkg);
|
||||
int pkgcmp(const void *p1, const void *p2);
|
||||
|
||||
#endif
|
||||
/* vim: set ts=2 sw=2 noet: */
|
1660
src/pacman.c
Normal file
1660
src/pacman.c
Normal file
File diff suppressed because it is too large
Load diff
62
src/pacman.h
Normal file
62
src/pacman.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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 _PAC_PACMAN_H
|
||||
#define _PAC_PACMAN_H
|
||||
|
||||
#ifndef PACVER
|
||||
#define PACVER "2.0"
|
||||
#endif
|
||||
|
||||
#ifndef PKGDIR
|
||||
#define PKGDIR "var/lib/pacman"
|
||||
#endif
|
||||
|
||||
#ifndef PACCONF
|
||||
#define PACCONF "etc/pacman.conf"
|
||||
#endif
|
||||
|
||||
/* Operations */
|
||||
#define PM_MAIN 1
|
||||
#define PM_ADD 2
|
||||
#define PM_REMOVE 3
|
||||
#define PM_QUERY 4
|
||||
#define PM_UPGRADE 5
|
||||
#define PM_SYNC 6
|
||||
#define PM_DEPTEST 7
|
||||
|
||||
int pacman_add(pacdb_t *db, PMList *targets);
|
||||
int pacman_remove(pacdb_t *db, PMList *targets);
|
||||
int pacman_upgrade(pacdb_t *db, PMList *targets);
|
||||
int pacman_query(pacdb_t *db, PMList *targets);
|
||||
int pacman_sync(pacdb_t *db, PMList *targets);
|
||||
int pacman_deptest(pacdb_t *db, PMList *targets);
|
||||
|
||||
PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets);
|
||||
int resolvedeps(pacdb_t *local, pacdb_t *sync, pkginfo_t *package, PMList *list, PMList *trail);
|
||||
int splitdep(char *depstr, depend_t *depend);
|
||||
|
||||
int lckmk(char *file, int retries, unsigned int sleep_secs);
|
||||
int lckrm(char *lckfile);
|
||||
void cleanup(int signum);
|
||||
|
||||
#endif /* PACMAN_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
183
src/pacsync.c
Normal file
183
src/pacsync.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <ftplib.h>
|
||||
/* pacman */
|
||||
#include "list.h"
|
||||
#include "package.h"
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
#include "pacsync.h"
|
||||
#include "pacman.h"
|
||||
|
||||
static int log_progress(netbuf *ctl, int xfered, void *arg);
|
||||
static char sync_fnm[25];
|
||||
|
||||
/* pacman options */
|
||||
extern char *pmo_root;
|
||||
/* configuration options */
|
||||
extern char pmc_syncserver[512];
|
||||
extern char pmc_syncpath[512];
|
||||
extern char pmc_syncname[512];
|
||||
|
||||
int sync_synctree()
|
||||
{
|
||||
char ldir[PATH_MAX] = "";
|
||||
char path[PATH_MAX];
|
||||
mode_t oldmask;
|
||||
char *str;
|
||||
PMList *files = NULL;
|
||||
|
||||
snprintf(ldir, PATH_MAX, "%s%s/%s", pmo_root, PKGDIR, pmc_syncname);
|
||||
|
||||
/* remove the old dir */
|
||||
vprint("Removing %s (if it exists)\n", ldir);
|
||||
rmrf(ldir);
|
||||
|
||||
/* make the new dir */
|
||||
oldmask = umask(0000);
|
||||
mkdir(ldir, 0755);
|
||||
umask(oldmask);
|
||||
|
||||
/* build out list of one */
|
||||
snprintf(path, PATH_MAX, "%s.db.tar.gz", pmc_syncname);
|
||||
str = strdup(path);
|
||||
files = list_add(files, str);
|
||||
if(downloadfiles(pmc_syncserver, pmc_syncpath, ldir, files)) {
|
||||
list_free(files);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* uncompress the sync database */
|
||||
snprintf(path, PATH_MAX, "%s/%s", ldir, (char*)files->data);
|
||||
list_free(files);
|
||||
vprint("Unpacking %s...\n", path);
|
||||
if(unpack(path, ldir)) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* remove the .tar.gz */
|
||||
unlink(path);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int downloadfiles(char *server, char *remotepath, char *localpath, PMList *files)
|
||||
{
|
||||
int fsz;
|
||||
netbuf *control = NULL;
|
||||
PMList *lp;
|
||||
int ret = 0;
|
||||
|
||||
if(files == NULL) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
FtpInit();
|
||||
if(!FtpConnect(server, &control)) {
|
||||
fprintf(stderr, "error: cannot connect to %s\n", server);
|
||||
return(1);
|
||||
}
|
||||
if(!FtpLogin("anonymous", "arch@guest", control)) {
|
||||
fprintf(stderr, "error: anonymous login failed\n");
|
||||
FtpQuit(control);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
if(!FtpChdir(remotepath, control)) {
|
||||
fprintf(stderr, "error: could not cwd to %s: %s\n", remotepath,
|
||||
FtpLastResponse(control));
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* get each file in the list */
|
||||
for(lp = files; lp; lp = lp->next) {
|
||||
char output[PATH_MAX];
|
||||
int j;
|
||||
|
||||
snprintf(output, PATH_MAX, "%s/%s", localpath, (char*)lp->data);
|
||||
|
||||
/* passive mode */
|
||||
/* TODO: make passive ftp an option */
|
||||
if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
|
||||
fprintf(stderr, "warning: failed to set passive mode\n");
|
||||
}
|
||||
|
||||
if(!FtpSize((char*)lp->data, &fsz, FTPLIB_IMAGE, control)) {
|
||||
fprintf(stderr, "warning: failed to get filesize for %s\n", (char*)lp->data);
|
||||
}
|
||||
|
||||
/* set up our progress bar's callback */
|
||||
FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
|
||||
FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
|
||||
FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
|
||||
FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
|
||||
|
||||
strncpy(sync_fnm, lp->data, 24);
|
||||
for(j = strlen(sync_fnm); j < 24; j++) {
|
||||
sync_fnm[j] = ' ';
|
||||
}
|
||||
sync_fnm[24] = '\0';
|
||||
if(!FtpGet(output, lp->data, FTPLIB_IMAGE, control)) {
|
||||
fprintf(stderr, "\nerror: could not download %s: %s\n", (char*)lp->data,
|
||||
FtpLastResponse(control));
|
||||
/* unlink the file */
|
||||
unlink(output);
|
||||
ret = 1;
|
||||
} else {
|
||||
log_progress(control, fsz, &fsz);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
FtpQuit(control);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int log_progress(netbuf *ctl, int xfered, void *arg)
|
||||
{
|
||||
int fsz = *(int*)arg;
|
||||
int pct = (unsigned int)(xfered * 100) / fsz;
|
||||
int i;
|
||||
|
||||
printf("%s [", sync_fnm);
|
||||
for(i = 0; i < (int)(pct/3); i++) {
|
||||
printf("#");
|
||||
}
|
||||
for(i = (int)(pct/3); i < (int)(100/3); i++) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("] %3d%% | %6dK\r", pct, (xfered/1024));
|
||||
fflush(stdout);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
29
src/pacsync.h
Normal file
29
src/pacsync.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 _PAC_PACSYNC_H
|
||||
#define _PAC_PACSYNC_H
|
||||
|
||||
int sync_synctree();
|
||||
int downloadfiles(char *server, char *remotepath, char *localpath, PMList *files);
|
||||
|
||||
#endif
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
120
src/rpmvercmp.c
Normal file
120
src/rpmvercmp.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* this function was taken from rpm 4.0.4 and rewritten */
|
||||
|
||||
int rpmvercmp(const char *a, const char *b)
|
||||
{
|
||||
char *str1, *str2;
|
||||
char *one, *two;
|
||||
char *rel1 = NULL, *rel2 = NULL;
|
||||
char oldch1, oldch2;
|
||||
int is1num, is2num;
|
||||
int rc;
|
||||
|
||||
if(!strcmp(a,b)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
str1 = strdup(a);
|
||||
str2 = strdup(b);
|
||||
|
||||
/* lose the release number */
|
||||
for(one = str1; *one && *one != '-'; one++);
|
||||
if(one) {
|
||||
*one = '\0';
|
||||
rel1 = ++one;
|
||||
}
|
||||
for(two = str2; *two && *two != '-'; two++);
|
||||
if(two) {
|
||||
*two = '\0';
|
||||
rel2 = ++two;
|
||||
}
|
||||
|
||||
one = str1;
|
||||
two = str2;
|
||||
|
||||
while(*one || *two) {
|
||||
while(*one && !isalnum(*one)) one++;
|
||||
while(*two && !isalnum(*two)) two++;
|
||||
|
||||
str1 = one;
|
||||
str2 = two;
|
||||
|
||||
/* find the next segment for each string */
|
||||
if(isdigit(*str1)) {
|
||||
is1num = 1;
|
||||
while(*str1 && isdigit(*str1)) str1++;
|
||||
} else {
|
||||
is1num = 0;
|
||||
while(*str1 && isalpha(*str1)) str1++;
|
||||
}
|
||||
if(isdigit(*str2)) {
|
||||
is2num = 1;
|
||||
while(*str2 && isdigit(*str2)) str2++;
|
||||
} else {
|
||||
is2num = 0;
|
||||
while(*str2 && isalpha(*str2)) str2++;
|
||||
}
|
||||
|
||||
oldch1 = *str1;
|
||||
*str1 = '\0';
|
||||
oldch2 = *str2;
|
||||
*str2 = '\0';
|
||||
|
||||
/* see if we ran out of segments on one string */
|
||||
if(one == str1 && two != str2) {
|
||||
return(is2num ? -1 : 1);
|
||||
}
|
||||
if(one != str1 && two == str2) {
|
||||
return(is1num ? 1 : -1);
|
||||
}
|
||||
|
||||
/* see if we have a type mismatch (ie, one is alpha and one is digits) */
|
||||
if(is1num && !is2num) return(1);
|
||||
if(!is1num && is2num) return(-1);
|
||||
|
||||
if(is1num) while(*one == '0') one++;
|
||||
if(is2num) while(*two == '0') two++;
|
||||
|
||||
rc = strverscmp(one, two);
|
||||
if(rc) return(rc);
|
||||
|
||||
*str1 = oldch1;
|
||||
*str2 = oldch2;
|
||||
one = str1;
|
||||
two = str2;
|
||||
}
|
||||
|
||||
if((!*one) && (!*two)) {
|
||||
/* compare release numbers */
|
||||
if(rel1 && rel2) return(rpmvercmp(rel1, rel2));
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(*one ? 1 : -1);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
571
src/util.c
Normal file
571
src/util.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <getopt.h>
|
||||
#include <ctype.h>
|
||||
#include "list.h"
|
||||
#include "package.h"
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
#include "pacman.h"
|
||||
|
||||
extern char* pmo_root;
|
||||
extern unsigned short pmo_op;
|
||||
extern unsigned short pmo_version;
|
||||
extern unsigned short pmo_verbose;
|
||||
extern unsigned short pmo_help;
|
||||
extern unsigned short pmo_force;
|
||||
extern unsigned short pmo_nodeps;
|
||||
extern unsigned short pmo_upgrade;
|
||||
extern unsigned short pmo_nosave;
|
||||
extern unsigned short pmo_vertest;
|
||||
extern unsigned short pmo_q_isfile;
|
||||
extern unsigned short pmo_q_info;
|
||||
extern unsigned short pmo_q_list;
|
||||
extern unsigned short pmo_q_owns;
|
||||
extern unsigned short pmo_s_sync;
|
||||
extern unsigned short pmo_s_search;
|
||||
extern unsigned short pmo_s_clean;
|
||||
extern unsigned short pmo_s_upgrade;
|
||||
|
||||
extern char pmc_syncserver[512];
|
||||
extern char pmc_syncname[512];
|
||||
extern char pmc_syncpath[512];
|
||||
|
||||
extern PMList *pm_targets;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
tartype_t gztype = {
|
||||
(openfunc_t) gzopen_frontend,
|
||||
(closefunc_t)gzclose,
|
||||
(readfunc_t) gzread,
|
||||
(writefunc_t)gzwrite
|
||||
};
|
||||
|
||||
int unpack(char *archive, char *prefix)
|
||||
{
|
||||
TAR *tar = NULL;
|
||||
char expath[PATH_MAX];
|
||||
|
||||
/* open the .tar.gz package */
|
||||
if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
|
||||
perror(archive);
|
||||
return(1);
|
||||
}
|
||||
while(!th_read(tar)) {
|
||||
snprintf(expath, PATH_MAX, "%s/%s", prefix, th_get_pathname(tar));
|
||||
if(tar_extract_file(tar, expath)) {
|
||||
fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), strerror(errno));
|
||||
}
|
||||
}
|
||||
tar_close(tar);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Parse command-line arguments for each operation
|
||||
* op: the operation code requested
|
||||
* argc: argc
|
||||
* argv: argv
|
||||
*
|
||||
* Returns: 0 on success, 1 on error
|
||||
*/
|
||||
int parseargs(int op, int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
static struct option opts[] =
|
||||
{
|
||||
{"add", no_argument, 0, 'A'},
|
||||
{"remove", no_argument, 0, 'R'},
|
||||
{"upgrade", no_argument, 0, 'U'},
|
||||
{"query", no_argument, 0, 'Q'},
|
||||
{"sync", no_argument, 0, 'S'},
|
||||
{"deptest", no_argument, 0, 'T'},
|
||||
{"vertest", no_argument, 0, 'Y'},
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"search", no_argument, 0, 's'},
|
||||
{"clean", no_argument, 0, 'c'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"nodeps", no_argument, 0, 'd'},
|
||||
{"nosave", no_argument, 0, 'n'},
|
||||
{"owns", no_argument, 0, 'o'},
|
||||
{"list", no_argument, 0, 'l'},
|
||||
{"file", no_argument, 0, 'p'},
|
||||
{"info", no_argument, 0, 'i'},
|
||||
{"sysupgrade", no_argument, 0, 'u'},
|
||||
{"refresh", no_argument, 0, 'y'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while((opt = getopt_long(argc, argv, "ARUQSTYr:vhscVfnoldpiuy", opts, &option_index))) {
|
||||
if(opt < 0) {
|
||||
break;
|
||||
}
|
||||
switch(opt) {
|
||||
case 0: break;
|
||||
case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break;
|
||||
case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break;
|
||||
case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break;
|
||||
case 'Q': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_QUERY); break;
|
||||
case 'S': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_SYNC); break;
|
||||
case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break;
|
||||
case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_vertest = 1; break;
|
||||
case 'h': pmo_help = 1; break;
|
||||
case 'V': pmo_version = 1; break;
|
||||
case 'v': pmo_verbose = 1; break;
|
||||
case 'f': pmo_force = 1; break;
|
||||
case 'd': pmo_nodeps = 1; break;
|
||||
case 'n': pmo_nosave = 1; break;
|
||||
case 'l': pmo_q_list = 1; break;
|
||||
case 'p': pmo_q_isfile = 1; break;
|
||||
case 'i': pmo_q_info = 1; break;
|
||||
case 'o': pmo_q_owns = 1; break;
|
||||
case 'u': pmo_s_upgrade = 1; break;
|
||||
case 'y': pmo_s_sync = 1; break;
|
||||
case 's': pmo_s_search = 1; break;
|
||||
case 'c': pmo_s_clean = 1; break;
|
||||
case 'r': if(realpath(optarg, pmo_root) == NULL) {
|
||||
perror("bad root path");
|
||||
return(1);
|
||||
} break;
|
||||
case '?': return(1);
|
||||
default: return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(pmo_op == 0) {
|
||||
fprintf(stderr, "error: only one operation may be used at a time\n\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if(pmo_help) {
|
||||
usage(pmo_op, (char*)basename(argv[0]));
|
||||
return(2);
|
||||
}
|
||||
if(pmo_version) {
|
||||
version();
|
||||
return(2);
|
||||
}
|
||||
|
||||
while(optind < argc) {
|
||||
/* add the target to our target array */
|
||||
char *s = strdup(argv[optind]);
|
||||
pm_targets = list_add(pm_targets, s);
|
||||
optind++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int parseconfig(char *configfile)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char line[PATH_MAX+1];
|
||||
char *ptr = NULL;
|
||||
char *key = NULL;
|
||||
int linenum = 0;
|
||||
|
||||
if((fp = fopen(configfile, "r")) == NULL) {
|
||||
perror(configfile);
|
||||
return(1);
|
||||
}
|
||||
|
||||
while(fgets(line, PATH_MAX, fp)) {
|
||||
linenum++;
|
||||
trim(line);
|
||||
if(strlen(line) == 0) {
|
||||
continue;
|
||||
}
|
||||
if(line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
ptr = line;
|
||||
key = strsep(&ptr, "=");
|
||||
if(key == NULL || ptr == NULL) {
|
||||
fprintf(stderr, "syntax error in config file (line %d)\n", linenum);
|
||||
} else {
|
||||
trim(key);
|
||||
key = strtoupper(key);
|
||||
trim(ptr);
|
||||
if(!strcmp(key, "SYNC_SERVER")) {
|
||||
strncpy(pmc_syncserver, ptr, sizeof(pmc_syncserver)-1);
|
||||
} else if(!strcmp(key, "SYNC_TREE_PATH")) {
|
||||
strncpy(pmc_syncpath, ptr, sizeof(pmc_syncpath)-1);
|
||||
} else if(!strcmp(key, "SYNC_TREE_NAME")) {
|
||||
strncpy(pmc_syncname, ptr, sizeof(pmc_syncname)-1);
|
||||
} else {
|
||||
fprintf(stderr, "Syntax error in description file line %d\n", linenum);
|
||||
}
|
||||
}
|
||||
line[0] = '\0';
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int copyfile(char *src, char *dest)
|
||||
{
|
||||
FILE *in, *out;
|
||||
size_t len;
|
||||
char buf[1025];
|
||||
|
||||
in = fopen(src, "r");
|
||||
if(in == NULL) {
|
||||
return(1);
|
||||
}
|
||||
out = fopen(dest, "w");
|
||||
if(out == NULL) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
while((len = fread(buf, 1, 1024, in))) {
|
||||
fwrite(buf, 1, len, out);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int makepath(char *path)
|
||||
{
|
||||
char *orig, *str, *ptr;
|
||||
char full[PATH_MAX] = "";
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask = umask(0000);
|
||||
|
||||
orig = strdup(path);
|
||||
str = orig;
|
||||
while((ptr = strsep(&str, "/"))) {
|
||||
if(strlen(ptr)) {
|
||||
struct stat buf;
|
||||
|
||||
strcat(full, "/");
|
||||
strcat(full, ptr);
|
||||
if(stat(full, &buf)) {
|
||||
if(mkdir(full, 0755)) {
|
||||
free(orig);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(orig);
|
||||
umask(oldmask);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int rmrf(char *path)
|
||||
{
|
||||
int errflag = 0;
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
char name[PATH_MAX];
|
||||
extern int errno;
|
||||
|
||||
if(!unlink(path)) {
|
||||
return(0);
|
||||
} else {
|
||||
if (errno == ENOENT) {
|
||||
return(0);
|
||||
} else if (errno == EPERM) {
|
||||
/* fallthrough */
|
||||
} else if (errno == EISDIR) {
|
||||
/* fallthrough */
|
||||
} else if (errno == ENOTDIR) {
|
||||
return(1);
|
||||
} else {
|
||||
/* not a directory */
|
||||
return(1);
|
||||
}
|
||||
|
||||
if((dirp = opendir(path)) == (DIR *)-1) {
|
||||
return(1);
|
||||
}
|
||||
for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
|
||||
if (dp->d_ino) {
|
||||
sprintf(name, "%s/%s", path, dp->d_name);
|
||||
if(strcmp(dp->d_name, "..") && strcmp(dp->d_name, ".")) {
|
||||
errflag += rmrf(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
if(rmdir(path)) {
|
||||
errflag++;
|
||||
}
|
||||
return(errflag);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
printf(" %s {-S --sync} [options] [package]\n", myname);
|
||||
printf("\nuse '%s --help' with other options for more syntax\n\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(" -d, --nodeps skip dependency checks\n");
|
||||
} else if(op == PM_REMOVE) {
|
||||
printf("usage: %s {-R --remove} [options] <package>\n", myname);
|
||||
printf("options:\n");
|
||||
printf(" -d, --nodeps skip dependency checks\n");
|
||||
printf(" -n, --nosave remove configuration files as well\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(" -d, --nodeps skip dependency checks\n");
|
||||
} else if(op == PM_QUERY) {
|
||||
printf("usage: %s {-Q --query} [options] [package]\n", myname);
|
||||
printf("options:\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 view package information\n");
|
||||
printf(" -p, --file pacman will query the package file [package] instead of\n");
|
||||
printf(" looking in the database\n");
|
||||
} else if(op == PM_SYNC) {
|
||||
printf("usage: %s {-S --sync} [options] [package]\n", myname);
|
||||
printf("options:\n");
|
||||
printf(" -s, --search search sync database for matching strings\n");
|
||||
printf(" -f, --force force install, overwrite conflicting files\n");
|
||||
printf(" -d, --nodeps skip dependency checks\n");
|
||||
printf(" -y, --refresh download a fresh package sync database from the server\n");
|
||||
printf(" -u, --sysupgrade upgrade all packages that are out of date\n");
|
||||
printf(" -c, --clean remove packages from cache directory to free up diskspace\n");
|
||||
}
|
||||
printf(" -v, --verbose be verbose\n");
|
||||
printf(" -r, --root <path> set an alternate installation root\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Version
|
||||
*/
|
||||
void version(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf(" .--. Pacman v%s\n", PACVER);
|
||||
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);
|
||||
}
|
||||
|
||||
int yesno(char *fmt, ...)
|
||||
{
|
||||
char response[32];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
if(fgets(response, 32, stdin)) {
|
||||
trim(response);
|
||||
if(!strcasecmp(response, "Y") || !strcasecmp(response, "YES") || !strlen(response)) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Test for existence of a string in a PMList
|
||||
*/
|
||||
int is_in(char *needle, PMList *haystack)
|
||||
{
|
||||
PMList *lp;
|
||||
|
||||
for(lp = haystack; lp; lp = lp->next) {
|
||||
if(lp->data && !strcmp(lp->data, needle)) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Look for a filename in a pkginfo_t.backup list. If we find it,
|
||||
* then we return the md5 hash (parsed from the same line)
|
||||
*/
|
||||
char* needbackup(char* file, PMList *backup)
|
||||
{
|
||||
PMList *lp;
|
||||
|
||||
/* run through the backup list and parse out the md5 hash for our file */
|
||||
for(lp = backup; lp; lp = lp->next) {
|
||||
char* str = strdup(lp->data);
|
||||
char* ptr;
|
||||
|
||||
/* tab delimiter */
|
||||
ptr = index(str, '\t');
|
||||
if(ptr == NULL) {
|
||||
FREE(str);
|
||||
continue;
|
||||
}
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
/* now str points to the filename and ptr points to the md5 hash */
|
||||
if(!strcmp(file, str)) {
|
||||
char *md5 = strdup(ptr);
|
||||
FREE(str);
|
||||
return(md5);
|
||||
}
|
||||
FREE(str);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Test for existence of a package in a PMList*
|
||||
* of pkginfo_t*
|
||||
*
|
||||
* returns: 0 for no match
|
||||
* 1 for identical match
|
||||
* -1 for name-only match (version mismatch)
|
||||
*/
|
||||
int is_pkgin(pkginfo_t *needle, PMList *haystack)
|
||||
{
|
||||
PMList *lp;
|
||||
pkginfo_t *info;
|
||||
|
||||
for(lp = haystack; lp; lp = lp->next) {
|
||||
info = (pkginfo_t*)lp->data;
|
||||
if(info && !strcmp(info->name, needle->name)) {
|
||||
if(!strcmp(info->version, needle->version)) {
|
||||
return(1);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
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 *pch = str;
|
||||
while(isspace(*pch)) {
|
||||
pch++;
|
||||
}
|
||||
if(pch != str) {
|
||||
memmove(str, pch, (strlen(pch) + 1));
|
||||
}
|
||||
|
||||
pch = (char*)(str + (strlen(str) - 1));
|
||||
while(isspace(*pch)) {
|
||||
pch--;
|
||||
}
|
||||
*++pch = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
52
src/util.h
Normal file
52
src/util.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 _PAC_UTIL_H
|
||||
#define _PAC_UTIL_H
|
||||
|
||||
#include <libtar.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#define MALLOC(p, b) { if((b) > 0) { \
|
||||
p = malloc(b); if (!(p)) { \
|
||||
fprintf(stderr, "malloc failure: could not allocate %d byets\n", b); \
|
||||
exit(1); }} else p = NULL; }
|
||||
|
||||
#define FREE(p) { if (p) { free(p); (p)= NULL; }}
|
||||
|
||||
int unpack(char *archive, char *prefix);
|
||||
int parseargs(int op, int argc, char **argv);
|
||||
int parseconfig(char *configfile);
|
||||
int copyfile(char *src, char *dest);
|
||||
int makepath(char *path);
|
||||
int rmrf(char *path);
|
||||
int vprint(char *fmt, ...);
|
||||
int yesno(char* fmt, ...);
|
||||
void usage(int op, char *myname);
|
||||
void version(void);
|
||||
char* needbackup(char *file, PMList *backup);
|
||||
int is_in(char *needle, PMList *haystack);
|
||||
int is_pkgin(pkginfo_t *needle, PMList *haystack);
|
||||
char* trim(char *str);
|
||||
char* strtoupper(char *str);
|
||||
|
||||
|
||||
#endif
|
||||
/* vim: set ts=2 sw=2 noet: */
|
Loading…
Add table
Reference in a new issue