Imported from pacman-1.2.tar.gz
This commit is contained in:
parent
8cf35f551f
commit
931506031b
12 changed files with 692 additions and 128 deletions
|
@ -1,5 +1,10 @@
|
|||
VERSION DESCRIPTION
|
||||
------------------------------------------------------------------
|
||||
-
|
||||
1.1 - Fixed some string-handling bugs
|
||||
- Added better handling of configuration files and the like.
|
||||
If "file" is about to be removed, but it is designated to
|
||||
be backed up, then it will be copied to "file.save"
|
||||
- Changed db_find_conflicts() to ignore directories
|
||||
1.0 - Initial Release
|
||||
|
||||
|
|
9
Makefile
9
Makefile
|
@ -27,7 +27,7 @@ BINDIR = /usr/bin
|
|||
MANDIR = /usr/man
|
||||
ETCDIR = /etc
|
||||
|
||||
VERSION = 1.1
|
||||
VERSION = 1.2
|
||||
LIBTAR_VERSION = 1.2.4
|
||||
|
||||
CXX = gcc
|
||||
|
@ -45,7 +45,7 @@ pacman: $(OBJECTS)
|
|||
pacman.o: pacman.c pacman.h
|
||||
$(CXX) $(CXXFLAGS) -c pacman.c
|
||||
|
||||
man: pacman.8
|
||||
man: pacman.8 pacsync.8 makepkg.8
|
||||
|
||||
%: %.in
|
||||
sed -e "s/#VERSION#/$(VERSION)/" $< > $@
|
||||
|
@ -62,11 +62,14 @@ libtar:
|
|||
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 "*** to /etc now."
|
||||
@echo "*** and pacsync.conf to /etc now."
|
||||
@echo ""
|
||||
|
||||
clean:
|
||||
|
|
18
README
18
README
|
@ -13,7 +13,17 @@ DESCRIPTION:
|
|||
upgrade packages in the system, and it will allow you to query the
|
||||
package database for installed packages, files and owners.
|
||||
|
||||
Plans exist for dependency checking and remote file fetching, as well.
|
||||
Although the package manager itself is quite simple, the pacman tarball
|
||||
also comes with scripts that help automate building and installing
|
||||
packages. These are used extensively in the Arch Build System (ABS),
|
||||
used in Arch Linux <http://www.archlinux.org>. See ABS.txt for more
|
||||
information.
|
||||
|
||||
As of version 1.2, pacsync is included as well. This performs an apt-like
|
||||
function, keeping your system's packages in sync with the packages on
|
||||
a remote server.
|
||||
|
||||
Plans exist for dependency checking as I approach version 2.0.
|
||||
See TODO for more info.
|
||||
|
||||
|
||||
|
@ -32,15 +42,15 @@ Note: Since pacman is compiled statically, you will need the static libraries
|
|||
|
||||
BUGS:
|
||||
-----
|
||||
If you find bugs (which is quite likely at version 1.0), please submit
|
||||
them to <jvinet@zeroflux.org> with specific information, such as your
|
||||
If you find bugs (which is quite likely), please submit them to
|
||||
<jvinet@zeroflux.org> with specific information, such as your
|
||||
commandline, the nature of the bug, and even the package database, if
|
||||
it helps.
|
||||
|
||||
|
||||
COPYRIGHT:
|
||||
----------
|
||||
pacman is Copyright (c) 2002 Judd vinet <jvinet@zeroflux.org> and is
|
||||
pacman is Copyright (c) 2002 Judd Vinet <jvinet@zeroflux.org> and is
|
||||
licensed through the GNU General Public License (see COPYING).
|
||||
|
||||
pacman uses "libtar", a library for reading/writing tar-files. This
|
||||
|
|
14
makepkg
14
makepkg
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
me=`basename $0`
|
||||
myver='1.1'
|
||||
myver='1.2'
|
||||
startdir=`pwd`
|
||||
|
||||
[ -f /etc/makepkg.conf ] && . /etc/makepkg.conf
|
||||
|
@ -30,9 +30,9 @@ for netfile in ${source[@]}; do
|
|||
if [ -f ../$file ]; then
|
||||
echo "==> Found $file in build dir" >&2
|
||||
cp ../$file .
|
||||
elif [ -f /var/cache/pkg/$file ]; then
|
||||
elif [ -f /var/cache/pacman/src/$file ]; then
|
||||
echo "==> Using local copy of $file" >&2
|
||||
cp /var/cache/pkg/$file .
|
||||
cp /var/cache/pacman/src/$file .
|
||||
else
|
||||
echo "==> Downloading $file" >&2
|
||||
wget --passive-ftp --no-directories --tries=3 --waitretry=3 $netfile 2>&1
|
||||
|
@ -41,7 +41,7 @@ for netfile in ${source[@]}; do
|
|||
echo "==> Aborting..." >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p /var/cache/pkg && cp $file /var/cache/pkg
|
||||
mkdir -p /var/cache/pacman/src && cp $file /var/cache/pacman/src
|
||||
fi
|
||||
case $file in
|
||||
*.tar.gz|*.tar.Z|*.tgz)
|
||||
|
@ -76,6 +76,12 @@ echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
|
|||
for bakfile in "${backup[@]}"; do
|
||||
echo "backup = $bakfile" >>.PKGINFO
|
||||
done
|
||||
if [ "$install" != "" ]; then
|
||||
cat $startdir/$install | egrep '^[^$]' | sed 's/^/install = /g' >>.PKGINFO
|
||||
fi
|
||||
if [ "$remove" != "" ]; then
|
||||
cat $startdir/$remove | egrep '^[^$]' | sed 's/^/remove = /g' >>.PKGINFO
|
||||
fi
|
||||
|
||||
# remove info/doc files
|
||||
cd $startdir
|
||||
|
|
110
makepkg.8.in
Executable file
110
makepkg.8.in
Executable file
|
@ -0,0 +1,110 @@
|
|||
.TH makepkg 8 "Mar 17, 2002" "makepkg #VERSION#" ""
|
||||
.SH NAME
|
||||
makepkg \- package build utility
|
||||
.SH SYNOPSIS
|
||||
\fBmakepkg\fP
|
||||
.SH DESCRIPTION
|
||||
\fBmakepkg\fP will build packages for you. All it needs is
|
||||
a build-capable linux platform, wget, and some build scripts. The advantage
|
||||
to a script-based build is that you only really do the work once. Once you
|
||||
have the build script for a package, you just need to run makepkg and it
|
||||
will do the rest: download source files, configure the buildtime settings,
|
||||
build the package, install the package into a temporary root, make
|
||||
customizations, and package the whole thing up for pacman to use.
|
||||
|
||||
\fBmakeworld\fP can be used to rebuild an entire package group, or the
|
||||
entire build tree.
|
||||
.SH BUILD PROCESS (or How To Build Your Own Packages)
|
||||
Start in an isolated directory (ie, it's not used for anything other
|
||||
than building this package). The build script should be called PKGBUILD
|
||||
and it should bear resemblance to the example below.
|
||||
|
||||
.TP
|
||||
.TP
|
||||
.SH PKGBUILD Example:
|
||||
.RS
|
||||
.nf
|
||||
pkgname=modutils
|
||||
pkgver=2.4.13
|
||||
pkgrel=1
|
||||
backup=(etc/modules.conf)
|
||||
source=(ftp://ftp.server.com/$pkgname-$pkgver.tar.gz modules.conf)
|
||||
|
||||
build() {
|
||||
cd $startdir/src/$pkgname-$pkgver
|
||||
./configure --prefix=/usr
|
||||
make || return 1
|
||||
make prefix=$startdir/pkg/usr install
|
||||
# copy our custom modules.conf into the package root
|
||||
mkdir -p $startdir/pkg/etc
|
||||
cp ../modules.conf $startdir/pkg/etc
|
||||
}
|
||||
.fi
|
||||
.RE
|
||||
|
||||
As you can see, the setup is fairly simple. The first three lines define
|
||||
the package name and version info. They also define the final package name,
|
||||
which will be of the form $pkgname-$pkgver-$pkgrel.pkg.tar.gz
|
||||
|
||||
The sources are then decompressed (if necessary) into a directory called ./src.
|
||||
Then the \fIbuild\fP function is called. This is where all package configuration,
|
||||
building, and installing should be done. Any customization will likely take
|
||||
place here.
|
||||
|
||||
After a package is built, the \fIbuild\fP function must install the package
|
||||
files into a special package root, which can be referenced by \fB$startdir/pkg\fP
|
||||
in the \fIbuild\fP function. The typical way to do this is one of the following:
|
||||
.RS
|
||||
.nf
|
||||
|
||||
make DESTDIR=$startdir/pkg install
|
||||
|
||||
or
|
||||
|
||||
make prefix=$startdir/pkg/usr install
|
||||
|
||||
.fi
|
||||
.RE
|
||||
Notice that the "/usr" portion should be present with "prefix", but not "DESTDIR."
|
||||
|
||||
Once the package is successfully installed into the package root, \fImakepkg\fP
|
||||
will remove some directories (as per Arch Linux package guidelines; if you use
|
||||
this elsewhere, feel free to change it) like /usr/doc and /usr/info. It will
|
||||
then strip debugging info from libraries and binaries and compress
|
||||
|
||||
.SH PKGBUILD Directives
|
||||
.TP
|
||||
.B backup
|
||||
A space-delimited array of filenames (without a preceiding slash). The
|
||||
\fIbackup\fP line will be propagated to the package meta-info file for
|
||||
pacman. This will designate all files listed there to be backed up if this
|
||||
package is ever removed from a system.
|
||||
|
||||
.TP
|
||||
.B source
|
||||
The \fIsource\fP line is an array of source files required to build the
|
||||
package. Source files must reside in the same directory as the PKGBUILD
|
||||
file, unless they have a fully-qualified URL. Then if the source file
|
||||
does not already exist in /var/cache/pacman/src, the file is downloaded
|
||||
by wget.
|
||||
|
||||
.TP
|
||||
.B install
|
||||
There is also an \fIinstall\fP directive that is not used in the example
|
||||
above. If \fIinstall\fP is set to the name of a file in the package build
|
||||
directory (but \fBnot\fP listed in the source line), then it will be
|
||||
copied to the package meta-info file and designated as a post-install script.
|
||||
This will be run by pacman whenever it installs the package.
|
||||
|
||||
.SH CONFIGURATION
|
||||
Configuration options are stored in /etc/makepkg.conf. This file is parsed
|
||||
as a bash script, so you can export any special compiler flags you wish
|
||||
to use. This is helpful for building for different architectures, or with
|
||||
different optimizations.
|
||||
|
||||
\fBNOTE:\fP This does not guarantee that all package Makefiles will use
|
||||
your exported variables. Some of them are flaky...
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Judd Vinet <jvinet@zeroflux.org>
|
||||
.fi
|
|
@ -1,11 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
toplevel=`pwd`
|
||||
version="1.2"
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "makepkg version $version"
|
||||
echo "usage: $0 <destdir> <category> [category] ..."
|
||||
echo " where <category> is base, opt, etc."
|
||||
echo " eg: makeworld /packages base opt extra"
|
||||
echo
|
||||
echo " this should be run from the toplevel directory of ABS (usually /usr/abs)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.TH pacman 8 "Feb 10, 2002" "pacman #VERSION#" ""
|
||||
.TH pacman 8 "Mar 17, 2002" "pacman #VERSION#" ""
|
||||
.SH NAME
|
||||
pacman \- package manager utility
|
||||
.SH SYNOPSIS
|
||||
\fBpacman <operation> [options] <package>\fP
|
||||
\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
|
||||
|
|
304
pacman.c
304
pacman.c
|
@ -95,15 +95,21 @@ unsigned short pmo_q_info = 0;
|
|||
unsigned short pmo_q_list = 0;
|
||||
char* pmo_q_owns = NULL;
|
||||
|
||||
pkginfo_t** packages = NULL;
|
||||
unsigned int pkgcount = 0;
|
||||
/* list of installed packages */
|
||||
pkginfo_t** pm_packages = NULL;
|
||||
unsigned int pm_pkgcount = 0;
|
||||
|
||||
/* list of targets specified on command line */
|
||||
fileset_t pm_targets = NULL;
|
||||
unsigned int pm_targct = 0;
|
||||
|
||||
/* path to post-install script, if any */
|
||||
char* pm_install = NULL;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
pm_opfunc_t op_func;
|
||||
char* funcvar = NULL;
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
|
||||
/* default root */
|
||||
pmo_root = (char*)malloc(2);
|
||||
|
@ -118,16 +124,16 @@ int main(int argc, char* argv[])
|
|||
/* the handler function */
|
||||
if(!strcmp(argv[1], "-A") || !strcmp(argv[1], "--add")) {
|
||||
op_func = pacman_add;
|
||||
funcvar = parseargs(PM_ADD, argc, argv);
|
||||
ret = parseargs(PM_ADD, argc, argv);
|
||||
} else if(!strcmp(argv[1], "-R") || !strcmp(argv[1], "--remove")) {
|
||||
op_func = pacman_remove;
|
||||
funcvar = parseargs(PM_REMOVE, argc, argv);
|
||||
ret = parseargs(PM_REMOVE, argc, argv);
|
||||
} else if(!strcmp(argv[1], "-Q") || !strcmp(argv[1], "--query")) {
|
||||
op_func = pacman_query;
|
||||
funcvar = parseargs(PM_QUERY, argc, argv);
|
||||
ret = parseargs(PM_QUERY, argc, argv);
|
||||
} else if(!strcmp(argv[1], "-U") || !strcmp(argv[1], "--upgrade")) {
|
||||
op_func = pacman_upgrade;
|
||||
funcvar = parseargs(PM_UPGRADE, argc, argv);
|
||||
ret = parseargs(PM_UPGRADE, argc, argv);
|
||||
} else if(!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
|
||||
usage(PM_MAIN, (char*)basename(argv[0]));
|
||||
return(1);
|
||||
|
@ -135,16 +141,21 @@ int main(int argc, char* argv[])
|
|||
version();
|
||||
return(1);
|
||||
} else {
|
||||
printf("error: invalid operation\n\n");
|
||||
fprintf(stderr, "error: invalid operation\n\n");
|
||||
usage(PM_MAIN, (char*)basename(argv[0]));
|
||||
return(1);
|
||||
}
|
||||
|
||||
if(funcvar == NULL && op_func != pacman_query) {
|
||||
if(ret || (pm_targct < 1 && op_func != pacman_query)) {
|
||||
return(1);
|
||||
}
|
||||
vprint("Installation Root: %s\n", pmo_root);
|
||||
vprint("Package Name: %s\n", funcvar);
|
||||
if(pm_targct) {
|
||||
vprint("Targets:\n");
|
||||
for(i = 0; i < pm_targct; i++) {
|
||||
vprint(" %s\n", pm_targets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* check for db existence */
|
||||
if(pmo_root != NULL) {
|
||||
|
@ -161,27 +172,40 @@ int main(int argc, char* argv[])
|
|||
|
||||
ret = db_open(dbpath);
|
||||
if(ret == 1) {
|
||||
printf("error: Could not open package database file!\n");
|
||||
printf(" Check to see that %s exists.\n", dbpath);
|
||||
printf(" If not, you may simply create it by \"touch\"-ing it.\n");
|
||||
fprintf(stderr, "error: Could not open package database file!\n");
|
||||
fprintf(stderr, " Check to see that %s exists.\n", dbpath);
|
||||
fprintf(stderr, " If not, you may simply create it by \"touch\"-ing it.\n");
|
||||
return(1);
|
||||
}
|
||||
if(ret == 2) {
|
||||
printf("error: Database is corrupt! You may need to use the backup database.\n");
|
||||
printf(" I hope you like tweaking... ;-)\n");
|
||||
fprintf(stderr, "error: Database is corrupt! You may need to use the backup database.\n");
|
||||
fprintf(stderr, " I hope you like tweaking... ;-)\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* start the requested operation */
|
||||
if(!pmo_nofunc) {
|
||||
ret = op_func(funcvar);
|
||||
if(ret) {
|
||||
printf("There were errors\n");
|
||||
for(i = 0; i < pm_targct; i++) {
|
||||
if(op_func(pm_targets[i])) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
if(op_func == pacman_query && pm_targct == 0) {
|
||||
ret = op_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if(op_func == pacman_remove) {
|
||||
/* the remove function no longer updates the db itself. we do it here
|
||||
* instead, in an effort to save some expensive file rewrites. note that we
|
||||
* can't do this for pacman_add() yet, as he's gotta call db_find_conflicts
|
||||
* for each package.
|
||||
*/
|
||||
ret = db_update(NULL, 0);
|
||||
}
|
||||
|
||||
fclose(dbfp);
|
||||
return(0);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int pacman_add(char* pkgfile)
|
||||
|
@ -206,13 +230,13 @@ int pacman_add(char* pkgfile)
|
|||
vprint("Looking for DB conflicts...\n");
|
||||
if((i = db_find_conflicts(files, filecount)) == 1) {
|
||||
if(pmo_force) {
|
||||
printf("\nInstalling package anyway...\n");
|
||||
printf(" You might have duplicate entries in your package\n");
|
||||
printf(" database now. You may want to edit it and remove\n");
|
||||
printf(" one of the copies.\n\n");
|
||||
fprintf(stderr, "\nInstalling package anyway...\n");
|
||||
fprintf(stderr, " You might have duplicate entries in your package\n");
|
||||
fprintf(stderr, " database now. You may want to edit it and remove\n");
|
||||
fprintf(stderr, " one of the copies.\n\n");
|
||||
} else {
|
||||
printf("Aborting...\n");
|
||||
printf(" (use -f to override)\n\n");
|
||||
fprintf(stderr, "Aborting...\n");
|
||||
fprintf(stderr, " (use -f to override)\n\n");
|
||||
return(1);
|
||||
}
|
||||
} else if(i == 2) {
|
||||
|
@ -225,7 +249,11 @@ int pacman_add(char* pkgfile)
|
|||
if(pmo_upgrade) {
|
||||
vprint("Removing old package first...\n");
|
||||
if(pacman_remove(pkgname)) {
|
||||
printf("\nUpgrade aborted.\n");
|
||||
fprintf(stderr, "\nUpgrade aborted.\n");
|
||||
return(1);
|
||||
}
|
||||
if(db_update(NULL, 0)) {
|
||||
fprintf(stderr, "\nError updating database. Upgrade aborted.\n");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
@ -257,11 +285,11 @@ int pacman_add(char* pkgfile)
|
|||
strcpy(newpath, expath);
|
||||
strcat(newpath, ".save");
|
||||
rename(expath, newpath);
|
||||
printf("%s renamed to %s\n", expath, newpath);
|
||||
fprintf(stderr, "%s renamed to %s\n", expath, newpath);
|
||||
}
|
||||
if(tar_extract_file(tar, expath)) {
|
||||
errmsg = strerror(errno);
|
||||
printf("could not extract %s: %s\n", th_get_pathname(tar), errmsg);
|
||||
fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), errmsg);
|
||||
errors = 1;
|
||||
}
|
||||
free(expath);
|
||||
|
@ -269,16 +297,29 @@ int pacman_add(char* pkgfile)
|
|||
tar_close(tar);
|
||||
vprint("Done.\n");
|
||||
if(errors) {
|
||||
printf("There were errors. No database update was performed.\n");
|
||||
fprintf(stderr, "There were errors. No database update was performed.\n");
|
||||
return(1);
|
||||
} else {
|
||||
vprint("Updating database...\n");
|
||||
if(db_update(files, filecount)) {
|
||||
printf("error: Could not update database! The database may not\n");
|
||||
printf(" be in a sane state!\n");
|
||||
fprintf(stderr, "error: Could not update database! The database may not\n");
|
||||
fprintf(stderr, " be in a sane state!\n");
|
||||
return(1);
|
||||
}
|
||||
vprint("Done.\n");
|
||||
}
|
||||
|
||||
/* run the script in pm_install */
|
||||
if(pm_install != NULL) {
|
||||
vprint("Executing post-install script...\n");
|
||||
expath = (char*)malloc(256);
|
||||
snprintf(expath, 255, "/bin/bash %s", pm_install);
|
||||
system(expath);
|
||||
free(expath);
|
||||
unlink(pm_install);
|
||||
free(pm_install);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -286,7 +327,7 @@ int pacman_remove(char* pkgfile)
|
|||
{
|
||||
int found = 0, done = 0;
|
||||
int i;
|
||||
char line[255];
|
||||
char line[PATH_MAX+1];
|
||||
fileset_t files = NULL;
|
||||
unsigned int filecount = 0, nb = 0;
|
||||
struct stat buf;
|
||||
|
@ -304,17 +345,17 @@ int pacman_remove(char* pkgfile)
|
|||
strcpy(line, trim(line));
|
||||
if(!strcmp(line, pkgfile)) {
|
||||
/* read the version */
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, 63, dbfp);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
printf("Cannot remove %s: Package was not found.\n", pkgfile);
|
||||
fprintf(stderr, "Cannot remove %s: Package was not found.\n", pkgfile);
|
||||
return(1);
|
||||
}
|
||||
|
||||
while(!done) {
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, PATH_MAX, dbfp);
|
||||
strcpy(line, trim(line));
|
||||
if(strlen(line)) {
|
||||
/* add the path to the list */
|
||||
|
@ -347,13 +388,13 @@ int pacman_remove(char* pkgfile)
|
|||
/* perror("cannot remove directory"); */
|
||||
}
|
||||
} else {
|
||||
/* if the file ends in .conf, back it up */
|
||||
/* if the file is flagged, back it up to .save */
|
||||
if(!pmo_nosave && nb) {
|
||||
newpath = (char*)realloc(newpath, strlen(file)+6);
|
||||
strcpy(newpath, file);
|
||||
strcat(newpath, ".save");
|
||||
rename(file, newpath);
|
||||
printf("%s renamed to %s\n", file, newpath);
|
||||
fprintf(stderr, "%s renamed to %s\n", file, newpath);
|
||||
} else {
|
||||
vprint(" unlinking %s\n", file);
|
||||
if(unlink(file)) {
|
||||
|
@ -365,31 +406,31 @@ int pacman_remove(char* pkgfile)
|
|||
|
||||
/* now splice this name out of the packages list */
|
||||
found = 0;
|
||||
for(i = 0; i < pkgcount-1; i++) {
|
||||
for(i = 0; i < pm_pkgcount-1; i++) {
|
||||
if(found) {
|
||||
packages[i] = packages[i+1];
|
||||
pm_packages[i] = pm_packages[i+1];
|
||||
} else {
|
||||
if(!strcmp(packages[i]->name, pkgfile)) {
|
||||
if(!strcmp(pm_packages[i]->name, pkgfile)) {
|
||||
found = 1;
|
||||
if(i < pkgcount-1) {
|
||||
packages[i] = packages[i+1];
|
||||
if(i < pm_pkgcount-1) {
|
||||
pm_packages[i] = pm_packages[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* drop the last item */
|
||||
packages = (pkginfo_t**)realloc(packages, (--pkgcount)*sizeof(pkginfo_t*));
|
||||
pm_packages = (pkginfo_t**)realloc(pm_packages, (--pm_pkgcount)*sizeof(pkginfo_t*));
|
||||
|
||||
/* and commit the db */
|
||||
return(db_update(NULL, 0));
|
||||
/* the db will be commited back up in main() */
|
||||
return(0);
|
||||
}
|
||||
|
||||
int pacman_query(char* pkgfile)
|
||||
{
|
||||
char *str = NULL;
|
||||
char name[255];
|
||||
char ver[255];
|
||||
char line[255];
|
||||
char name[256];
|
||||
char ver[64];
|
||||
char line[PATH_MAX+1];
|
||||
int found = 0;
|
||||
int done = 0;
|
||||
int i;
|
||||
|
@ -422,22 +463,25 @@ int pacman_query(char* pkgfile)
|
|||
while(!found && !feof(dbfp)) {
|
||||
fgets(name, 255, dbfp);
|
||||
strcpy(name, trim(name));
|
||||
fgets(ver, 255, dbfp);
|
||||
fgets(ver, 63, dbfp);
|
||||
strcpy(ver, trim(ver));
|
||||
strcpy(line, " ");
|
||||
while(strlen(line) && !feof(dbfp)) {
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, PATH_MAX, dbfp);
|
||||
strcpy(line, trim(line));
|
||||
str = line;
|
||||
if(line[0] == '*') {
|
||||
str++;
|
||||
}
|
||||
str += strlen(pmo_root);
|
||||
if(!strcmp(line, pmo_q_owns)) {
|
||||
if(!strcmp(str, pmo_q_owns)) {
|
||||
printf("%s %s\n", name, ver);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("No package owns this file.\n");
|
||||
return(0);
|
||||
fprintf(stderr, "No package owns this file.\n");
|
||||
return(2);
|
||||
}
|
||||
|
||||
/* find packages in the db */
|
||||
|
@ -449,7 +493,7 @@ int pacman_query(char* pkgfile)
|
|||
strcpy(name, trim(name));
|
||||
if(pkgfile == NULL || (pkgfile != NULL && !strcmp(name, pkgfile))) {
|
||||
/* read the version */
|
||||
fgets(ver, 255, dbfp);
|
||||
fgets(ver, 63, dbfp);
|
||||
strcpy(ver, trim(ver));
|
||||
found = 1;
|
||||
if(pkgfile != NULL) {
|
||||
|
@ -459,13 +503,14 @@ int pacman_query(char* pkgfile)
|
|||
}
|
||||
if(feof(dbfp)) {
|
||||
if(pkgfile != NULL && !found) {
|
||||
printf("Package was not found in database.\n");
|
||||
fprintf(stderr, "Package \"%s\" was not found in database.\n", pkgfile);
|
||||
return(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
found = 0;
|
||||
while(!found) {
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, PATH_MAX, dbfp);
|
||||
strcpy(line, trim(line));
|
||||
if(strlen(line)) {
|
||||
if(pmo_q_list) {
|
||||
|
@ -495,8 +540,7 @@ int pacman_upgrade(char* pkgfile)
|
|||
/* this is basically just a remove,add process. pacman_add() will */
|
||||
/* handle it */
|
||||
pmo_upgrade = 1;
|
||||
pacman_add(pkgfile);
|
||||
return(0);
|
||||
return pacman_add(pkgfile);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -559,10 +603,10 @@ int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output)
|
|||
}
|
||||
tar_close(tar);
|
||||
|
||||
free(descfile);
|
||||
|
||||
if(pkgname == NULL || pkgver == NULL) {
|
||||
printf("The current version of Pacman requires a .PKGINFO file\n");
|
||||
printf("present in the .tar.gz archive. This package does not\n");
|
||||
printf("have one.\n");
|
||||
fprintf(stderr, "Error: Missing .PKGINFO file in %s\n", pkgfile);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -575,26 +619,38 @@ int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output)
|
|||
*/
|
||||
int db_open(char* path)
|
||||
{
|
||||
char line[255];
|
||||
char line[PATH_MAX+1];
|
||||
int i;
|
||||
pkginfo_t* info;
|
||||
|
||||
/* if pm_packages already contains data, free it first */
|
||||
if(pm_pkgcount) {
|
||||
for(i = 0; i < pm_pkgcount; i++) {
|
||||
free(pm_packages[i]);
|
||||
}
|
||||
free(pm_packages);
|
||||
pm_packages = NULL;
|
||||
pm_pkgcount = 0;
|
||||
}
|
||||
|
||||
dbfp = fopen(path, "r");
|
||||
if(dbfp == NULL) {
|
||||
return(1);
|
||||
}
|
||||
while(!feof(dbfp)) {
|
||||
info = (pkginfo_t*)malloc(sizeof(pkginfo_t));
|
||||
fgets(line, 64, dbfp);
|
||||
fgets(line, sizeof(info->name)-1, dbfp);
|
||||
if(feof(dbfp)) {
|
||||
break;
|
||||
}
|
||||
strcpy(info->name, trim(line));
|
||||
fgets(line, 32, dbfp);
|
||||
fgets(line, sizeof(info->version)-1, dbfp);
|
||||
strcpy(info->version, trim(line));
|
||||
/* add to the collective */
|
||||
packages = (pkginfo_t**)realloc(packages, (++pkgcount) * sizeof(pkginfo_t*));
|
||||
packages[pkgcount-1] = info;
|
||||
pm_packages = (pkginfo_t**)realloc(pm_packages, (++pm_pkgcount) * sizeof(pkginfo_t*));
|
||||
pm_packages[pm_pkgcount-1] = info;
|
||||
for(;;) {
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, PATH_MAX, dbfp);
|
||||
if(feof(dbfp)) {
|
||||
return(2);
|
||||
}
|
||||
|
@ -617,12 +673,12 @@ int db_open(char* path)
|
|||
*/
|
||||
int db_update(fileset_t files, unsigned int filecount)
|
||||
{
|
||||
FILE* olddb;
|
||||
FILE* olddb = NULL;
|
||||
char* newpath = NULL;
|
||||
char* str = NULL;
|
||||
char name[64];
|
||||
char ver[32];
|
||||
char line[255];
|
||||
char name[256];
|
||||
char ver[64];
|
||||
char line[PATH_MAX+1];
|
||||
int i = 0, found = 0, done = 0;
|
||||
|
||||
/* build the backup pathname */
|
||||
|
@ -643,21 +699,21 @@ int db_update(fileset_t files, unsigned int filecount)
|
|||
|
||||
rewind(olddb);
|
||||
while(!feof(olddb)) {
|
||||
if(!fgets(name, 64, olddb)) {
|
||||
if(!fgets(name, 255, olddb)) {
|
||||
break;
|
||||
}
|
||||
strcpy(name, trim(name));
|
||||
fgets(ver, 32, olddb);
|
||||
fgets(ver, 63, olddb);
|
||||
found = 0;
|
||||
for(i = 0; i < pkgcount && !found; i++) {
|
||||
if(!strcmp(packages[i]->name, name)) {
|
||||
for(i = 0; i < pm_pkgcount && !found; i++) {
|
||||
if(!strcmp(pm_packages[i]->name, name)) {
|
||||
/* it's there... copy the entries over */
|
||||
found = 1;
|
||||
fputs(name, dbfp);
|
||||
fputc('\n', dbfp);
|
||||
fputs(ver, dbfp);
|
||||
for(done = 0; !done;) {
|
||||
fgets(line, 255, olddb);
|
||||
fgets(line, PATH_MAX, olddb);
|
||||
if(found) {
|
||||
fputs(line, dbfp);
|
||||
}
|
||||
|
@ -670,7 +726,7 @@ int db_update(fileset_t files, unsigned int filecount)
|
|||
if(!found) {
|
||||
/* skip through filelist for this package */
|
||||
for(done = 0; !done;) {
|
||||
fgets(line, 255, olddb);
|
||||
fgets(line, PATH_MAX, olddb);
|
||||
if(strlen(trim(line)) == 0 || feof(olddb)) {
|
||||
done = 1;
|
||||
}
|
||||
|
@ -713,8 +769,8 @@ int db_update(fileset_t files, unsigned int filecount)
|
|||
int db_find_conflicts(fileset_t files, unsigned int filecount)
|
||||
{
|
||||
int i;
|
||||
char line[255];
|
||||
char name[255];
|
||||
char line[PATH_MAX+1];
|
||||
char name[256];
|
||||
char* dbstr = NULL;
|
||||
char* filestr = NULL;
|
||||
struct stat buf;
|
||||
|
@ -726,13 +782,13 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
|
|||
fgets(name, 255, dbfp);
|
||||
strcpy(name, trim(name));
|
||||
if(!pmo_upgrade && !strcmp(name, pkgname)) {
|
||||
printf("error: This package is already installed.\n");
|
||||
printf(" Maybe you should be using --upgrade.\n");
|
||||
fprintf(stderr, "error: This package is already installed.\n");
|
||||
fprintf(stderr, " Maybe you should be using --upgrade.\n");
|
||||
return(2);
|
||||
}
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, 64, dbfp);
|
||||
while(!feof(dbfp)) {
|
||||
fgets(line, 255, dbfp);
|
||||
fgets(line, PATH_MAX, dbfp);
|
||||
strcpy(line, trim(line));
|
||||
dbstr = line;
|
||||
if(dbstr[0] == '*') {
|
||||
|
@ -742,6 +798,7 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
|
|||
break;
|
||||
}
|
||||
if(index(dbstr, '/') == dbstr && (!pmo_upgrade || strcmp(name,pkgname))) {
|
||||
/* we're looking at a file in the db that belongs to a different package */
|
||||
for(i = 0; i < filecount; i++) {
|
||||
filestr = files[i];
|
||||
if(filestr[0] == '*') {
|
||||
|
@ -752,7 +809,7 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
|
|||
/* this filename has a trailing '/', so it's a directory -- skip it. */
|
||||
continue;
|
||||
}
|
||||
printf("conflict: %s already exists in package \"%s\"\n", dbstr, name);
|
||||
fprintf(stderr, "conflict: %s already exists in package \"%s\"\n", dbstr, name);
|
||||
conflicts = 1;
|
||||
}
|
||||
}
|
||||
|
@ -768,7 +825,7 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
|
|||
filestr++;
|
||||
}
|
||||
if(!stat(filestr, &buf) && !S_ISDIR(buf.st_mode)) {
|
||||
printf("conflict: %s already exists in filesystem\n", filestr);
|
||||
fprintf(stderr, "conflict: %s already exists in filesystem\n", filestr);
|
||||
conflicts = 1;
|
||||
}
|
||||
}
|
||||
|
@ -785,8 +842,9 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
|
|||
int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
||||
unsigned int* bakct)
|
||||
{
|
||||
FILE* fp;
|
||||
char line[255];
|
||||
FILE* fp = NULL;
|
||||
FILE* inst = NULL;
|
||||
char line[PATH_MAX+1];
|
||||
char* ptr = NULL;
|
||||
char* key = NULL;
|
||||
int linenum = 0;
|
||||
|
@ -799,7 +857,7 @@ int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
|||
}
|
||||
|
||||
while(!feof(fp)) {
|
||||
fgets(line, 255, fp);
|
||||
fgets(line, PATH_MAX, fp);
|
||||
if(output) {
|
||||
printf("%s", line);
|
||||
}
|
||||
|
@ -814,7 +872,7 @@ int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
|||
ptr = line;
|
||||
key = strsep(&ptr, "=");
|
||||
if(key == NULL || ptr == NULL) {
|
||||
printf("Syntax error in description file line %d\n", linenum);
|
||||
fprintf(stderr, "Syntax error in description file line %d\n", linenum);
|
||||
} else {
|
||||
key = trim(key);
|
||||
key = strtoupper(key);
|
||||
|
@ -827,12 +885,25 @@ int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
|||
strcpy(pkgver, ptr);
|
||||
} else if(!strcmp(key, "PKGDESC")) {
|
||||
/* Not used yet */
|
||||
} else if(!strcmp(key, "INSTALL")) {
|
||||
if(inst == NULL) {
|
||||
pm_install = (char*)malloc(strlen("/tmp/pacman_XXXXXX")+1);
|
||||
strcpy(pm_install, "/tmp/pacman_XXXXXX");
|
||||
mkstemp(pm_install);
|
||||
inst = fopen(pm_install, "w");
|
||||
if(inst == NULL) {
|
||||
perror("fopen");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
fputs(ptr, inst);
|
||||
fputc('\n', inst);
|
||||
} else if(!strcmp(key, "BACKUP")) {
|
||||
backup = (fileset_t)realloc(backup, (++count) * sizeof(char*));
|
||||
backup[count-1] = (char*)malloc(strlen(ptr)+1);
|
||||
strcpy(backup[count-1], ptr);
|
||||
} else {
|
||||
printf("Syntax error in description file line %d\n", linenum);
|
||||
fprintf(stderr, "Syntax error in description file line %d\n", linenum);
|
||||
}
|
||||
}
|
||||
line[0] = '\0';
|
||||
|
@ -840,6 +911,11 @@ int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
|||
fclose(fp);
|
||||
unlink(descfile);
|
||||
|
||||
if(inst != NULL) {
|
||||
fputs("exit 0\n", inst);
|
||||
fclose(inst);
|
||||
}
|
||||
|
||||
if(count > 0) {
|
||||
(*bakptr) = backup;
|
||||
(*bakct) = count;
|
||||
|
@ -853,19 +929,21 @@ int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
|
|||
* argc: argc
|
||||
* argv: argv
|
||||
*
|
||||
* Returns: the functional variable for that operation
|
||||
* (eg, the package file name for PM_ADD)
|
||||
* Returns: 0 on success, 1 on error
|
||||
*/
|
||||
char* parseargs(int op, int argc, char** argv)
|
||||
int parseargs(int op, int argc, char** argv)
|
||||
{
|
||||
char* pkg = NULL;
|
||||
int i;
|
||||
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(strlen(argv[i]) > PATH_MAX) {
|
||||
fprintf(stderr, "error: argument %d is too long.\n", i);
|
||||
return(1);
|
||||
}
|
||||
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
pmo_nofunc = 1;
|
||||
usage(op, (char*)basename(argv[0]));
|
||||
return(NULL);
|
||||
return(1);
|
||||
} else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
|
||||
pmo_verbose = 1;
|
||||
} else if(!strcmp(argv[i], "-f") || !strcmp(argv[i], "--force")) {
|
||||
|
@ -873,14 +951,14 @@ char* parseargs(int op, int argc, char** argv)
|
|||
} else if(!strcmp(argv[i], "-r") || !strcmp(argv[i], "--root")) {
|
||||
i++;
|
||||
if(i >= argc) {
|
||||
printf("error: missing argument for %s\n", argv[i-1]);
|
||||
return(NULL);
|
||||
fprintf(stderr, "error: missing argument for %s\n", argv[i-1]);
|
||||
return(1);
|
||||
}
|
||||
free(pmo_root);
|
||||
pmo_root = (char*)malloc(PATH_MAX);
|
||||
if(realpath(argv[i], pmo_root) == NULL) {
|
||||
perror("bad root path");
|
||||
return(NULL);
|
||||
return(1);
|
||||
}
|
||||
} else if(!strcmp(argv[i], "-n") || !strcmp(argv[i], "--nosave")) {
|
||||
pmo_nosave = 1;
|
||||
|
@ -888,15 +966,19 @@ char* parseargs(int op, int argc, char** argv)
|
|||
/* PM_QUERY only */
|
||||
i++;
|
||||
if(i >= argc) {
|
||||
printf("error: missing argument for %s\n", argv[i-1]);
|
||||
return(NULL);
|
||||
fprintf(stderr, "error: missing argument for %s\n", argv[i-1]);
|
||||
return(1);
|
||||
}
|
||||
if(strlen(argv[i]) > PATH_MAX) {
|
||||
fprintf(stderr, "error: argument %d is too long.\n", i);
|
||||
return(1);
|
||||
}
|
||||
free(pmo_q_owns);
|
||||
pmo_q_owns = (char*)malloc(PATH_MAX);
|
||||
if(realpath(argv[i], pmo_q_owns) == NULL) {
|
||||
perror("bad path specified for --owns");
|
||||
pmo_nofunc = 1;
|
||||
return(NULL);
|
||||
return(1);
|
||||
}
|
||||
} else if(!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) {
|
||||
/* PM_QUERY only */
|
||||
|
@ -908,20 +990,22 @@ char* parseargs(int op, int argc, char** argv)
|
|||
/* PM_QUERY only */
|
||||
pmo_q_info = 1;
|
||||
} else {
|
||||
pkg = argv[i];
|
||||
/* add the target to our pseudo linked list */
|
||||
pm_targets = (fileset_t)realloc(pm_targets, (++pm_targct) * sizeof(char*));
|
||||
pm_targets[pm_targct-1] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(op != PM_QUERY && pkg == NULL) {
|
||||
printf("error: no package specified\n\n");
|
||||
if(op != PM_QUERY && pm_targct < 1) {
|
||||
fprintf(stderr, "error: no package specified\n\n");
|
||||
usage(op, (char*)basename(argv[0]));
|
||||
return(NULL);
|
||||
return(1);
|
||||
}
|
||||
if(op == PM_QUERY && pmo_q_isfile && pkg == NULL) {
|
||||
printf("error: no package file specified\n\n");
|
||||
return(NULL);
|
||||
if(op == PM_QUERY && pmo_q_isfile && pm_targct < 1) {
|
||||
fprintf(stderr, "error: no package file specified\n\n");
|
||||
return(1);
|
||||
}
|
||||
return(pkg);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Display usage/syntax for the specified operation.
|
||||
|
|
8
pacman.h
8
pacman.h
|
@ -21,7 +21,7 @@
|
|||
#ifndef PACMAN_H
|
||||
#define PACMAN_H
|
||||
|
||||
#define VERSION "1.1"
|
||||
#define VERSION "1.2"
|
||||
|
||||
#define PKGEXT ".tar.gz"
|
||||
#define PKGDB "/var/lib/pacman/pacman.db"
|
||||
|
@ -36,8 +36,8 @@
|
|||
typedef int (*pm_opfunc_t)(char*);
|
||||
typedef char** fileset_t;
|
||||
typedef struct __pkginfo_t {
|
||||
char version[32];
|
||||
char name[64];
|
||||
char version[64];
|
||||
char name[256];
|
||||
} pkginfo_t;
|
||||
|
||||
int pacman_add(char* pkgfile);
|
||||
|
@ -50,7 +50,7 @@ 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);
|
||||
|
||||
char* parseargs(int op, int argc, char** argv);
|
||||
int parseargs(int op, int argc, char** argv);
|
||||
int parse_descfile(char* descfile, unsigned short output, fileset_t* bakptr,
|
||||
unsigned int* bakct);
|
||||
|
||||
|
|
281
pacsync
Executable file
281
pacsync
Executable file
|
@ -0,0 +1,281 @@
|
|||
#!/bin/bash
|
||||
|
||||
version="1.2"
|
||||
tanpath="/var/lib/pacman"
|
||||
tandb="pacsync.db"
|
||||
errors=0
|
||||
upgrade=0
|
||||
|
||||
message() {
|
||||
echo "==> $1" >&2
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "pacsync version $version"
|
||||
echo "usage: $0 <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 ""
|
||||
}
|
||||
|
||||
checkdb() {
|
||||
if [ ! -f $tanpath/$tandb ]; then
|
||||
message "missing package list. (use \"sync\" first)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download() {
|
||||
targ=$1
|
||||
shift
|
||||
cl=
|
||||
for file in $*; do
|
||||
cl="$cl $SYNC_SERVER/$file"
|
||||
done
|
||||
message "Downloading $targ"
|
||||
$ftpagent $cl
|
||||
if [ $? -gt 0 ]; then
|
||||
message "ERROR: could not download $targ"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
dosync() {
|
||||
cd /tmp
|
||||
download "package list" $tandb
|
||||
if [ $? -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tanpath/$tandb
|
||||
mv /tmp/$tandb $tanpath/$tandb
|
||||
message "Done."
|
||||
}
|
||||
|
||||
doinstall() {
|
||||
pkg2dl=
|
||||
pkg2inst=
|
||||
for pkgname in $*; do
|
||||
line=`egrep "^[a-z]+/$pkgname-[a-z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $tanpath/$tandb`
|
||||
if [ $? -gt 0 ]; then
|
||||
message "package $pkgname not found"
|
||||
exit 1
|
||||
fi
|
||||
pacman=`pacman -Q $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 /var/cache/pacman/pkg/$filename ]; then
|
||||
pkg2dl="$pkg2dl arch/$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` != "/var/cache/pacman/pkg" ]; then
|
||||
# move downloaded files into cache
|
||||
mkdir -p /var/cache/pacman/pkg
|
||||
mv `echo $pkg2dl | sed 's|arch/||g'` /var/cache/pacman/pkg/
|
||||
fi
|
||||
fi
|
||||
|
||||
# install packages
|
||||
message "Installing packages"
|
||||
cd /var/cache/pacman/pkg
|
||||
pacman -A $pkg2inst
|
||||
if [ $? -gt 0 ]; then
|
||||
echo "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-z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $tanpath/$tandb`
|
||||
if [ $? -gt 0 ]; then
|
||||
message "package $pkgname not found"
|
||||
exit 1
|
||||
fi
|
||||
pacman=`pacman -Q $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 /var/cache/pacman/pkg/$filename ]; then
|
||||
pkg2dl="$pkg2dl arch/$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` != "/var/cache/pacman/pkg" ]; then
|
||||
# move downloaded files into cache
|
||||
mkdir -p /var/cache/pacman/pkg
|
||||
mv `echo $pkg2dl | sed 's|arch/||g'` /var/cache/pacman/pkg/
|
||||
fi
|
||||
fi
|
||||
|
||||
# install packages
|
||||
if [ "$pkg2up" != "" ]; then
|
||||
message "Upgrading packages"
|
||||
cd /var/cache/pacman/pkg
|
||||
pacman -U $pkg2up
|
||||
if [ $? -gt 0 ]; then
|
||||
echo "ERROR: some packages failed to upgrade"
|
||||
exit 1
|
||||
fi
|
||||
message "Done"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
doreport() {
|
||||
headers=0
|
||||
pkg2up=
|
||||
for pkgfile in `cat $tanpath/$tandb | sed "s|^[a-z]*/||g"`; do
|
||||
pkgname=`echo $pkgfile | sed 's|-[a-z0-9\.]*-[0-9]*\.pkg\.tar\.gz||g'`
|
||||
pacman=`pacman -Q $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-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 [ "$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
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /etc/pacsync.conf ]; then
|
||||
. /etc/pacsync.conf
|
||||
else
|
||||
message "error: missing configuration file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
proto=`echo $SYNC_SERVER | sed 's|://.*||'`
|
||||
# check for a download utility
|
||||
if [ -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 (lftp or 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 /var/cache/pacman/pkg/*
|
||||
;;
|
||||
*)
|
||||
message "error: invalid operation"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
53
pacsync.8.in
Normal file
53
pacsync.8.in
Normal file
|
@ -0,0 +1,53 @@
|
|||
.TH pacsync 8 "Mar 17, 2002" "pacsync #VERSION#" ""
|
||||
.SH NAME
|
||||
pacsync \- package update frontend for pacman
|
||||
.SH SYNOPSIS
|
||||
\fBpacsync <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
|
8
pacsync.conf
Normal file
8
pacsync.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# /etc/pacsync.conf
|
||||
#
|
||||
|
||||
# the full URL of the server (up to the /arch package directory)
|
||||
SYNC_SERVER="ftp://ftp.archlinux.org"
|
||||
#SYNC_SERVER="http://www.archlinux.org/pub"
|
||||
|
Loading…
Add table
Reference in a new issue