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
|
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.23 - Added install/upgrade/remove scripting control
|
||||||
1.22 - Some manpage typo fixes
|
1.22 - Some manpage typo fixes
|
||||||
- Added --root switch to pacsync
|
- 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
|
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
|
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
|
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
|
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
|
Although the package manager itself is quite simple, the pacman tarball
|
||||||
also comes with scripts that help automate building and installing
|
also comes with scripts that help automate building and installing
|
||||||
packages. These are used extensively in the Arch Build System (ABS),
|
packages. These are used extensively in the Arch Build System (ABS),
|
||||||
used in Arch Linux <http://www.archlinux.org>. See ABS.txt for more
|
used in Arch Linux <http://www.archlinux.org>.
|
||||||
information.
|
|
||||||
|
|
||||||
As of version 1.2, pacsync is included as well. This performs an
|
As of version 2.0, pacman can also keep your system's packages in
|
||||||
apt-like function, keeping your system's packages in sync with the
|
sync with a master server. You can follow CURRENT and STABLE trees,
|
||||||
packages on a remote server.
|
or lock yourself into a specific version. See the pacman manpage
|
||||||
|
for more info on this (--sync operation).
|
||||||
Plans exist for dependency checking as I approach version 2.0.
|
|
||||||
See TODO for more info.
|
|
||||||
|
|
||||||
|
|
||||||
INSTALL:
|
INSTALL:
|
||||||
|
@ -44,7 +43,7 @@ BUGS:
|
||||||
-----
|
-----
|
||||||
If you find bugs (which is quite likely), please submit them to
|
If you find bugs (which is quite likely), please submit them to
|
||||||
<jvinet@zeroflux.org> with specific information, such as your
|
<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.
|
it helps.
|
||||||
|
|
||||||
|
|
||||||
|
|
31
TODO
31
TODO
|
@ -1,11 +1,22 @@
|
||||||
- add a [sibling] option to .PKGINFO -- used when only one of
|
- check $PACCONF env var
|
||||||
the siblings can be installed at a time (eg, bsdinit,sysvinit)
|
- ftp transfer progress bar breaks after ~42000 K
|
||||||
- sort packages by package name in pacman.db
|
- use a 'trust pacman' config option for downgrading?
|
||||||
? manage conditional file installs (ie, 'info' pages)
|
- use a provides tag (instead of an OR operator in depends)
|
||||||
- maybe add a 'confirm every action' option for doing paranoid installs
|
- instead of 'conflicts' use a ! operator in depends
|
||||||
- add a consistency check operation
|
- add a --pretend option
|
||||||
- add file locking to db
|
- add a consistency/sanity check operation
|
||||||
- add a --dbpath option
|
- add a --dbpath option
|
||||||
+ dependency checking
|
- build-time (source) dependencies in makepkg
|
||||||
- upgrade currently does a double db backup; not really desirable
|
- 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
|
.SH NAME
|
||||||
makepkg \- package build utility
|
makepkg \- package build utility
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -8,9 +8,10 @@ makepkg \- package build utility
|
||||||
a build-capable linux platform, wget, and some build scripts. The advantage
|
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
|
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
|
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,
|
will do the rest: download source files, check dependencies,
|
||||||
build the package, install the package into a temporary root, make
|
configure the buildtime settings, build the package, install the package
|
||||||
customizations, and package the whole thing up for pacman to use.
|
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
|
\fBmakeworld\fP can be used to rebuild an entire package group, or the
|
||||||
entire build tree.
|
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
|
than building this package). The build script should be called PKGBUILD
|
||||||
and it should bear resemblance to the example below.
|
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
|
||||||
.TP
|
.TP
|
||||||
.SH PKGBUILD Example:
|
.SH PKGBUILD Example:
|
||||||
|
@ -27,7 +33,9 @@ and it should bear resemblance to the example below.
|
||||||
pkgname=modutils
|
pkgname=modutils
|
||||||
pkgver=2.4.13
|
pkgver=2.4.13
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
|
pkgdesc="Utilities for inserting and removing modules from the linux kernel"
|
||||||
backup=(etc/modules.conf)
|
backup=(etc/modules.conf)
|
||||||
|
depends=('glibc>=2.2.5' 'bash' 'zlib')
|
||||||
source=(ftp://ftp.server.com/$pkgname-$pkgver.tar.gz modules.conf)
|
source=(ftp://ftp.server.com/$pkgname-$pkgver.tar.gz modules.conf)
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
@ -43,11 +51,26 @@ build() {
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
As you can see, the setup is fairly simple. The first three lines define
|
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,
|
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
|
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.
|
The line with \fIbackup=\fP specifies files that should be treated specially
|
||||||
Then the \fIbuild\fP function is called. This is where all package configuration,
|
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
|
building, and installing should be done. Any customization will likely take
|
||||||
place here.
|
place here.
|
||||||
|
|
||||||
|
@ -65,13 +88,14 @@ make prefix=$startdir/pkg/usr install
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.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
|
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
|
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
|
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
|
then strip debugging info from libraries and binaries and generate a meta-info
|
||||||
into a .pkg.tar.gz file in the directory you ran \fBmakepkg\fP from.
|
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
|
At this point you should have a package file in the current directory, named
|
||||||
something like name-version-release.pkg.tar.gz. Done!
|
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.
|
script is run right before files are removed.
|
||||||
|
|
||||||
.RE
|
.RE
|
||||||
In order to use this feature, your build function should put the script in
|
To use this feature, just create a file (eg, pkgname.install) and put it in
|
||||||
$startdir/pkg/var/lib/pacman/scripts and it must be named exactly the same
|
the same directory as the PKGBUILD script. Then use the \fIinstall\fP directive:
|
||||||
as the \fI$pkgname\fP variable in the PKGBUILD script. For example, an
|
.RS
|
||||||
install script for grep will be $startdir/pkg/var/lib/pacman/scripts/grep.
|
.nf
|
||||||
Note that the scripts should be 644, not 755 (we don't need execute permission).
|
install=pkgname.install
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
|
||||||
|
The install script does not need to be specified in the \fIsource\fP array.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.TP
|
.TP
|
||||||
|
@ -111,6 +139,7 @@ post_install() {
|
||||||
#
|
#
|
||||||
# do post-install stuff here
|
# do post-install stuff here
|
||||||
#
|
#
|
||||||
|
/bin/true
|
||||||
}
|
}
|
||||||
|
|
||||||
# arg 1: the new package version
|
# arg 1: the new package version
|
||||||
|
@ -119,6 +148,7 @@ post_upgrade() {
|
||||||
#
|
#
|
||||||
# do post-upgrade stuff here
|
# do post-upgrade stuff here
|
||||||
#
|
#
|
||||||
|
/bin/true
|
||||||
}
|
}
|
||||||
|
|
||||||
# arg 1: the old package version
|
# arg 1: the old package version
|
||||||
|
@ -126,6 +156,7 @@ pre_remove() {
|
||||||
#
|
#
|
||||||
# do pre-remove stuff here
|
# do pre-remove stuff here
|
||||||
#
|
#
|
||||||
|
/bin/true
|
||||||
}
|
}
|
||||||
|
|
||||||
op=$1
|
op=$1
|
||||||
|
@ -151,12 +182,39 @@ This is the version of the software as released from the author (eg, 2.7.1).
|
||||||
.B pkgrel
|
.B pkgrel
|
||||||
This is the release number specific to Arch Linux packages.
|
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
|
.TP
|
||||||
.B backup
|
.B backup
|
||||||
A space-delimited array of filenames (without a preceding slash). The
|
A space-delimited array of filenames (without a preceding slash). The
|
||||||
\fIbackup\fP line will be propagated to the package meta-info file for
|
\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
|
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
|
.TP
|
||||||
.B source
|
.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
|
does not already exist in /var/cache/pacman/src, the file is downloaded
|
||||||
by wget.
|
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
|
.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
|
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
|
to use. This is helpful for building for different architectures, or with
|
||||||
different optimizations.
|
different optimizations.
|
||||||
|
|
||||||
\fBNOTE:\fP This does not guarantee that all package Makefiles will use
|
\fBNOTE:\fP This does not guarantee that all package Makefiles will use
|
||||||
your exported variables. Some of them are flaky...
|
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
|
.SH AUTHOR
|
||||||
.nf
|
.nf
|
||||||
Judd Vinet <jvinet@zeroflux.org>
|
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 CFLAGS="-O2 -march=i686 -pipe"
|
||||||
export CXXFLAGS="-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
|
#!/bin/bash
|
||||||
|
|
||||||
toplevel=`pwd`
|
toplevel=`pwd`
|
||||||
version="1.23"
|
version="2.0"
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
if [ $# -lt 2 -o "$1" = "--help" -o "$1" = "-h" ]; then
|
||||||
echo "makepkg version $version"
|
echo "makeworld version $version"
|
||||||
echo "usage: $0 <destdir> <category> [category] ..."
|
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 " where <category> is one or more of base, opt, contrib"
|
||||||
echo " eg: makeworld /packages base opt"
|
echo " eg: makeworld /packages base opt"
|
||||||
echo
|
echo
|
||||||
|
@ -13,6 +18,16 @@ if [ $# -lt 2 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
dest=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
|
@ -25,7 +40,7 @@ for category in $*; do
|
||||||
. PKGBUILD
|
. PKGBUILD
|
||||||
buildstatus=0
|
buildstatus=0
|
||||||
if [ ! -f $dest/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then
|
if [ ! -f $dest/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then
|
||||||
makepkg
|
makepkg $MAKEPKG_OPTS 2>>$toplevel/makepkg.log
|
||||||
if [ $? -gt 0 ]; then
|
if [ $? -gt 0 ]; then
|
||||||
buildstatus=2
|
buildstatus=2
|
||||||
else
|
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