Imported from pacman-2.9.3.tar.gz
This commit is contained in:
parent
4795965caf
commit
f6b8ed22f4
18 changed files with 735 additions and 160 deletions
|
@ -1,5 +1,13 @@
|
|||
VERSION DESCRIPTION
|
||||
-----------------------------------------------------------------------------
|
||||
2.9.3 - fixed a couple manpage typos
|
||||
- added --ignore to -S operations, works just like IgnorePkg
|
||||
- respect IgnorePkg list when pulling in dependencies
|
||||
- numerous memleak fixes
|
||||
- some code changes to improve customizability/branding
|
||||
- Makefile fix for nonstandard lib search paths (Kevin Piche)
|
||||
- fixed the leftover directories in /tmp
|
||||
- speed improvement patches from Tommi Rantala
|
||||
2.9.2 - bugfix for 2.9.1
|
||||
2.9.1 - --refresh now only downloads fresh packages lists if they've
|
||||
been updated (currently only works with FTP)
|
||||
|
|
|
@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
|||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
|
||||
PACVER = 2.9.2
|
||||
PACVER = 2.9.3
|
||||
|
||||
TOPDIR = @srcdir@
|
||||
SRCDIR = $(TOPDIR)/src/
|
||||
|
@ -55,6 +55,7 @@ SRCS = $(SRCDIR)pacman.c \
|
|||
$(SRCDIR)pacsync.c \
|
||||
$(SRCDIR)md5.c \
|
||||
$(SRCDIR)md5driver.c \
|
||||
$(SRCDIR)strhash.c \
|
||||
$(SRCDIR)vercmp.c \
|
||||
$(SRCDIR)rpmvercmp.c
|
||||
|
||||
|
@ -66,6 +67,7 @@ OBJECTS = $(OBJDIR)pacman.o \
|
|||
$(OBJDIR)pacsync.o \
|
||||
$(OBJDIR)md5.o \
|
||||
$(OBJDIR)md5driver.o \
|
||||
$(OBJDIR)strhash.o \
|
||||
$(OBJDIR)rpmvercmp.o
|
||||
|
||||
all: libftp.a pacman vercmp convertdb man
|
||||
|
@ -78,7 +80,7 @@ vercmp: $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o
|
|||
$(CXX) $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o $(CXXFLAGS) -o $@
|
||||
|
||||
convertdb: $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o
|
||||
$(CXX) $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o $(CXXFLAGS) -lz -ltar -o $@
|
||||
$(CXX) $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o $(LDFLAGS) -o $@
|
||||
|
||||
.c.o: $(SRCS)
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
|
|
@ -60,7 +60,7 @@ installed and there are no package conflicts in the system. This
|
|||
switch disables these checks.
|
||||
.TP
|
||||
.B "\-f, \-\-force"
|
||||
Bypass file conflict checks,, overwriting conflicting files. If the
|
||||
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.
|
||||
|
@ -147,9 +147,9 @@ removed.
|
|||
.TP
|
||||
.B "\-s, \-\-recursive"
|
||||
For each target specified, remove it and all its dependencies, provided
|
||||
that (A) they are not required by other packages; and (B) they were
|
||||
explicitly installed by the user and not pulled in as a dependency for
|
||||
other packages. This option is analagous to a backwards --sync operation.
|
||||
that (A) they are not required by other packages; and (B) they were not
|
||||
explicitly installed by the user.
|
||||
This option is analagous to a backwards --sync operation.
|
||||
.SH QUERY OPTIONS
|
||||
.TP
|
||||
.B "\-e, \-\-orphans"
|
||||
|
|
|
@ -134,6 +134,8 @@ db_write_entry()
|
|||
done
|
||||
echo "" >>depends
|
||||
fi
|
||||
# preserve the modification time
|
||||
touch -r $1 desc depends
|
||||
}
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
|
|
|
@ -463,6 +463,7 @@ if [ "$GENMD5" = "0" ]; then
|
|||
# extract sources
|
||||
msg "Extracting Sources..."
|
||||
for netfile in ${source[@]}; do
|
||||
unziphack=0
|
||||
file=`strip_url $netfile`
|
||||
unset cmd
|
||||
case $file in
|
||||
|
@ -473,6 +474,7 @@ if [ "$GENMD5" = "0" ]; then
|
|||
*.tar)
|
||||
cmd="tar -xf $file" ;;
|
||||
*.zip)
|
||||
unziphack=1
|
||||
cmd="unzip -qqo $file" ;;
|
||||
*.gz)
|
||||
cmd="gunzip $file" ;;
|
||||
|
@ -483,9 +485,12 @@ if [ "$GENMD5" = "0" ]; then
|
|||
msg " $cmd"
|
||||
$cmd
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Failed to extract $file"
|
||||
msg "Aborting..."
|
||||
exit 1
|
||||
# unzip will return a 1 as a warning, it is not an error
|
||||
if [ "$unziphack" != "1" -o $? -ne 1 ]; then
|
||||
error "Failed to extract $file"
|
||||
msg "Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "pacconf.h"
|
||||
#include "list.h"
|
||||
#include "util.h"
|
||||
|
||||
unsigned short pmo_verbose = 0;
|
||||
|
||||
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];
|
||||
|
@ -44,6 +46,9 @@ int main(int argc, char* argv[])
|
|||
char path[PATH_MAX+1];
|
||||
mode_t oldumask;
|
||||
struct stat buf;
|
||||
char dbdir[PATH_MAX];
|
||||
|
||||
sprintf(dbdir, "/%s", PACDBDIR);
|
||||
|
||||
if(argc < 2) {
|
||||
printf("converts a pacman 1.x database to a pacman 2.0 format\n");
|
||||
|
|
127
src/db.c
127
src/db.c
|
@ -29,6 +29,7 @@
|
|||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include "package.h"
|
||||
#include "strhash.h"
|
||||
#include "util.h"
|
||||
#include "db.h"
|
||||
|
||||
|
@ -131,26 +132,63 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
|||
struct dirent *ent = NULL;
|
||||
struct stat sbuf;
|
||||
char path[PATH_MAX];
|
||||
char name[256];
|
||||
int path_len = 0;
|
||||
char *name = NULL;
|
||||
char *ptr = NULL;
|
||||
int found = 0;
|
||||
|
||||
/* hash table for caching directory names */
|
||||
static strhash_t* htable = NULL;
|
||||
|
||||
if (!htable)
|
||||
htable = new_strhash(951);
|
||||
|
||||
snprintf(path, PATH_MAX, "%s/", db->path);
|
||||
path_len = strlen(path);
|
||||
|
||||
if(target != NULL) {
|
||||
/* search for a specific package (by name only) */
|
||||
|
||||
/* See if we have the path cached. */
|
||||
strcat(path, target);
|
||||
if (strhash_isin(htable, path)) {
|
||||
struct dirent* pkgdir;
|
||||
pkginfo_t* pkg;
|
||||
|
||||
/* db_read() wants 'struct dirent' so lets give it one.
|
||||
* Actually it only uses the d_name field. */
|
||||
|
||||
MALLOC(pkgdir, sizeof(struct dirent));
|
||||
strcpy(pkgdir->d_name, strhash_get(htable, path));
|
||||
|
||||
pkg = db_read(db, pkgdir, inforeq);
|
||||
FREE(pkgdir);
|
||||
return pkg;
|
||||
}
|
||||
path[path_len] = '\0';
|
||||
|
||||
/* OK the entry was not in cache, so lets look for it manually. */
|
||||
|
||||
rewinddir(db->dir);
|
||||
ent = readdir(db->dir);
|
||||
|
||||
while(!found && ent != NULL) {
|
||||
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
|
||||
ent = readdir(db->dir);
|
||||
continue;
|
||||
}
|
||||
strncpy(name, ent->d_name, 255);
|
||||
|
||||
/* stat the entry, make sure it's a directory */
|
||||
snprintf(path, PATH_MAX, "%s/%s", db->path, name);
|
||||
path[path_len] = '\0';
|
||||
strncat(path, ent->d_name, PATH_MAX - path_len);
|
||||
|
||||
if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
|
||||
ent = readdir(db->dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
name = path + path_len;
|
||||
|
||||
/* truncate the string at the second-to-last hyphen, */
|
||||
/* which will give us the package name */
|
||||
if((ptr = rindex(name, '-'))) {
|
||||
|
@ -176,8 +214,11 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
|||
if(ent == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* stat the entry, make sure it's a directory */
|
||||
snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
|
||||
path[path_len] = '\0';
|
||||
strncat(path, ent->d_name, PATH_MAX - path_len);
|
||||
|
||||
if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
|
||||
isdir = 1;
|
||||
}
|
||||
|
@ -185,6 +226,25 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
|||
isdir = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
name = path + path_len;
|
||||
|
||||
if((ptr = rindex(name, '-'))) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
if((ptr = rindex(name, '-'))) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
/* Add entries like:
|
||||
*
|
||||
* key: /var/lib/pacman/extra/xrally
|
||||
* data: xrally-1.1.1-1
|
||||
*/
|
||||
|
||||
if (!strhash_isin(htable, path)) {
|
||||
strhash_add(htable, strdup(path), strdup(ent->d_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return(db_read(db, ent, inforeq));
|
||||
|
@ -603,6 +663,28 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
|||
char *str = NULL;
|
||||
struct stat buf, buf2;
|
||||
PMList *conflicts = NULL;
|
||||
strhash_t** htables;
|
||||
int target_num = 0;
|
||||
int d = 0;
|
||||
int e = 0;
|
||||
|
||||
/* Create and initialise an array of hash tables.
|
||||
*
|
||||
* htables [ 0 ... target_num ] : targets' files
|
||||
* htables [ target_num ] : used later
|
||||
*/
|
||||
|
||||
target_num = list_count(targets);
|
||||
|
||||
MALLOC(htables, (target_num+1) * sizeof(strhash_t*));
|
||||
|
||||
for(d = 0, i = targets; i; i = i->next, d++) {
|
||||
htables[d] = new_strhash(151);
|
||||
|
||||
strhash_add_list(htables[d], ((pkginfo_t*)i->data)->files);
|
||||
}
|
||||
|
||||
htables[target_num] = new_strhash(151);
|
||||
|
||||
/* CHECK 1: check every db package against every target package */
|
||||
/* XXX: I've disabled the database-against-targets check for now, as the
|
||||
|
@ -613,34 +695,30 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
|||
pkginfo_t *info = NULL;
|
||||
char *dbstr = NULL;
|
||||
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) {
|
||||
|
||||
if(dbstr == NULL || rindex(dbstr, '/') == dbstr+strlen(dbstr)-1)
|
||||
continue;
|
||||
|
||||
for(d = 0, j = targets; j; j = j->next, d++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if(strcmp(info->name, targ->name) && strhash_isin(htables[d], dbstr)) {
|
||||
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 */
|
||||
for(i = targets; i; i = i->next) {
|
||||
for(d = 0, i = targets; i; i = i->next, d++) {
|
||||
pkginfo_t *p1 = (pkginfo_t*)i->data;
|
||||
for(j = i; j; j = j->next) {
|
||||
for(e = d, j = i; j; j = j->next, e++) {
|
||||
pkginfo_t *p2 = (pkginfo_t*)j->data;
|
||||
if(strcmp(p1->name, p2->name)) {
|
||||
for(k = p1->files; k; k = k->next) {
|
||||
|
@ -652,7 +730,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
|||
/* this filename has a trailing '/', so it's a directory -- skip it. */
|
||||
continue;
|
||||
}
|
||||
if(is_in(filestr, p2->files)) {
|
||||
if(strhash_isin(htables[e], filestr)) {
|
||||
MALLOC(str, 512);
|
||||
snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (target)",
|
||||
filestr, p1->name, p2->name);
|
||||
|
@ -674,8 +752,11 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
|||
int ok = 0;
|
||||
if(dbpkg == NULL) {
|
||||
dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES);
|
||||
|
||||
if(dbpkg)
|
||||
strhash_add_list(htables[target_num], dbpkg->files);
|
||||
}
|
||||
if(dbpkg && is_in(j->data, dbpkg->files)) {
|
||||
if(dbpkg && strhash_isin(htables[target_num], filestr)) {
|
||||
ok = 1;
|
||||
}
|
||||
/* Make sure that the supposedly-conflicting file is not actually just
|
||||
|
|
104
src/list.c
104
src/list.c
|
@ -23,8 +23,32 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "list.h"
|
||||
|
||||
/* 1: List seems to be OK.
|
||||
* 0: We're in deep ...
|
||||
*/
|
||||
|
||||
int CheckList(PMList* list)
|
||||
{
|
||||
PMList* it = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
return 1;
|
||||
|
||||
if (list->last == NULL)
|
||||
return 0;
|
||||
|
||||
for (it = list; it && it->next; it = it->next)
|
||||
;
|
||||
|
||||
if (it != list->last)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
PMList* list_new()
|
||||
{
|
||||
PMList *list = NULL;
|
||||
|
@ -36,6 +60,7 @@ PMList* list_new()
|
|||
list->data = NULL;
|
||||
list->prev = NULL;
|
||||
list->next = NULL;
|
||||
list->last = list;
|
||||
return(list);
|
||||
}
|
||||
|
||||
|
@ -62,6 +87,8 @@ PMList* list_add(PMList *list, void *data)
|
|||
ptr = list;
|
||||
if(ptr == NULL) {
|
||||
ptr = list_new();
|
||||
if (!ptr)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
lp = list_last(ptr);
|
||||
|
@ -73,12 +100,67 @@ PMList* list_add(PMList *list, void *data)
|
|||
return(NULL);
|
||||
}
|
||||
lp->next->prev = lp;
|
||||
lp->last = NULL;
|
||||
lp = lp->next;
|
||||
}
|
||||
|
||||
lp->data = data;
|
||||
ptr->last = lp;
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/* list: the beginning of the list
|
||||
* item: the item in the list to be removed
|
||||
*
|
||||
* returns:
|
||||
* list with item removed
|
||||
*/
|
||||
|
||||
PMList* list_remove(PMList* list, PMList* item)
|
||||
{
|
||||
assert(CheckList(list));
|
||||
|
||||
if (list == NULL || item == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Remove first item in list. */
|
||||
if (item == list) {
|
||||
if (list->next == NULL) { /* Only item in list. */
|
||||
list_free(item);
|
||||
return NULL;
|
||||
} else {
|
||||
list->next->prev = NULL;
|
||||
list->next->last = list->last;
|
||||
list = list->next;
|
||||
item->prev = item->next = NULL;
|
||||
list_free(item);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove last item in list. */
|
||||
if (list->last == item) {
|
||||
list->last = item->prev;
|
||||
item->prev->next = NULL;
|
||||
item->prev = item->next = NULL;
|
||||
list_free(item);
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Remove middle item in list. */
|
||||
assert(item->prev != NULL &&
|
||||
item->next != NULL);
|
||||
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
item->prev = item->next = NULL;
|
||||
list_free(item);
|
||||
|
||||
assert(CheckList(list));
|
||||
return list;
|
||||
}
|
||||
|
||||
int list_count(PMList *list)
|
||||
{
|
||||
int i;
|
||||
|
@ -141,10 +223,11 @@ PMList* list_merge(PMList *one, PMList *two)
|
|||
|
||||
PMList* list_last(PMList *list)
|
||||
{
|
||||
PMList *ptr;
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
|
||||
for(ptr = list; ptr && ptr->next; ptr = ptr->next);
|
||||
return(ptr);
|
||||
assert(list->last != NULL);
|
||||
return list->last;
|
||||
}
|
||||
|
||||
/* Helper function for sorting a list of strings
|
||||
|
@ -257,10 +340,23 @@ PMList* list_add_sorted(PMList *list, void *data, cmp_fn sortfunc)
|
|||
/* Insert node before insertion point. */
|
||||
add->prev = prev;
|
||||
add->next = iter;
|
||||
if(iter != NULL) iter->prev = add; /* Not at end. */
|
||||
|
||||
if(iter != NULL) {
|
||||
iter->prev = add; /* Not at end. */
|
||||
} else {
|
||||
if (list != NULL)
|
||||
list->last = add; /* Added new to end, so update the link to last. */
|
||||
}
|
||||
|
||||
if(prev != NULL) {
|
||||
prev->next = add; /* In middle. */
|
||||
} else {
|
||||
if (list == NULL) {
|
||||
add->last = add;
|
||||
} else {
|
||||
add->last = list->last;
|
||||
list->last = NULL;
|
||||
}
|
||||
list = add; /* Start or empty, new list head. */
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef struct __pmlist_t {
|
|||
void* data;
|
||||
struct __pmlist_t* prev;
|
||||
struct __pmlist_t* next;
|
||||
struct __pmlist_t* last; /* Quick access to last item in list */
|
||||
} PMList;
|
||||
|
||||
|
||||
|
@ -38,6 +39,7 @@ typedef int (*cmp_fn) (const void *, const void *);
|
|||
PMList* list_new();
|
||||
void list_free(PMList* list);
|
||||
PMList* list_add(PMList* list, void* data);
|
||||
PMList* list_remove(PMList* list, PMList* item);
|
||||
int list_count(PMList* list);
|
||||
int list_isin(PMList *haystack, void *needle);
|
||||
PMList* is_in(char *needle, PMList *haystack);
|
||||
|
|
46
src/pacconf.h
Normal file
46
src/pacconf.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* pacconf.h
|
||||
*
|
||||
* Copyright (c) 2002-2004 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_PACCONF_H
|
||||
#define _PAC_PACCONF_H
|
||||
|
||||
#ifndef PACVER
|
||||
#define PACVER "2.9.3"
|
||||
#endif
|
||||
|
||||
#ifndef PACDBDIR
|
||||
#define PACDBDIR "var/lib/pacman"
|
||||
#endif
|
||||
|
||||
#ifndef PKGEXT
|
||||
#define PKGEXT ".pkg.tar.gz"
|
||||
#endif
|
||||
|
||||
#ifndef PACCONF
|
||||
#define PACCONF "/etc/pacman.conf"
|
||||
#endif
|
||||
|
||||
#ifndef CACHEDIR
|
||||
#define CACHEDIR "var/cache/pacman/pkg"
|
||||
#endif
|
||||
|
||||
#endif /* PACCONF_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
|
@ -27,6 +27,7 @@
|
|||
#include <string.h>
|
||||
#include <libtar.h>
|
||||
#include <zlib.h>
|
||||
#include "pacconf.h"
|
||||
#include "util.h"
|
||||
#include "package.h"
|
||||
|
||||
|
@ -410,7 +411,7 @@ int split_pkgname(char *pkgfile, char *name, char *version)
|
|||
}
|
||||
strncpy(tmp, p, 512);
|
||||
/* trim file extension (if any) */
|
||||
if((p = strstr(tmp, ".pkg.tar.gz"))) {
|
||||
if((p = strstr(tmp, PKGEXT))) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
|
|
237
src/pacman.c
237
src/pacman.c
|
@ -37,6 +37,7 @@
|
|||
#include <libtar.h>
|
||||
#include <dirent.h>
|
||||
/* pacman */
|
||||
#include "pacconf.h"
|
||||
#include "rpmvercmp.h"
|
||||
#include "md5.h"
|
||||
#include "list.h"
|
||||
|
@ -52,35 +53,36 @@
|
|||
*/
|
||||
|
||||
/* command line options */
|
||||
char *pmo_root = NULL;
|
||||
unsigned short pmo_op = PM_MAIN;
|
||||
unsigned short pmo_verbose = 0;
|
||||
unsigned short pmo_version = 0;
|
||||
unsigned short pmo_help = 0;
|
||||
unsigned short pmo_force = 0;
|
||||
unsigned short pmo_nodeps = 0;
|
||||
unsigned short pmo_upgrade = 0;
|
||||
unsigned short pmo_freshen = 0;
|
||||
unsigned short pmo_nosave = 0;
|
||||
unsigned short pmo_noconfirm = 0;
|
||||
unsigned short pmo_d_vertest = 0;
|
||||
unsigned short pmo_d_resolve = 0;
|
||||
unsigned short pmo_q_isfile = 0;
|
||||
unsigned short pmo_q_info = 0;
|
||||
unsigned short pmo_q_list = 0;
|
||||
unsigned short pmo_q_orphans = 0;
|
||||
unsigned short pmo_q_owns = 0;
|
||||
unsigned short pmo_q_search = 0;
|
||||
unsigned short pmo_r_cascade = 0;
|
||||
unsigned short pmo_r_dbonly = 0;
|
||||
unsigned short pmo_r_recurse = 0;
|
||||
unsigned short pmo_s_upgrade = 0;
|
||||
char *pmo_root = NULL;
|
||||
unsigned short pmo_op = PM_MAIN;
|
||||
unsigned short pmo_verbose = 0;
|
||||
unsigned short pmo_version = 0;
|
||||
unsigned short pmo_help = 0;
|
||||
unsigned short pmo_force = 0;
|
||||
unsigned short pmo_nodeps = 0;
|
||||
unsigned short pmo_upgrade = 0;
|
||||
unsigned short pmo_freshen = 0;
|
||||
unsigned short pmo_nosave = 0;
|
||||
unsigned short pmo_noconfirm = 0;
|
||||
unsigned short pmo_d_vertest = 0;
|
||||
unsigned short pmo_d_resolve = 0;
|
||||
unsigned short pmo_q_isfile = 0;
|
||||
unsigned short pmo_q_info = 0;
|
||||
unsigned short pmo_q_list = 0;
|
||||
unsigned short pmo_q_orphans = 0;
|
||||
unsigned short pmo_q_owns = 0;
|
||||
unsigned short pmo_q_search = 0;
|
||||
unsigned short pmo_r_cascade = 0;
|
||||
unsigned short pmo_r_dbonly = 0;
|
||||
unsigned short pmo_r_recurse = 0;
|
||||
unsigned short pmo_s_upgrade = 0;
|
||||
unsigned short pmo_s_downloadonly = 0;
|
||||
unsigned short pmo_s_printuris = 0;
|
||||
unsigned short pmo_s_sync = 0;
|
||||
unsigned short pmo_s_search = 0;
|
||||
unsigned short pmo_s_clean = 0;
|
||||
unsigned short pmo_group = 0;
|
||||
unsigned short pmo_s_sync = 0;
|
||||
unsigned short pmo_s_search = 0;
|
||||
unsigned short pmo_s_clean = 0;
|
||||
PMList *pmo_s_ignore = NULL;
|
||||
unsigned short pmo_group = 0;
|
||||
/* configuration file options */
|
||||
char *pmo_dbpath = NULL;
|
||||
char *pmo_configfile = NULL;
|
||||
|
@ -91,6 +93,7 @@ char *pmo_xfercommand = NULL;
|
|||
PMList *pmo_noupgrade = NULL;
|
||||
PMList *pmo_ignorepkg = NULL;
|
||||
PMList *pmo_holdpkg = NULL;
|
||||
unsigned short pmo_chomp = 0;
|
||||
unsigned short pmo_usesyslog = 0;
|
||||
unsigned short pmo_nopassiveftp = 0;
|
||||
|
||||
|
@ -132,7 +135,7 @@ int main(int argc, char *argv[])
|
|||
strcpy(pmo_root, "/");
|
||||
/* default dbpath */
|
||||
MALLOC(pmo_dbpath, PATH_MAX);
|
||||
strcpy(pmo_dbpath, PKGDIR);
|
||||
strcpy(pmo_dbpath, PACDBDIR);
|
||||
/* default configuration file */
|
||||
MALLOC(pmo_configfile, PATH_MAX);
|
||||
strcpy(pmo_configfile, PACCONF);
|
||||
|
@ -152,6 +155,9 @@ int main(int argc, char *argv[])
|
|||
myuid = 99;
|
||||
}
|
||||
|
||||
/* change to / so we can avoid having our CWD removed from under us */
|
||||
chdir("/");
|
||||
|
||||
/* check for permission */
|
||||
pm_access = READ_ONLY;
|
||||
if(pmo_op != PM_MAIN && pmo_op != PM_QUERY && pmo_op != PM_DEPTEST) {
|
||||
|
@ -343,9 +349,12 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
PMList *cache = NULL;
|
||||
PMList *clean = NULL;
|
||||
PMList *i, *j;
|
||||
char dirpath[PATH_MAX];
|
||||
|
||||
snprintf(dirpath, PATH_MAX, "%s%s", pmo_root, CACHEDIR);
|
||||
|
||||
printf("removing old packages from cache... ");
|
||||
dir = opendir("/var/cache/pacman/pkg");
|
||||
dir = opendir(dirpath);
|
||||
if(dir == NULL) {
|
||||
fprintf(stderr, "error: could not access cache directory\n");
|
||||
return(1);
|
||||
|
@ -361,14 +370,15 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
|
||||
for(i = cache; i; i = i->next) {
|
||||
char *str = (char *)i->data;
|
||||
char name[256], version[64];
|
||||
char pkgpart[256], name[256], version[64];
|
||||
|
||||
if(strstr(str, ".pkg.tar.gz") == NULL) {
|
||||
if(strstr(str, PKGEXT) == NULL) {
|
||||
clean = list_add(clean, strdup(str));
|
||||
continue;
|
||||
}
|
||||
snprintf(pkgpart, sizeof(pkgpart), "%s.part", PKGEXT);
|
||||
/* we keep partially downloaded files */
|
||||
if(strstr(str, ".pkg.tar.gz.part")) {
|
||||
if(strstr(str, pkgpart)) {
|
||||
continue;
|
||||
}
|
||||
if(split_pkgname(str, name, version) != 0) {
|
||||
|
@ -379,10 +389,10 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
char *s = (char *)j->data;
|
||||
char n[256], v[64];
|
||||
|
||||
if(strstr(s, ".pkg.tar.gz") == NULL) {
|
||||
if(strstr(s, PKGEXT) == NULL) {
|
||||
continue;
|
||||
}
|
||||
if(strstr(s, ".pkg.tar.gz.part")) {
|
||||
if(strstr(s, pkgpart)) {
|
||||
continue;
|
||||
}
|
||||
if(split_pkgname(s, n, v) != 0) {
|
||||
|
@ -617,7 +627,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
for(m = pm_packages; m; m = m->next) {
|
||||
pkginfo_t *p = (pkginfo_t*)m->data;
|
||||
if(!strcmp(k->data, p->name)) {
|
||||
if(is_in(p->name, pmo_ignorepkg)) {
|
||||
if(is_in(p->name, pmo_ignorepkg) || is_in(p->name, pmo_s_ignore)) {
|
||||
fprintf(stderr, ":: %s-%s: ignoring package upgrade (to be replaced by %s-%s)\n",
|
||||
p->name, p->version, pkg->name, pkg->version);
|
||||
ignore = 1;
|
||||
|
@ -684,8 +694,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
cmp = rpmvercmp(local->version, sync->pkg->version);
|
||||
if(cmp > 0 && !sync->pkg->force) {
|
||||
/* local version is newer */
|
||||
fprintf(stderr, ":: %s-%s: local version is newer\n",
|
||||
local->name, local->version);
|
||||
fprintf(stderr, ":: %s: local version (%s) is newer than repo version (%s)\n",
|
||||
local->name, local->version, sync->pkg->version);
|
||||
newer = 1;
|
||||
FREE(sync);
|
||||
continue;
|
||||
|
@ -693,7 +703,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
/* versions are identical */
|
||||
FREE(sync);
|
||||
continue;
|
||||
} else if(is_in((char*)i->data, pmo_ignorepkg)) {
|
||||
} else if(is_in((char*)i->data, pmo_ignorepkg) || is_in((char*)i->data, pmo_s_ignore)) {
|
||||
/* package should be ignored (IgnorePkg) */
|
||||
fprintf(stderr, ":: %s-%s: ignoring package upgrade (%s)\n",
|
||||
local->name, local->version, sync->pkg->version);
|
||||
|
@ -780,8 +790,13 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
if(sync->pkg == NULL) {
|
||||
found = 0;
|
||||
}
|
||||
/* this package was explicitly requested */
|
||||
sync->pkg->reason = REASON_EXPLICIT;
|
||||
if(pmo_d_resolve) {
|
||||
/* looks like we're being called from 'makepkg -s' so these are all deps */
|
||||
sync->pkg->reason = REASON_DEPEND;
|
||||
} else {
|
||||
/* this package was explicitly requested */
|
||||
sync->pkg->reason = REASON_EXPLICIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1132,7 +1147,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
PMList *processed = NULL;
|
||||
PMList *files = NULL;
|
||||
|
||||
snprintf(ldir, PATH_MAX, "%svar/cache/pacman/pkg", pmo_root);
|
||||
snprintf(ldir, PATH_MAX, "%s%s", pmo_root, CACHEDIR);
|
||||
|
||||
/* group sync records by repository and download */
|
||||
while(!done) {
|
||||
|
@ -1153,17 +1168,17 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
char path[PATH_MAX];
|
||||
|
||||
if(pmo_s_printuris) {
|
||||
snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
|
||||
snprintf(path, PATH_MAX, "%s-%s%s", sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
files = list_add(files, strdup(path));
|
||||
} else {
|
||||
snprintf(path, PATH_MAX, "%s/%s-%s.pkg.tar.gz",
|
||||
ldir, sync->pkg->name, sync->pkg->version);
|
||||
snprintf(path, PATH_MAX, "%s/%s-%s%s",
|
||||
ldir, sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
if(stat(path, &buf)) {
|
||||
/* file is not in the cache dir, so add it to the list */
|
||||
snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
|
||||
snprintf(path, PATH_MAX, "%s-%s%s", sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
files = list_add(files, strdup(path));
|
||||
} else {
|
||||
vprint(" %s-%s.pkg.tar.gz is already in the cache\n", sync->pkg->name, sync->pkg->version);
|
||||
vprint(" %s-%s%s is already in the cache\n", sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -1235,7 +1250,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
char *md5sum1, *md5sum2;
|
||||
|
||||
sync = (syncpkg_t*)i->data;
|
||||
snprintf(pkgname, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
|
||||
snprintf(pkgname, PATH_MAX, "%s-%s%s", sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
|
||||
md5sum1 = sync->pkg->md5sum;
|
||||
if(md5sum1 == NULL || md5sum1[0] == '\0') {
|
||||
|
@ -1327,7 +1342,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
|||
syncpkg_t *sync = (syncpkg_t*)i->data;
|
||||
if(sync->pkg) {
|
||||
MALLOC(str, PATH_MAX);
|
||||
snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, sync->pkg->name, sync->pkg->version);
|
||||
snprintf(str, PATH_MAX, "%s/%s-%s%s", ldir, sync->pkg->name, sync->pkg->version, PKGEXT);
|
||||
files = list_add(files, str);
|
||||
if(sync->pkg->reason == REASON_DEPEND) {
|
||||
dependonly = list_add(dependonly, strdup(str));
|
||||
|
@ -1978,7 +1993,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
|||
* or installed as a dependency for another package
|
||||
*/
|
||||
info->reason = REASON_EXPLICIT;
|
||||
if(is_in(file->data, dependonly)) {
|
||||
if(is_in(file->data, dependonly) || pmo_d_resolve) {
|
||||
info->reason = REASON_DEPEND;
|
||||
}
|
||||
/* make an install date (in UTC) */
|
||||
|
@ -2254,7 +2269,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
|||
|
||||
/* update dependency packages' REQUIREDBY fields */
|
||||
for(lp = info->depends; lp; lp = lp->next) {
|
||||
PMList *last, *j;
|
||||
PMList *j;
|
||||
|
||||
if(splitdep((char*)lp->data, &depend)) {
|
||||
continue;
|
||||
|
@ -2280,17 +2295,9 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
|||
}
|
||||
}
|
||||
/* splice out this entry from requiredby */
|
||||
last = list_last(depinfo->requiredby);
|
||||
for(j = depinfo->requiredby; j; j = j->next) {
|
||||
if(!strcmp((char*)j->data, info->name)) {
|
||||
if(j == depinfo->requiredby) {
|
||||
depinfo->requiredby = j->next;
|
||||
}
|
||||
if(j->prev) j->prev->next = j->next;
|
||||
if(j->next) j->next->prev = j->prev;
|
||||
/* free the spliced node */
|
||||
j->prev = j->next = NULL;
|
||||
list_free(j);
|
||||
depinfo->requiredby = list_remove(depinfo->requiredby, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2693,7 +2700,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
|
|||
targ = list_add(targ, syncpkg->pkg);
|
||||
deps = checkdeps(local, PM_ADD, targ);
|
||||
targ->data = NULL;
|
||||
list_free(targ);
|
||||
FREELIST(targ);
|
||||
for(i = deps; i; i = i->next) {
|
||||
int found = 0;
|
||||
depmissing_t *miss = (depmissing_t*)i->data;
|
||||
|
@ -2737,7 +2744,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
|
|||
sync->pkg->reason = REASON_DEPEND;
|
||||
sync->dbs = dbs;
|
||||
}
|
||||
list_free(provides);
|
||||
FREELIST(provides);
|
||||
}
|
||||
if(!found) {
|
||||
fprintf(stderr, "error: cannot resolve dependencies for \"%s\":\n", miss->target);
|
||||
|
@ -2753,6 +2760,8 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
|
|||
}
|
||||
if(found) {
|
||||
/* this dep is already in the target list */
|
||||
FREEPKG(sync->pkg);
|
||||
FREE(sync);
|
||||
continue;
|
||||
}
|
||||
vprint("resolving %s\n", sync->pkg->name);
|
||||
|
@ -2764,15 +2773,41 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
|
|||
}
|
||||
}
|
||||
if(!found) {
|
||||
list_add(trail, sync);
|
||||
if(resolvedeps(local, databases, sync, list, trail)) {
|
||||
/* check pmo_ignorepkg and pmo_s_ignore to make sure we haven't pulled in
|
||||
* something we're not supposed to.
|
||||
*/
|
||||
int usedep = 1;
|
||||
found = 0;
|
||||
for(j = pmo_ignorepkg; j && !found; j = j->next) {
|
||||
if(!strcmp(j->data, sync->pkg->name)) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
for(j = pmo_s_ignore; j && !found; j = j->next) {
|
||||
if(!strcmp(j->data, sync->pkg->name)) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if(found) {
|
||||
usedep = yesno("%s requires %s, but it is in IgnorePkg. Install anyway? [Y/n] ",
|
||||
miss->target, sync->pkg->name);
|
||||
}
|
||||
if(usedep) {
|
||||
trail = list_add(trail, sync);
|
||||
if(resolvedeps(local, databases, sync, list, trail)) {
|
||||
return(1);
|
||||
}
|
||||
vprint("adding %s-%s\n", sync->pkg->name, sync->pkg->version);
|
||||
list = list_add(list, sync);
|
||||
} else {
|
||||
fprintf(stderr, "error: cannot resolve dependencies for \"%s\"\n", miss->target);
|
||||
return(1);
|
||||
}
|
||||
vprint("adding %s-%s\n", sync->pkg->name, sync->pkg->version);
|
||||
list_add(list, sync);
|
||||
} else {
|
||||
/* cycle detected -- skip it */
|
||||
vprint("dependency cycle detected: %s\n", sync->pkg->name);
|
||||
FREEPKG(sync->pkg);
|
||||
FREE(sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2820,6 +2855,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
}
|
||||
if(is_pkgin(p, targets)) {
|
||||
/* this package is also in the upgrade list, so don't worry about it */
|
||||
FREEPKG(p);
|
||||
continue;
|
||||
}
|
||||
for(k = p->depends; k && !found; k = k->next) {
|
||||
|
@ -2836,9 +2872,11 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
PMList *provides = whatprovides(db, depend.name);
|
||||
if(provides == NULL) {
|
||||
/* not found */
|
||||
FREEPKG(p);
|
||||
continue;
|
||||
}
|
||||
/* we found an installed package that provides depend.name */
|
||||
FREELIST(provides);
|
||||
}
|
||||
found = 0;
|
||||
if(depend.mod == DEP_ANY) {
|
||||
|
@ -2870,8 +2908,9 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
baddeps = list_add(baddeps, miss);
|
||||
}
|
||||
}
|
||||
FREEPKG(p);
|
||||
}
|
||||
freepkg(oldpkg);
|
||||
FREEPKG(oldpkg);
|
||||
}
|
||||
}
|
||||
if(op == PM_ADD || op == PM_UPGRADE) {
|
||||
|
@ -2984,6 +3023,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
}
|
||||
}
|
||||
}
|
||||
FREEPKG(info);
|
||||
}
|
||||
|
||||
/* PROVIDES -- check to see if another package already provides what
|
||||
|
@ -3084,7 +3124,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
/* wtf */
|
||||
fprintf(stderr, "data error: %s supposedly provides %s, but it was not found in db\n",
|
||||
(char*)k->data, depend.name);
|
||||
list_free(k);
|
||||
FREELIST(k);
|
||||
continue;
|
||||
}
|
||||
if(depend.mod == DEP_ANY) {
|
||||
|
@ -3108,8 +3148,9 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
|||
}
|
||||
FREE(ver);
|
||||
}
|
||||
FREEPKG(p);
|
||||
FREELIST(k);
|
||||
}
|
||||
list_free(k);
|
||||
}
|
||||
/* else if still not found... */
|
||||
if(!found) {
|
||||
|
@ -3255,6 +3296,9 @@ int runscriptlet(char *installfn, char *script, char *ver, char *oldver)
|
|||
|
||||
if(!grep(scriptfn, script)) {
|
||||
/* script not found in scriptlet file */
|
||||
if(strlen(tmpdir) && rmrf(tmpdir)) {
|
||||
fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -3289,39 +3333,40 @@ int parseargs(int op, int argc, char **argv)
|
|||
static struct option opts[] =
|
||||
{
|
||||
{"add", no_argument, 0, 'A'},
|
||||
{"remove", no_argument, 0, 'R'},
|
||||
{"upgrade", no_argument, 0, 'U'},
|
||||
{"resolve", no_argument, 0, 'D'}, /* used by 'makepkg -s' */
|
||||
{"freshen", no_argument, 0, 'F'},
|
||||
{"query", no_argument, 0, 'Q'},
|
||||
{"remove", no_argument, 0, 'R'},
|
||||
{"sync", no_argument, 0, 'S'},
|
||||
{"deptest", no_argument, 0, 'T'},
|
||||
{"vertest", no_argument, 0, 'Y'},
|
||||
{"resolve", no_argument, 0, 'D'},
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"dbpath", required_argument, 0, 'b'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"deptest", no_argument, 0, 'T'}, /* used by makepkg */
|
||||
{"upgrade", no_argument, 0, 'U'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"search", no_argument, 0, 's'},
|
||||
{"vertest", no_argument, 0, 'Y'}, /* does the same as the 'vercmp' binary */
|
||||
{"dbpath", required_argument, 0, 'b'},
|
||||
{"clean", no_argument, 0, 'c'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"cascade", no_argument, 0, 'c'},
|
||||
{"nodeps", no_argument, 0, 'd'},
|
||||
{"orphans", no_argument, 0, 'e'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"groups", no_argument, 0, 'g'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"info", no_argument, 0, 'i'},
|
||||
{"dbonly", no_argument, 0, 'k'},
|
||||
{"list", no_argument, 0, 'l'},
|
||||
{"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'},
|
||||
{"downloadonly", no_argument, 0, 'w'},
|
||||
{"print-uris", no_argument, 0, 'p'},
|
||||
{"refresh", no_argument, 0, 'y'},
|
||||
{"dbonly", no_argument, 0, 'k'},
|
||||
{"cascade", no_argument, 0, 'c'},
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"search", no_argument, 0, 's'},
|
||||
{"recursive", no_argument, 0, 's'},
|
||||
{"groups", no_argument, 0, 'g'},
|
||||
{"sysupgrade", no_argument, 0, 'u'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"downloadonly", no_argument, 0, 'w'},
|
||||
{"refresh", no_argument, 0, 'y'},
|
||||
{"noconfirm", no_argument, 0, 1000},
|
||||
{"config", required_argument, 0, 1001},
|
||||
{"ignore", required_argument, 0, 1002},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -3333,6 +3378,7 @@ int parseargs(int op, int argc, char **argv)
|
|||
case 0: break;
|
||||
case 1000: pmo_noconfirm = 1; break;
|
||||
case 1001: strcpy(pmo_configfile, optarg); break;
|
||||
case 1002: pmo_s_ignore = list_add(pmo_s_ignore, strdup(optarg)); 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;
|
||||
|
@ -3469,6 +3515,8 @@ int parseconfig(char *configfile)
|
|||
} else if(!strcmp(key, "USESYSLOG")) {
|
||||
pmo_usesyslog = 1;
|
||||
vprint("config: usesyslog\n");
|
||||
} else if(!strcmp(key, "ILOVECANDY")) {
|
||||
pmo_chomp = 1;
|
||||
} else {
|
||||
fprintf(stderr, "config: line %d: syntax error\n", linenum);
|
||||
return(1);
|
||||
|
@ -3691,6 +3739,7 @@ void usage(int op, char *myname)
|
|||
printf(" -u, --sysupgrade upgrade all packages that are out of date\n");
|
||||
printf(" -w, --downloadonly download packages but do not install/upgrade anything\n");
|
||||
printf(" -y, --refresh download fresh package databases from the server\n");
|
||||
printf(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n");
|
||||
}
|
||||
printf(" --config <path> set an alternate configuration file\n");
|
||||
printf(" --noconfirm do not ask for any confirmation\n");
|
||||
|
@ -3712,20 +3761,6 @@ void version(void)
|
|||
printf(" the terms of the GNU General Public License\n\n");
|
||||
}
|
||||
|
||||
/* Check verbosity option and, if set, print the
|
||||
* string to stdout
|
||||
*/
|
||||
void vprint(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
if(pmo_verbose) {
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a message to stderr, and (optionally) syslog and/or a logfile */
|
||||
void logaction(FILE *fp, char *fmt, ...)
|
||||
{
|
||||
|
|
17
src/pacman.h
17
src/pacman.h
|
@ -21,22 +21,6 @@
|
|||
#ifndef _PAC_PACMAN_H
|
||||
#define _PAC_PACMAN_H
|
||||
|
||||
#ifndef PACVER
|
||||
#define PACVER "2.9.2"
|
||||
#endif
|
||||
|
||||
#ifndef PKGDIR
|
||||
#define PKGDIR "var/lib/pacman"
|
||||
#endif
|
||||
|
||||
#ifndef PACCONF
|
||||
#define PACCONF "/etc/pacman.conf"
|
||||
#endif
|
||||
|
||||
#ifndef CACHEDIR
|
||||
#define CACHEDIR "var/cache/pacman/pkg"
|
||||
#endif
|
||||
|
||||
/* Operations */
|
||||
#define PM_MAIN 1
|
||||
#define PM_ADD 2
|
||||
|
@ -69,7 +53,6 @@ int parseconfig(char *configfile);
|
|||
void usage(int op, char *myname);
|
||||
void version(void);
|
||||
|
||||
void vprint(char *fmt, ...);
|
||||
void logaction(FILE *fp, char *fmt, ...);
|
||||
char* buildstring(PMList *strlist);
|
||||
int yesno(char* fmt, ...);
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include <sys/time.h>
|
||||
#include <ftplib.h>
|
||||
/* pacman */
|
||||
#include "pacconf.h"
|
||||
#include "list.h"
|
||||
#include "package.h"
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
#include "pacsync.h"
|
||||
#include "pacman.h"
|
||||
|
||||
/* progress bar */
|
||||
static int log_progress(netbuf *ctl, int xfered, void *arg);
|
||||
|
@ -52,6 +52,7 @@ extern char *pmo_xfercommand;
|
|||
|
||||
extern unsigned short pmo_proxyport;
|
||||
extern unsigned short pmo_nopassiveftp;
|
||||
extern unsigned short pmo_chomp;
|
||||
|
||||
/* sync servers */
|
||||
extern PMList *pmc_syncs;
|
||||
|
@ -205,7 +206,7 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
|
|||
char *host;
|
||||
unsigned port;
|
||||
host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
|
||||
port = (pmo_proxyhost) ? pmo_proxyport : 80;
|
||||
port = (pmo_proxyport) ? pmo_proxyport : 80;
|
||||
if(strchr(host, ':')) {
|
||||
vprint("connecting to %s\n", host);
|
||||
} else {
|
||||
|
@ -306,7 +307,7 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
|
|||
if(ptr && (ptr-fn) < 24) {
|
||||
sync_fnm[ptr-fn] = '\0';
|
||||
}
|
||||
ptr = strstr(fn, ".pkg.tar.gz");
|
||||
ptr = strstr(fn, PKGEXT);
|
||||
if(ptr && (ptr-fn) < 24) {
|
||||
sync_fnm[ptr-fn] = '\0';
|
||||
}
|
||||
|
@ -469,6 +470,11 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
|
|||
int i, cur;
|
||||
struct timeval t1;
|
||||
float timediff;
|
||||
/* a little hard to conceal easter eggs in open-source software, but
|
||||
* they're still fun. ;)
|
||||
*/
|
||||
static unsigned short mouth;
|
||||
static unsigned int lastcur = 0;
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
if(xfered+offset == fsz) {
|
||||
|
@ -501,13 +507,39 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
|
|||
printf(" %s [", sync_fnm);
|
||||
cur = (int)((maxcols-64)*pct/100);
|
||||
for(i = 0; i < maxcols-64; i++) {
|
||||
(i < cur) ? printf("#") : printf(" ");
|
||||
if(pmo_chomp) {
|
||||
if(i < cur) {
|
||||
printf("-");
|
||||
} else {
|
||||
if(i == cur) {
|
||||
if(lastcur == cur) {
|
||||
if(mouth) {
|
||||
printf("\033[1;33mC\033[m");
|
||||
} else {
|
||||
printf("\033[1;33mc\033[m");
|
||||
}
|
||||
} else {
|
||||
mouth = mouth == 1 ? 0 : 1;
|
||||
if(mouth) {
|
||||
printf("\033[1;33mC\033[m");
|
||||
} else {
|
||||
printf("\033[1;33mc\033[m");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("\033[0;37m*\033[m");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(i < cur) ? printf("#") : printf(" ");
|
||||
}
|
||||
}
|
||||
if(rate > 1000) {
|
||||
printf("] %3d%% %6dK %6.0fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
|
||||
} else {
|
||||
printf("] %3d%% %6dK %6.1fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
|
||||
}
|
||||
lastcur = cur;
|
||||
fflush(stdout);
|
||||
return(1);
|
||||
}
|
||||
|
|
195
src/strhash.c
Normal file
195
src/strhash.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* evtgen string hash functions.
|
||||
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
|
||||
|
||||
This file is part of evtgen.
|
||||
|
||||
evtgen 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
evtgen 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 evtgen; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
|
||||
*
|
||||
* Modified for usage in Pacman.
|
||||
*/
|
||||
|
||||
/*
|
||||
** strhash.c -- string hash utility functions
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "list.h"
|
||||
#include "strhash.h"
|
||||
|
||||
void
|
||||
strhash_add_list(strhash_t *hash, PMList* list)
|
||||
{
|
||||
for(; list; list = list->next)
|
||||
strhash_add(hash, list->data, NULL);
|
||||
}
|
||||
|
||||
strhash_t *
|
||||
new_strhash(size_t hsize)
|
||||
{
|
||||
strhash_t *h;
|
||||
|
||||
MALLOC(h, sizeof (strhash_t));
|
||||
h->size = hsize;
|
||||
h->elmts = 0;
|
||||
h->hash = DEFAULT_STRHASH_FUNCTION;
|
||||
MALLOC(h->htable, hsize * sizeof (strhash_elmt_t *));
|
||||
memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *));
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
void
|
||||
clear_strhash(strhash_t *hash)
|
||||
{
|
||||
int i;
|
||||
strhash_elmt_t *tmp;
|
||||
strhash_elmt_t *tmp_next;
|
||||
|
||||
for (i = 0; i < hash->size; i++)
|
||||
{
|
||||
tmp = hash->htable[i];
|
||||
while (tmp)
|
||||
{
|
||||
tmp_next = tmp->next;
|
||||
free(tmp);
|
||||
tmp = tmp_next;
|
||||
}
|
||||
}
|
||||
hash->elmts = 0;
|
||||
memset(hash->htable, 0, hash->size * sizeof (void *));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_strhash(strhash_t *hash)
|
||||
{
|
||||
int i;
|
||||
strhash_elmt_t *tmp;
|
||||
strhash_elmt_t *tmp_next;
|
||||
|
||||
for (i = 0; i < hash->size; i++)
|
||||
{
|
||||
tmp = hash->htable[i];
|
||||
while (tmp)
|
||||
{
|
||||
tmp_next = tmp->next;
|
||||
free(tmp);
|
||||
tmp = tmp_next;
|
||||
}
|
||||
}
|
||||
|
||||
free(hash->htable);
|
||||
free(hash);
|
||||
}
|
||||
|
||||
void
|
||||
strhash_add(strhash_t *hash, char *key, char *data)
|
||||
{
|
||||
strhash_elmt_t *elmt;
|
||||
unsigned long hcode;
|
||||
|
||||
MALLOC(elmt, sizeof (strhash_elmt_t));
|
||||
elmt->key = key;
|
||||
elmt->data = data;
|
||||
|
||||
hcode = hash->hash(key) % hash->size;
|
||||
elmt->next = hash->htable[hcode];
|
||||
hash->htable[hcode] = elmt;
|
||||
hash->elmts++;
|
||||
}
|
||||
|
||||
/* 1: Yes, the key exists in the hash table.
|
||||
* 0: No, its not here.
|
||||
*/
|
||||
|
||||
int
|
||||
strhash_isin(strhash_t *hash, char* key)
|
||||
{
|
||||
strhash_elmt_t *elmt;
|
||||
|
||||
elmt = hash->htable[hash->hash(key) % hash->size];
|
||||
for (; elmt; elmt = elmt->next)
|
||||
{
|
||||
if (!strcmp(key, elmt->key))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char*
|
||||
strhash_get(strhash_t *hash, char* key)
|
||||
{
|
||||
strhash_elmt_t *elmt;
|
||||
|
||||
elmt = hash->htable[hash->hash(key) % hash->size];
|
||||
for (; elmt; elmt = elmt->next)
|
||||
{
|
||||
if (!strcmp(key, elmt->key))
|
||||
return elmt->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** fast hash function samples
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
strhash_pjw(char *key)
|
||||
{
|
||||
unsigned long h;
|
||||
unsigned long g;
|
||||
|
||||
h = 0;
|
||||
while (*key)
|
||||
{
|
||||
h = (h << 4) + *key++;
|
||||
if ((g = h & 0xF0000000U) != 0)
|
||||
{
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
int
|
||||
strhash_collide_count(strhash_t *hash)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < hash->size; i++)
|
||||
{
|
||||
strhash_elmt_t *tmp;
|
||||
|
||||
for (tmp = hash->htable[i]; tmp; tmp = tmp->next)
|
||||
if (tmp->next)
|
||||
count++;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
65
src/strhash.h
Normal file
65
src/strhash.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* evtgen string hash headers.
|
||||
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
|
||||
|
||||
This file is part of evtgen.
|
||||
|
||||
evtgen 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
evtgen 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 evtgen; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
|
||||
*
|
||||
* Modified for usage in Pacman.
|
||||
*/
|
||||
|
||||
/*
|
||||
** strhash.h --
|
||||
*/
|
||||
|
||||
#ifndef STRHASH_H
|
||||
#define STRHASH_H
|
||||
|
||||
#define DEFAULT_STRHASH_FUNCTION strhash_pjw
|
||||
|
||||
typedef struct strhash_elmt_s strhash_elmt_t;
|
||||
struct strhash_elmt_s
|
||||
{
|
||||
char *key;
|
||||
char *data;
|
||||
strhash_elmt_t *next;
|
||||
};
|
||||
|
||||
typedef unsigned long (*strhashfunc_t)(char *key);
|
||||
|
||||
typedef struct strhash_s strhash_t;
|
||||
struct strhash_s
|
||||
{
|
||||
strhash_elmt_t **htable;
|
||||
size_t size;
|
||||
int elmts;
|
||||
strhashfunc_t hash;
|
||||
};
|
||||
|
||||
void strhash_add_list(strhash_t *hash, PMList* list);
|
||||
strhash_t *new_strhash(size_t hsize);
|
||||
void free_strhash(strhash_t *hash);
|
||||
void clear_strhash(strhash_t *hash);
|
||||
void strhash_add(strhash_t *hash, char *key, char *data);
|
||||
int strhash_isin(strhash_t *hash, char* key);
|
||||
char* strhash_get(strhash_t *hash, char* key);
|
||||
int strhash_collide_count(strhash_t *hash);
|
||||
|
||||
unsigned long strhash_pjw(char *key);
|
||||
|
||||
#endif /* STRHASH_H */
|
16
src/util.c
16
src/util.c
|
@ -32,6 +32,22 @@
|
|||
#include <libtar.h>
|
||||
#include "util.h"
|
||||
|
||||
extern unsigned short pmo_verbose;
|
||||
|
||||
/* Check verbosity option and, if set, print the
|
||||
* string to stdout
|
||||
*/
|
||||
void vprint(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
if(pmo_verbose) {
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */
|
||||
long gzopen_frontend(char *pathname, int oflags, int mode)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#define FREE(p) { if (p) { free(p); (p)= NULL; }}
|
||||
|
||||
void vprint(char *fmt, ...);
|
||||
long gzopen_frontend(char *pathname, int oflags, int mode);
|
||||
int unpack(char *archive, const char *prefix, const char *fn);
|
||||
int copyfile(char *src, char *dest);
|
||||
|
|
Loading…
Add table
Reference in a new issue