Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm
diff options
context:
space:
mode:
authorAaron Griffin <aaron@archlinux.org>2006-10-15 19:31:03 +0000
committerAaron Griffin <aaron@archlinux.org>2006-10-15 19:31:03 +0000
commitd37ad048732fbcef38aec001993553896dbe4198 (patch)
treec80472214aae0cd94c32ac00d613d38d51bc1adf /lib/libalpm
parent83381bd21748d79f46247fab17877bc5c440a8de (diff)
Merged frugalware changes (too many to list). Also added some config file
handling changes (support [sections] to carry over to included files - this helps with backwards compatibility with existing pacman config files)
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/Makefile.am11
-rw-r--r--lib/libalpm/add.c294
-rw-r--r--lib/libalpm/alpm.c609
-rw-r--r--lib/libalpm/alpm.h136
-rw-r--r--lib/libalpm/backup.c11
-rw-r--r--lib/libalpm/be_files.c156
-rw-r--r--lib/libalpm/conflict.c18
-rw-r--r--lib/libalpm/db.c98
-rw-r--r--lib/libalpm/db.h13
-rw-r--r--lib/libalpm/deps.c92
-rw-r--r--lib/libalpm/deps.h4
-rw-r--r--lib/libalpm/error.c28
-rw-r--r--lib/libalpm/error.h4
-rw-r--r--lib/libalpm/handle.c136
-rw-r--r--lib/libalpm/handle.h19
-rw-r--r--lib/libalpm/md5.c40
-rw-r--r--lib/libalpm/md5.h11
-rw-r--r--lib/libalpm/md5driver.c10
-rw-r--r--lib/libalpm/package.c119
-rw-r--r--lib/libalpm/package.h15
-rw-r--r--lib/libalpm/po/LINGUAS3
-rw-r--r--lib/libalpm/po/Makefile.in.in5
-rw-r--r--lib/libalpm/po/Makevars4
-rw-r--r--lib/libalpm/po/POTFILES.in1
-rw-r--r--lib/libalpm/po/libalpm.pot746
-rw-r--r--lib/libalpm/remove.c51
-rw-r--r--lib/libalpm/sync.c297
-rw-r--r--lib/libalpm/sync.h4
-rw-r--r--lib/libalpm/trans.c16
-rw-r--r--lib/libalpm/trans.h17
-rw-r--r--lib/libalpm/util.c262
-rw-r--r--lib/libalpm/util.h33
-rw-r--r--lib/libalpm/versioncmp.c106
-rw-r--r--lib/libalpm/versioncmp.h8
34 files changed, 2604 insertions, 773 deletions
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am
index 5151f4dd..a656d7e6 100644
--- a/lib/libalpm/Makefile.am
+++ b/lib/libalpm/Makefile.am
@@ -1,6 +1,7 @@
AUTOMAKE_OPTIONS = gnu
DEFINES = -pedantic -D_GNU_SOURCE
-AM_CFLAGS = $(DEFINES)
+AM_CFLAGS = $(DEFINES) \
+ -I$(top_srcdir)/lib/libftp
SUBDIRS = po
localedir = $(datadir)/locale
@@ -8,6 +9,7 @@ DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
TARGETS = md5driver.c \
md5.c \
+ sha1.c \
util.c \
list.c \
log.c \
@@ -26,8 +28,9 @@ TARGETS = md5driver.c \
remove.c \
sync.c \
handle.c \
- alpm.c
-TARGETS += be_files.c
+ server.c \
+ alpm.c \
+ be_files.c
lib_LTLIBRARIES = libalpm.la
@@ -36,6 +39,7 @@ include_HEADERS = alpm.h
libalpm_la_SOURCES = $(TARGETS)
libalpm_la_LDFLAGS = -no-undefined -version-info $(PM_VERSION_INFO)
+libalpm_la_LIBADD = $(top_srcdir)/lib/libftp/libftp.la
if HAS_DOXYGEN
all: doxygen.in
@@ -44,4 +48,3 @@ doxygen.in:
doxygen Doxyfile
endif
-
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 66c36b8a..a4c5a557 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -2,6 +2,10 @@
* add.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -19,6 +23,27 @@
* USA.
*/
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__)
+#include <sys/stat.h>
+#endif
+
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__)
+#include <sys/stat.h>
+#endif
+
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__)
+#include <sys/stat.h>
+#endif
+
#include "config.h"
#include <stdlib.h>
#include <errno.h>
@@ -28,19 +53,20 @@
#include <limits.h>
#include <libintl.h>
/* pacman */
+#include "list.h"
+#include "trans.h"
#include "util.h"
#include "error.h"
-#include "list.h"
#include "cache.h"
#include "versioncmp.h"
#include "md5.h"
+#include "sha1.h"
#include "log.h"
#include "backup.h"
#include "package.h"
#include "db.h"
#include "provide.h"
#include "conflict.h"
-#include "trans.h"
#include "deps.h"
#include "add.h"
#include "remove.h"
@@ -199,6 +225,9 @@ error:
int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
{
PMList *lp;
+ PMList *rmlist = NULL;
+ char rm_fname[PATH_MAX];
+ pmpkg_t *info = NULL;
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
@@ -209,8 +238,8 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
/* look for unsatisfied dependencies */
- _alpm_log(PM_LOG_FLOW1,_( "looking for unsatisfied dependencies"));
- lp = _alpm_checkdeps(db, trans->type, trans->packages);
+ _alpm_log(PM_LOG_FLOW1, _("looking for unsatisfied dependencies"));
+ lp = _alpm_checkdeps(trans, db, trans->type, trans->packages);
if(lp != NULL) {
if(data) {
*data = lp;
@@ -242,6 +271,45 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
}
+ /* Cleaning up
+ */
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_START, NULL, NULL);
+ _alpm_log(PM_LOG_FLOW1, _("cleaning up"));
+ for (lp=trans->packages; lp!=NULL; lp=lp->next) {
+ info=(pmpkg_t *)lp->data;
+ for (rmlist=info->removes; rmlist!=NULL; rmlist=rmlist->next) {
+ snprintf(rm_fname, PATH_MAX, "%s%s", handle->root, (char *)rmlist->data);
+ remove(rm_fname);
+ }
+ }
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_DONE, NULL, NULL);
+
+ /* Cleaning up
+ */
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_START, NULL, NULL);
+ _alpm_log(PM_LOG_FLOW1, _("cleaning up"));
+ for (lp=trans->packages; lp!=NULL; lp=lp->next) {
+ info=(pmpkg_t *)lp->data;
+ for (rmlist=info->removes; rmlist!=NULL; rmlist=rmlist->next) {
+ snprintf(rm_fname, PATH_MAX, "%s%s", handle->root, (char *)rmlist->data);
+ remove(rm_fname);
+ }
+ }
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_DONE, NULL, NULL);
+
+ /* Cleaning up
+ */
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_START, NULL, NULL);
+ _alpm_log(PM_LOG_FLOW1, _("cleaning up"));
+ for (lp=trans->packages; lp!=NULL; lp=lp->next) {
+ info=(pmpkg_t *)lp->data;
+ for (rmlist=info->removes; rmlist!=NULL; rmlist=rmlist->next) {
+ snprintf(rm_fname, PATH_MAX, "%s%s", handle->root, (char *)rmlist->data);
+ remove(rm_fname);
+ }
+ }
+ EVENT(trans, PM_TRANS_EVT_CLEANUP_DONE, NULL, NULL);
+
/* Check for file conflicts
*/
if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {
@@ -267,15 +335,24 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
}
+#ifndef __sun__
+ if(_alpm_check_freespace(trans, data) == -1) {
+ /* pm_errno is set by check_freespace */
+ return(-1);
+ }
+#endif
+
return(0);
}
int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
{
- int i, ret = 0, errors = 0;
+ int i, ret = 0, errors = 0, needdisp = 0;
+ double percent;
register struct archive *archive;
struct archive_entry *entry;
- char expath[PATH_MAX];
+ char expath[PATH_MAX], cwd[PATH_MAX] = "", *what;
+ unsigned char cb_state;
time_t t;
PMList *targ, *lp;
@@ -304,7 +381,12 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
pmpkg_t *local = _alpm_db_get_pkgfromcache(db, info->name);
if(local) {
EVENT(trans, PM_TRANS_EVT_UPGRADE_START, info, NULL);
+ cb_state = PM_TRANS_PROGRESS_UPGRADE_START;
_alpm_log(PM_LOG_FLOW1, _("upgrading package %s-%s"), info->name, info->version);
+ if((what = (char *)malloc(strlen(info->name)+1)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ STRNCPY(what, info->name, strlen(info->name)+1);
/* we'll need to save some record for backup checks later */
oldpkg = _alpm_pkg_new(local->name, local->version);
@@ -314,6 +396,8 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
_alpm_db_read(db, INFRQ_FILES, local);
}
oldpkg->backup = _alpm_list_strdup(local->backup);
+ strncpy(oldpkg->name, local->name, PKG_NAME_LEN);
+ strncpy(oldpkg->version, local->version, PKG_VERSION_LEN);
}
/* copy over the install reason */
@@ -325,7 +409,8 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
/* pre_upgrade scriptlet */
if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
- _alpm_runscriptlet(handle->root, info->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
+ _alpm_runscriptlet(handle->root, info->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL,
+ trans);
}
if(oldpkg) {
@@ -335,7 +420,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
if(tr == NULL) {
RET_ERR(PM_ERR_TRANS_ABORT, -1);
}
- if(_alpm_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags, NULL, NULL) == -1) {
+ if(_alpm_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags, NULL, NULL, NULL) == -1) {
FREETRANS(tr);
RET_ERR(PM_ERR_TRANS_ABORT, -1);
}
@@ -359,11 +444,16 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
}
if(!pmo_upgrade) {
EVENT(trans, PM_TRANS_EVT_ADD_START, info, NULL);
+ cb_state = PM_TRANS_PROGRESS_ADD_START;
_alpm_log(PM_LOG_FLOW1, _("adding package %s-%s"), info->name, info->version);
+ if((what = (char *)malloc(strlen(info->name)+1)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ STRNCPY(what, info->name, strlen(info->name)+1);
/* pre_install scriptlet */
if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
- _alpm_runscriptlet(handle->root, info->data, "pre_install", info->version, NULL);
+ _alpm_runscriptlet(handle->root, info->data, "pre_install", info->version, NULL, trans);
}
} else {
_alpm_log(PM_LOG_FLOW1, _("adding new package %s-%s"), info->name, info->version);
@@ -372,35 +462,62 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
_alpm_log(PM_LOG_FLOW1, _("extracting files"));
- /* Extract the .tar.gz package */
- if((archive = archive_read_new()) == NULL) {
+ /* Extract the package */
+ if ((archive = archive_read_new ()) == NULL)
RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
- }
- archive_read_support_compression_all(archive);
- archive_read_support_format_all(archive);
- if(archive_read_open_file(archive, info->data, 10240) != ARCHIVE_OK) {
+ archive_read_support_compression_all (archive);
+ archive_read_support_format_all (archive);
+
+ if (archive_read_open_file (archive, info->data, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
RET_ERR(PM_ERR_PKG_OPEN, -1);
}
+ /* save the cwd so we can restore it later */
+ if(getcwd(cwd, PATH_MAX) == NULL) {
+ _alpm_log(PM_LOG_ERROR, _("could not get current working directory"));
+ /* in case of error, cwd content is undefined: so we set it to something */
+ cwd[0] = 0;
+ }
+
+ /* libarchive requires this for extracting hard links */
chdir(handle->root);
- for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
+
+ for(i = 0; archive_read_next_header (archive, &entry) == ARCHIVE_OK; i++) {
int nb = 0;
int notouch = 0;
char *md5_orig = NULL;
+ char *sha1_orig = NULL;
char pathname[PATH_MAX];
struct stat buf;
- STRNCPY(pathname, archive_entry_pathname(entry), PATH_MAX);
+ STRNCPY(pathname, archive_entry_pathname (entry), PATH_MAX);
+
+ if (info->size != 0)
+ percent = (double)archive_position_uncompressed(archive) / info->size;
+ if (needdisp == 0) {
+ PROGRESS(trans, cb_state, what, (int)(percent * 100), _alpm_list_count(trans->packages), (_alpm_list_count(trans->packages) - _alpm_list_count(targ) +1));
+ }
if(!strcmp(pathname, ".PKGINFO") || !strcmp(pathname, ".FILELIST")) {
- archive_read_data_skip(archive);
+ archive_read_data_skip (archive);
continue;
}
- if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL")) {
- /* the install script goes inside the db */
- snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
+ /*if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL")) {
+ * the install script goes inside the db
+ * snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version); */
+ if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL") ||
+ !strcmp(pathname, ".CHANGELOG")) {
+ if(!strcmp(pathname, ".CHANGELOG")) {
+ /* the changelog goes inside the db */
+ snprintf(expath, PATH_MAX, "%s/%s-%s/changelog", db->path,
+ info->name, info->version);
+ } else {
+ /* the install script goes inside the db */
+ snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path,
+ info->name, info->version);
+ }
} else {
/* build the new pathname relative to handle->root */
snprintf(expath, PATH_MAX, "%s%s", handle->root, pathname);
@@ -413,7 +530,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
*/
if(_alpm_list_is_strin(pathname, handle->noextract)) {
alpm_logaction(_("notice: %s is in NoExtract -- skipping extraction"), pathname);
- archive_read_data_skip(archive);
+ archive_read_data_skip (archive);
continue;
}
@@ -427,7 +544,8 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
} else {
/* op == PM_TRANS_TYPE_UPGRADE */
md5_orig = _alpm_needbackup(pathname, oldpkg->backup);
- if(md5_orig) {
+ sha1_orig = _alpm_needbackup(pathname, oldpkg->backup);
+ if(md5_orig || sha1_orig) {
nb = 1;
}
}
@@ -437,98 +555,128 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
if(nb) {
char *temp;
char *md5_local, *md5_pkg;
+ char *sha1_local, *sha1_pkg;
int fd;
/* extract the package's version to a temporary file and md5 it */
temp = strdup("/tmp/alpm_XXXXXX");
fd = mkstemp(temp);
- archive_entry_set_pathname(entry, temp);
- if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
+
+ archive_entry_set_pathname (entry, temp);
+
+ if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
alpm_logaction(_("could not extract %s (%s)"), pathname, strerror(errno));
errors++;
unlink(temp);
FREE(temp);
FREE(md5_orig);
+ FREE(sha1_orig);
close(fd);
continue;
}
- md5_local = MDFile(expath);
- md5_pkg = MDFile(temp);
- /* append the new md5 hash to it's respective entry in info->backup
+ md5_local = _alpm_MDFile(expath);
+ md5_pkg = _alpm_MDFile(temp);
+ sha1_local = _alpm_SHAFile(expath);
+ sha1_pkg = _alpm_SHAFile(temp);
+ /* append the new md5 or sha1 hash to it's respective entry in info->backup
* (it will be the new orginal)
*/
for(lp = info->backup; lp; lp = lp->next) {
+ char *fn;
char *file = lp->data;
- if(!file) {
- continue;
- }
+
+ if(!file) continue;
if(!strcmp(file, pathname)) {
- char *fn;
+ if(info->sha1sum != NULL && info->sha1sum != '\0') {
/* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */
- fn = (char *)malloc(strlen(file)+34);
- if(fn == NULL) {
+ if((fn = (char *)malloc(strlen(file)+34)) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
sprintf(fn, "%s\t%s", file, md5_pkg);
FREE(file);
lp->data = fn;
+ } else {
+ /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */
+ if((fn = (char *)malloc(strlen(file)+43)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ sprintf(fn, "%s\t%s", file, sha1_pkg);
+ FREE(file);
+ lp->data = fn;
+ }
}
}
+ if (info->sha1sum != NULL && info->sha1sum != '\0') {
_alpm_log(PM_LOG_DEBUG, _("checking md5 hashes for %s"), pathname);
_alpm_log(PM_LOG_DEBUG, _("current: %s"), md5_local);
_alpm_log(PM_LOG_DEBUG, _("new: %s"), md5_pkg);
if(md5_orig) {
_alpm_log(PM_LOG_DEBUG, _("original: %s"), md5_orig);
}
+ } else {
+ _alpm_log(PM_LOG_DEBUG, _("checking sha1 hashes for %s"), pathname);
+ _alpm_log(PM_LOG_DEBUG, _("current: %s"), sha1_local);
+ _alpm_log(PM_LOG_DEBUG, _("new: %s"), sha1_pkg);
+ if(sha1_orig) {
+ _alpm_log(PM_LOG_DEBUG, _("original: %s"), sha1_orig);
+ }
+ }
if(!pmo_upgrade) {
/* PM_ADD */
- /* if a file already exists with a different md5 hash,
+ /* if a file already exists with a different md5 or sha1 hash,
* then we rename it to a .pacorig extension and continue */
- if(strcmp(md5_local, md5_pkg)) {
+ if(strcmp(md5_local, md5_pkg) || strcmp(sha1_local, sha1_pkg)) {
char newpath[PATH_MAX];
snprintf(newpath, PATH_MAX, "%s.pacorig", expath);
if(rename(expath, newpath)) {
- archive_entry_set_pathname(entry, expath);
+ archive_entry_set_pathname (entry, expath);
_alpm_log(PM_LOG_ERROR, _("could not rename %s (%s)"), pathname, strerror(errno));
alpm_logaction(_("error: could not rename %s (%s)"), expath, strerror(errno));
}
- archive_entry_set_pathname(entry, expath);
if(_alpm_copyfile(temp, expath)) {
+ archive_entry_set_pathname (entry, expath);
_alpm_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno));
alpm_logaction(_("error: could not copy %s to %s (%s)"), temp, expath, strerror(errno));
errors++;
} else {
+ archive_entry_set_pathname (entry, expath);
_alpm_log(PM_LOG_WARNING, _("%s saved as %s.pacorig"), pathname, pathname);
alpm_logaction(_("warning: %s saved as %s"), expath, newpath);
}
}
- } else if(md5_orig) {
+ } else if(md5_orig || sha1_orig) {
/* PM_UPGRADE */
int installnew = 0;
/* the fun part */
- if(!strcmp(md5_orig, md5_local)) {
- if(!strcmp(md5_local, md5_pkg)) {
+ if(!strcmp(md5_orig, md5_local)|| !strcmp(sha1_orig, sha1_local)) {
+ if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) {
_alpm_log(PM_LOG_DEBUG, _("action: installing new file"));
installnew = 1;
} else {
_alpm_log(PM_LOG_DEBUG, _("action: installing new file"));
installnew = 1;
}
- } else if(!strcmp(md5_orig, md5_pkg)) {
+ } else if(!strcmp(md5_orig, md5_pkg) || !strcmp(sha1_orig, sha1_pkg)) {
_alpm_log(PM_LOG_DEBUG, _("action: leaving existing file in place"));
- } else if(!strcmp(md5_local, md5_pkg)) {
+ } else if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) {
_alpm_log(PM_LOG_DEBUG, _("action: installing new file"));
installnew = 1;
} else {
- _alpm_log(PM_LOG_DEBUG, _("action: leaving file in place, installing new one as .pacnew"));
- strncat(expath, ".pacnew", PATH_MAX);
- installnew = 1;
- _alpm_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew"), pathname, pathname);
- alpm_logaction(_("warning: extracting %s%s as %s"), handle->root, pathname, expath);
+ char newpath[PATH_MAX];
+ _alpm_log(PM_LOG_DEBUG, _("action: keeping current file and installing new one with .pacnew ending"));
+ installnew = 0;
+ snprintf(newpath, PATH_MAX, "%s.pacnew", expath);
+ if(_alpm_copyfile(temp, newpath)) {
+ _alpm_log(PM_LOG_ERROR, _("could not install %s as %s: %s"), expath, newpath, strerror(errno));
+ alpm_logaction(_("error: could not install %s as %s: %s"), expath, newpath, strerror(errno));
+ } else {
+ _alpm_log(PM_LOG_WARNING, _("%s installed as %s"), expath, newpath);
+ alpm_logaction(_("warning: %s installed as %s"), expath, newpath);
+ }
}
if(installnew) {
@@ -537,13 +685,16 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
_alpm_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno));
errors++;
}
- archive_entry_set_pathname(entry, expath);
+ archive_entry_set_pathname (entry, expath);
}
}
FREE(md5_local);
FREE(md5_pkg);
FREE(md5_orig);
+ FREE(sha1_local);
+ FREE(sha1_pkg);
+ FREE(sha1_orig);
unlink(temp);
FREE(temp);
close(fd);
@@ -565,15 +716,15 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
*/
unlink(expath);
}
- archive_entry_set_pathname(entry, expath);
- if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
+ archive_entry_set_pathname (entry, expath);
+ if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
_alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), expath, strerror(errno));
alpm_logaction(_("error: could not extract %s (%s)"), expath, strerror(errno));
errors++;
}
- /* calculate an md5 hash if this is in info->backup */
+ /* calculate an md5 or sha1 hash if this is in info->backup */
for(lp = info->backup; lp; lp = lp->next) {
- char *fn, *md5;
+ char *fn, *md5, *sha1;
char path[PATH_MAX];
char *file = lp->data;
@@ -581,21 +732,33 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
if(!strcmp(file, pathname)) {
_alpm_log(PM_LOG_DEBUG, _("appending backup entry"));
snprintf(path, PATH_MAX, "%s%s", handle->root, file);
- md5 = MDFile(path);
- /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */
- fn = (char *)malloc(strlen(file)+34);
- if(fn == NULL) {
- RET_ERR(PM_ERR_MEMORY, -1);
+ if (info->sha1sum != NULL && info->sha1sum != '\0') {
+ md5 = _alpm_MDFile(path);
+ /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */
+ if((fn = (char *)malloc(strlen(file)+34)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ sprintf(fn, "%s\t%s", file, md5);
+ FREE(md5);
+ } else {
+ /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */
+ sha1 = _alpm_SHAFile(path);
+ if((fn = (char *)malloc(strlen(file)+43)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ sprintf(fn, "%s\t%s", file, sha1);
+ FREE(sha1);
}
- sprintf(fn, "%s\t%s", file, md5);
- FREE(md5);
FREE(file);
lp->data = fn;
}
}
}
}
- archive_read_finish(archive);
+ if(strlen(cwd)) {
+ chdir(cwd);
+ }
+ archive_read_finish (archive);
if(errors) {
ret = 1;
@@ -682,13 +845,18 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
}
}
+ PROGRESS(trans, cb_state, what, 100, _alpm_list_count(trans->packages), (_alpm_list_count(trans->packages) - _alpm_list_count(targ) +1));
+ needdisp = 0;
+ EVENT(trans, PM_TRANS_EVT_EXTRACT_DONE, NULL, NULL);
+ FREE(what);
+
/* run the post-install script if it exists */
if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", handle->root, handle->dbpath, db->treename, info->name, info->version);
if(pmo_upgrade) {
- _alpm_runscriptlet(handle->root, pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
+ _alpm_runscriptlet(handle->root, pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL, trans);
} else {
- _alpm_runscriptlet(handle->root, pm_install, "post_install", info->version, NULL);
+ _alpm_runscriptlet(handle->root, pm_install, "post_install", info->version, NULL, trans);
}
}
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index 96d8536e..cd6beea5 100644
--- a/lib/libalpm/alpm.c
+++ b/lib/libalpm/alpm.c
@@ -2,6 +2,9 @@
* alpm.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -37,6 +40,7 @@
#include "error.h"
#include "versioncmp.h"
#include "md5.h"
+#include "sha1.h"
#include "list.h"
#include "package.h"
#include "group.h"
@@ -50,8 +54,12 @@
#include "remove.h"
#include "sync.h"
#include "handle.h"
+#include "provide.h"
+#include "server.h"
#include "alpm.h"
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
+
/* Globals */
pmhandle_t *handle = NULL;
enum __pmerrno_t pm_errno;
@@ -72,7 +80,7 @@ int alpm_initialize(char *root)
ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1));
- handle = handle_new();
+ handle = _alpm_handle_new();
if(handle == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
@@ -133,7 +141,7 @@ int alpm_set_option(unsigned char parm, unsigned long data)
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
- return(handle_set_option(handle, parm, data));
+ return(_alpm_handle_set_option(handle, parm, data));
}
/** Get the value of a library option.
@@ -147,7 +155,7 @@ int alpm_get_option(unsigned char parm, long *data)
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
- return(handle_get_option(handle, parm, data));
+ return(_alpm_handle_get_option(handle, parm, data));
}
/** @} */
@@ -158,13 +166,13 @@ int alpm_get_option(unsigned char parm, long *data)
/** Register a package database
* @param treename the name of the repository
+ * @param callback a function to be called upon new database creation
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
-pmdb_t *alpm_db_register(char *treename)
+pmdb_t *alpm_db_register(char *treename, alpm_cb_db_register callback)
{
struct stat buf;
pmdb_t *db;
- int found = 0;
char path[PATH_MAX];
/* Sanity checks */
@@ -175,21 +183,20 @@ pmdb_t *alpm_db_register(char *treename)
if(strcmp(treename, "local") == 0) {
if(handle->db_local != NULL) {
- found = 1;
+ _alpm_log(PM_LOG_WARNING, _("attempt to re-register the 'local' DB\n"));
+ RET_ERR(PM_ERR_DB_NOT_NULL, NULL);
}
} else {
PMList *i;
- for(i = handle->dbs_sync; i && !found; i = i->next) {
+ for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *sdb = i->data;
if(strcmp(treename, sdb->treename) == 0) {
- found = 1;
+ _alpm_log(PM_LOG_DEBUG, _("attempt to re-register the '%s' databse, using existing\n"), sdb->treename);
+ return sdb;
}
}
}
- if(found) {
- RET_ERR(PM_ERR_DB_NOT_NULL, NULL);
- }
-
+
_alpm_log(PM_LOG_FLOW1, _("registering database '%s'"), treename);
/* make sure the database directory exists */
@@ -203,15 +210,18 @@ pmdb_t *alpm_db_register(char *treename)
db = _alpm_db_new(handle->root, handle->dbpath, treename);
if(db == NULL) {
- return(NULL);
+ RET_ERR(PM_ERR_DB_CREATE, NULL);
}
_alpm_log(PM_LOG_DEBUG, _("opening database '%s'"), db->treename);
- if(_alpm_db_open(db, DB_O_CREATE) == -1) {
+ if(_alpm_db_open(db) == -1) {
_alpm_db_free(db);
RET_ERR(PM_ERR_DB_OPEN, NULL);
}
+ /* Only call callback on NEW registration. */
+ if(callback) callback(treename, db);
+
if(strcmp(treename, "local") == 0) {
handle->db_local = db;
} else {
@@ -271,6 +281,8 @@ int alpm_db_unregister(pmdb_t *db)
void *alpm_db_getinfo(PM_DB *db, unsigned char parm)
{
void *data = NULL;
+ char path[PATH_MAX];
+ pmserver_t *server;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
@@ -278,6 +290,16 @@ void *alpm_db_getinfo(PM_DB *db, unsigned char parm)
switch(parm) {
case PM_DB_TREENAME: data = db->treename; break;
+ case PM_DB_FIRSTSERVER:
+ server = (pmserver_t*)db->servers->data;
+ if(!strcmp(server->protocol, "file")) {
+ snprintf(path, PATH_MAX, "%s://%s", server->protocol, server->path);
+ } else {
+ snprintf(path, PATH_MAX, "%s://%s%s", server->protocol,
+ server->server, server->path);
+ }
+ data = strdup(path);
+ break;
default:
data = NULL;
}
@@ -285,14 +307,66 @@ void *alpm_db_getinfo(PM_DB *db, unsigned char parm)
return(data);
}
+/** Set the serverlist of a database.
+ * @param db database pointer
+ * @param url url of the server
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int alpm_db_setserver(pmdb_t *db, char *url)
+{
+ int found = 0;
+
+ /* Sanity checks */
+ ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
+
+ if(strcmp(db->treename, "local") == 0) {
+ if(handle->db_local != NULL) {
+ found = 1;
+ }
+ } else {
+ PMList *i;
+ for(i = handle->dbs_sync; i && !found; i = i->next) {
+ pmdb_t *sdb = i->data;
+ if(strcmp(db->treename, sdb->treename) == 0) {
+ found = 1;
+ }
+ }
+ }
+ if(!found) {
+ RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
+ }
+
+ if(url && strlen(url)) {
+ pmserver_t *server;
+ if((server = _alpm_server_new(url)) == NULL) {
+ /* pm_errno is set by _alpm_server_new */
+ return(-1);
+ }
+ db->servers = _alpm_list_add(db->servers, server);
+ _alpm_log(PM_LOG_FLOW2, _("adding new server to database '%s': protocol '%s', server '%s', path '%s'"),
+ db->treename, server->protocol, server->server, server->path);
+ } else {
+ FREELIST(db->servers);
+ _alpm_log(PM_LOG_FLOW2, _("serverlist flushed for '%s'"), db->treename);
+ }
+
+ return(0);
+}
+
/** Update a package database
+ * @param level control for checking lastupdate time
* @param db pointer to the package database to update
- * @param archive path to the new package database tarball
- * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ * @return 0 on success, > 0 on error (pm_errno is set accordingly), < 0 if up
+ * to date
*/
-int alpm_db_update(PM_DB *db, char *archive)
+int alpm_db_update(int level, PM_DB *db)
{
PMList *lp;
+ char path[PATH_MAX];
+ PMList *files = NULL;
+ char newmtime[16] = "";
+ char lastupdate[16] = "";
+ int ret;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
@@ -304,28 +378,60 @@ int alpm_db_update(PM_DB *db, char *archive)
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
}
- /* remove the old dir */
- _alpm_log(PM_LOG_FLOW2, _("flushing database %s/%s"), handle->dbpath, db->treename);
- for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
- if(_alpm_db_remove(db, lp->data) == -1) {
- if(lp->data) {
- _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s/%s"), db->treename,
- ((pmpkg_t *)lp->data)->name);
- }
- RET_ERR(PM_ERR_DB_REMOVE, -1);
+ if(level < 2) {
+ /* get the lastupdate time */
+ _alpm_db_getlastupdate(db, lastupdate);
+ if(strlen(lastupdate) == 0) {
+ _alpm_log(PM_LOG_DEBUG, _("failed to get lastupdate time for %s (no big deal)\n"), db->treename);
}
}
- /* Cache needs to be rebuild */
- _alpm_db_free_pkgcache(db);
+ /* build a one-element list */
+ snprintf(path, PATH_MAX, "%s" PM_EXT_DB, db->treename);
+ files = _alpm_list_add(files, strdup(path));
- /* uncompress the sync database */
- /* ORE
- we should not simply unpack the archive, but better parse it and
- db_write each entry (see sync_load_dbarchive to get archive content) */
- _alpm_log(PM_LOG_FLOW2, _("unpacking %s"), archive);
- if(_alpm_unpack(archive, db->path, NULL)) {
- RET_ERR(PM_ERR_SYSTEM, -1);
+ snprintf(path, PATH_MAX, "%s%s", handle->root, handle->dbpath);
+
+ ret = _alpm_downloadfiles_forreal(db->servers, path, files, lastupdate, newmtime);
+ FREELIST(files);
+ if(ret != 0) {
+ if(ret > 0) {
+ _alpm_log(PM_LOG_DEBUG, _("failed to sync db: %s [%d]\n"), alpm_strerror(ret), ret);
+ pm_errno = PM_ERR_DB_SYNC;
+ }
+ return(ret);
+ } else {
+ if(strlen(newmtime)) {
+ _alpm_log(PM_LOG_DEBUG, _("sync: new mtime for %s: %s\n"), db->treename, newmtime);
+ _alpm_db_setlastupdate(db, newmtime);
+ }
+ snprintf(path, PATH_MAX, "%s%s/%s" PM_EXT_DB, handle->root, handle->dbpath, db->treename);
+
+ /* remove the old dir */
+ _alpm_log(PM_LOG_FLOW2, _("flushing database %s/%s"), handle->dbpath, db->treename);
+ for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
+ if(_alpm_db_remove(db, lp->data) == -1) {
+ if(lp->data) {
+ _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s/%s"), db->treename,
+ ((pmpkg_t *)lp->data)->name);
+ }
+ RET_ERR(PM_ERR_DB_REMOVE, 1);
+ }
+ }
+
+ /* Cache needs to be rebuild */
+ _alpm_db_free_pkgcache(db);
+
+ /* uncompress the sync database */
+ /* ORE
+ we should not simply unpack the archive, but better parse it and
+ db_write each entry (see sync_load_dbarchive to get archive content) */
+ _alpm_log(PM_LOG_FLOW2, _("unpacking %s"), path);
+ if(_alpm_unpack(path, db->path, NULL)) {
+ RET_ERR(PM_ERR_SYSTEM, 1);
+ }
+ /* remove the .tar.gz */
+ unlink(path);
}
return(0);
@@ -359,6 +465,21 @@ PMList *alpm_db_getpkgcache(pmdb_t *db)
return(_alpm_db_get_pkgcache(db));
}
+/** Get the list of packages that a package provides
+ * @param db pointer to the package database to get the package from
+ * @param name name of the package
+ * @return the list of packages on success, NULL on error
+ */
+PMList *alpm_db_whatprovides(pmdb_t *db, char *name)
+{
+ /* Sanity checks */
+ ASSERT(handle != NULL, return(NULL));
+ ASSERT(db != NULL, return(NULL));
+ ASSERT(name != NULL && strlen(name) != 0, return(NULL));
+
+ return(_alpm_db_whatprovides(db, name));
+}
+
/** Get a group entry from a package database
* @param db pointer to the package database to get the group from
* @param name of the group
@@ -386,6 +507,7 @@ PMList *alpm_db_getgrpcache(pmdb_t *db)
return(_alpm_db_get_grpcache(db));
}
+
/** @} */
/** @defgroup alpm_packages Package Functions
@@ -396,7 +518,7 @@ PMList *alpm_db_getgrpcache(pmdb_t *db)
/** Get informations about a package.
* @param pkg package pointer
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_pkg_getinfo(pmpkg_t *pkg, unsigned char parm)
{
@@ -421,8 +543,10 @@ void *alpm_pkg_getinfo(pmpkg_t *pkg, unsigned char parm)
case PM_PKG_INSTALLDATE:
case PM_PKG_PACKAGER:
case PM_PKG_SIZE:
+ case PM_PKG_USIZE:
case PM_PKG_REASON:
case PM_PKG_MD5SUM:
+ case PM_PKG_SHA1SUM:
if(!(pkg->infolevel & INFRQ_DESC)) {
_alpm_log(PM_LOG_DEBUG, _("loading DESC info for '%s'"), pkg->name);
_alpm_db_read(pkg->data, INFRQ_DESC, pkg);
@@ -466,20 +590,24 @@ void *alpm_pkg_getinfo(pmpkg_t *pkg, unsigned char parm)
case PM_PKG_URL: data = pkg->url; break;
case PM_PKG_ARCH: data = pkg->arch; break;
case PM_PKG_BUILDDATE: data = pkg->builddate; break;
+ case PM_PKG_BUILDTYPE: data = pkg->buildtype; break;
case PM_PKG_INSTALLDATE: data = pkg->installdate; break;
case PM_PKG_PACKAGER: data = pkg->packager; break;
- case PM_PKG_SIZE: data = (void *)pkg->size; break;
- case PM_PKG_REASON: data = (void *)(int)pkg->reason; break;
+ case PM_PKG_SIZE: data = (void *)(long)pkg->size; break;
+ case PM_PKG_USIZE: data = (void *)(long)pkg->usize; break;
+ case PM_PKG_REASON: data = (void *)(long)pkg->reason; break;
case PM_PKG_LICENSE: data = pkg->license; break;
case PM_PKG_REPLACES: data = pkg->replaces; break;
case PM_PKG_MD5SUM: data = pkg->md5sum; break;
+ case PM_PKG_SHA1SUM: data = pkg->sha1sum; break;
case PM_PKG_DEPENDS: data = pkg->depends; break;
+ case PM_PKG_REMOVES: data = pkg->removes; break;
case PM_PKG_REQUIREDBY: data = pkg->requiredby; break;
case PM_PKG_PROVIDES: data = pkg->provides; break;
case PM_PKG_CONFLICTS: data = pkg->conflicts; break;
case PM_PKG_FILES: data = pkg->files; break;
case PM_PKG_BACKUP: data = pkg->backup; break;
- case PM_PKG_SCRIPLET: data = (void *)(int)pkg->scriptlet; break;
+ case PM_PKG_SCRIPLET: data = (void *)(long)pkg->scriptlet; break;
case PM_PKG_DATA: data = pkg->data; break;
default:
data = NULL;
@@ -525,13 +653,60 @@ int alpm_pkg_free(pmpkg_t *pkg)
return(0);
}
-/** Check the integrity of a package from the sync cache.
+/** Check the integrity (with sha1) of a package from the sync cache.
+ * @param pkg package pointer
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int alpm_pkg_checksha1sum(pmpkg_t *pkg)
+{
+ char path[PATH_MAX];
+ char *sha1sum = NULL;
+ int retval = 0;
+
+ ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+ /* We only inspect packages from sync repositories */
+ ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
+ ASSERT(pkg->data != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
+
+ snprintf(path, PATH_MAX, "%s%s/%s-%s" PM_EXT_PKG,
+ handle->root, handle->cachedir,
+ pkg->name, pkg->version);
+
+ sha1sum = _alpm_SHAFile(path);
+ if(sha1sum == NULL) {
+ _alpm_log(PM_LOG_ERROR, _("could not get sha1 checksum for package %s-%s\n"),
+ pkg->name, pkg->version);
+ pm_errno = PM_ERR_NOT_A_FILE;
+ retval = -1;
+ } else {
+ if(!(pkg->infolevel & INFRQ_DESC)) {
+ _alpm_log(PM_LOG_DEBUG, _("loading DESC info for '%s'"), pkg->name);
+ _alpm_db_read(pkg->data, INFRQ_DESC, pkg);
+ }
+
+ if(strcmp(sha1sum, pkg->sha1sum) == 0) {
+ _alpm_log(PM_LOG_FLOW1, _("checksums for package %s-%s are matching"),
+ pkg->name, pkg->version);
+ } else {
+ _alpm_log(PM_LOG_ERROR, _("sha1sums do not match for package %s-%s\n"),
+ pkg->name, pkg->version);
+ pm_errno = PM_ERR_PKG_INVALID;
+ retval = -1;
+ }
+ }
+
+ FREE(sha1sum);
+
+ return(retval);
+}
+
+/** Check the integrity (with md5) of a package from the sync cache.
* @param pkg package pointer
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{
- char *path = NULL;
+ char path[PATH_MAX];
char *md5sum = NULL;
int retval = 0;
@@ -540,11 +715,11 @@ int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->data != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
- asprintf(&path, "%s%s/%s-%s" PM_EXT_PKG,
+ snprintf(path, PATH_MAX, "%s%s/%s-%s" PM_EXT_PKG,
handle->root, handle->cachedir,
pkg->name, pkg->version);
- md5sum = MDFile(path);
+ md5sum = _alpm_MDFile(path);
if(md5sum == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not get md5 checksum for package %s-%s\n"),
pkg->name, pkg->version);
@@ -567,7 +742,6 @@ int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
}
}
- FREE(path);
FREE(md5sum);
return(retval);
@@ -583,6 +757,7 @@ int alpm_pkg_vercmp(const char *ver1, const char *ver2)
{
return(_alpm_versioncmp(ver1, ver2));
}
+
/** @} */
/** @defgroup alpm_groups Group Functions
@@ -593,7 +768,7 @@ int alpm_pkg_vercmp(const char *ver1, const char *ver2)
/** Get informations about a group.
* @param grp group pointer
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_grp_getinfo(pmgrp_t *grp, unsigned char parm)
{
@@ -620,9 +795,9 @@ void *alpm_grp_getinfo(pmgrp_t *grp, unsigned char parm)
*/
/** Get informations about a sync.
- * @param sync package pointer
+ * @param sync pointer
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_sync_getinfo(pmsyncpkg_t *sync, unsigned char parm)
{
@@ -632,7 +807,7 @@ void *alpm_sync_getinfo(pmsyncpkg_t *sync, unsigned char parm)
ASSERT(sync != NULL, return(NULL));
switch(parm) {
- case PM_SYNC_TYPE: data = (void *)(int)sync->type; break;
+ case PM_SYNC_TYPE: data = (void *)(long)sync->type; break;
case PM_SYNC_PKG: data = sync->pkg; break;
case PM_SYNC_DATA: data = sync->data; break;
default:
@@ -642,6 +817,21 @@ void *alpm_sync_getinfo(pmsyncpkg_t *sync, unsigned char parm)
return(data);
}
+
+/** Searches a database
+ * @param db pointer to the package database to search in
+ * @return the list of packages on success, NULL on error
+ */
+PMList *alpm_db_search(pmdb_t *db)
+{
+ /* Sanity checks */
+ ASSERT(handle != NULL, return(NULL));
+ ASSERT(handle->needles != NULL, return(NULL));
+ ASSERT(handle->needles->data != NULL, return(NULL));
+ ASSERT(db != NULL, return(NULL));
+
+ return(_alpm_db_search(db, handle->needles));
+}
/** @} */
/** @defgroup alpm_trans Transaction Functions
@@ -651,7 +841,7 @@ void *alpm_sync_getinfo(pmsyncpkg_t *sync, unsigned char parm)
/** Get informations about the transaction.
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_trans_getinfo(unsigned char parm)
{
@@ -665,8 +855,8 @@ void *alpm_trans_getinfo(unsigned char parm)
trans = handle->trans;
switch(parm) {
- case PM_TRANS_TYPE: data = (void *)(int)trans->type; break;
- case PM_TRANS_FLAGS: data = (void *)(int)trans->flags; break;
+ case PM_TRANS_TYPE: data = (void *)(long)trans->type; break;
+ case PM_TRANS_FLAGS: data = (void *)(long)trans->flags; break;
case PM_TRANS_TARGETS: data = trans->targets; break;
case PM_TRANS_PACKAGES: data = trans->packages; break;
default:
@@ -681,21 +871,22 @@ void *alpm_trans_getinfo(unsigned char parm)
* @param type type of the transaction
* @param flags flags of the transaction (like nodeps, etc)
* @param event event callback function pointer
- * @param conv conversation callback function pointer
+ * @param conv question callback function pointer
+ * @param progress progress callback function pointer
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
-int alpm_trans_init(unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv)
+int alpm_trans_init(unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv, alpm_trans_cb_progress progress)
{
+ char path[PATH_MAX];
+
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
- ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
- /* ORE
- * perform sanity checks on type and flags:
- * for instance, we can't set UPGRADE and FRESHEN at the same time */
+ ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
/* lock db */
- handle->lckfd = _alpm_lckmk(PM_LOCK);
+ snprintf(path, PATH_MAX, "%s/%s", handle->root, PM_LOCK);
+ handle->lckfd = _alpm_lckmk(path);
if(handle->lckfd == -1) {
RET_ERR(PM_ERR_HANDLE_LOCK, -1);
}
@@ -705,7 +896,7 @@ int alpm_trans_init(unsigned char type, unsigned int flags, alpm_trans_cb_event
RET_ERR(PM_ERR_MEMORY, -1);
}
- return(_alpm_trans_init(handle->trans, type, flags, event, conv));
+ return(_alpm_trans_init(handle->trans, type, flags, event, conv, progress));
}
/** Search for packages to upgrade and add them to the transaction.
@@ -751,14 +942,12 @@ int alpm_trans_addtarget(char *target)
*/
int alpm_trans_prepare(PMList **data)
{
- pmtrans_t *trans;
-
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
- trans = handle->trans;
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+ ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
return(_alpm_trans_prepare(handle->trans, data));
}
@@ -770,14 +959,11 @@ int alpm_trans_prepare(PMList **data)
*/
int alpm_trans_commit(PMList **data)
{
- pmtrans_t *trans;
-
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
- trans = handle->trans;
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1));
+ ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(handle->trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1));
/* Check for database R/W permission */
ASSERT(handle->access == PM_ACCESS_RW, RET_ERR(PM_ERR_BADPERMS, -1));
@@ -791,6 +977,7 @@ int alpm_trans_commit(PMList **data)
int alpm_trans_release()
{
pmtrans_t *trans;
+ char path[PATH_MAX];
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
@@ -799,11 +986,12 @@ int alpm_trans_release()
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans->state != STATE_IDLE, RET_ERR(PM_ERR_TRANS_NULL, -1));
- /* during a commit do not interrupt immediately, just after a target */
- if(trans->state == STATE_COMMITTING || trans->state == STATE_INTERRUPTED) {
- if(trans->state == STATE_COMMITTING) {
+ /* during a commit do not interrupt inmediatelly, just after a target */
+ if(trans->state == STATE_COMMITING || trans->state == STATE_INTERRUPTED) {
+ if(trans->state == STATE_COMMITING) {
trans->state = STATE_INTERRUPTED;
}
+ pm_errno = PM_ERR_TRANS_COMMITING;
return(-1);
}
@@ -814,9 +1002,10 @@ int alpm_trans_release()
close(handle->lckfd);
handle->lckfd = -1;
}
- if(_alpm_lckrm(PM_LOCK) == -1) {
- _alpm_log(PM_LOG_WARNING, _("could not remove lock file %s"), PM_LOCK);
- alpm_logaction(_("warning: could not remove lock file %s"), PM_LOCK);
+ snprintf(path, PATH_MAX, "%s/%s", handle->root, PM_LOCK);
+ if(_alpm_lckrm(path)) {
+ _alpm_log(PM_LOG_WARNING, _("could not remove lock file %s"), path);
+ alpm_logaction(_("warning: could not remove lock file %s"), path);
}
return(0);
@@ -829,9 +1018,9 @@ int alpm_trans_release()
*/
/** Get informations about a dependency.
- * @param db dependency pointer
+ * @param miss dependency pointer
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_dep_getinfo(pmdepmissing_t *miss, unsigned char parm)
{
@@ -841,9 +1030,9 @@ void *alpm_dep_getinfo(pmdepmissing_t *miss, unsigned char parm)
ASSERT(miss != NULL, return(NULL));
switch(parm) {
- case PM_DEP_TARGET: data = (void *)(int)miss->target; break;
- case PM_DEP_TYPE: data = (void *)(int)miss->type; break;
- case PM_DEP_MOD: data = (void *)(int)miss->depend.mod; break;
+ case PM_DEP_TARGET: data = (void *)(long)miss->target; break;
+ case PM_DEP_TYPE: data = (void *)(long)miss->type; break;
+ case PM_DEP_MOD: data = (void *)(long)miss->depend.mod; break;
case PM_DEP_NAME: data = miss->depend.name; break;
case PM_DEP_VERSION: data = miss->depend.version; break;
default:
@@ -861,9 +1050,9 @@ void *alpm_dep_getinfo(pmdepmissing_t *miss, unsigned char parm)
*/
/** Get informations about a file conflict.
- * @param db conflict pointer
+ * @param conflict database conflict structure
* @param parm name of the info to get
- * @return a void* on success (the value), NULL on error
+ * @return a char* on success (the value), NULL on error
*/
void *alpm_conflict_getinfo(pmconflict_t *conflict, unsigned char parm)
{
@@ -874,7 +1063,7 @@ void *alpm_conflict_getinfo(pmconflict_t *conflict, unsigned char parm)
switch(parm) {
case PM_CONFLICT_TARGET: data = conflict->target; break;
- case PM_CONFLICT_TYPE: data = (void *)(int)conflict->type; break;
+ case PM_CONFLICT_TYPE: data = (void *)(long)conflict->type; break;
case PM_CONFLICT_FILE: data = conflict->file; break;
case PM_CONFLICT_CTARGET: data = conflict->ctarget; break;
default:
@@ -979,6 +1168,8 @@ int alpm_list_free(PMList *entry)
*/
int alpm_list_count(PMList *list)
{
+ ASSERT(list != NULL, return(-1));
+
return(_alpm_list_count(list));
}
/** @} */
@@ -996,8 +1187,258 @@ char *alpm_get_md5sum(char *name)
{
ASSERT(name != NULL, return(NULL));
- return(MDFile(name));
+ return(_alpm_MDFile(name));
+}
+
+/** Get the sha1 sum of file.
+ * @param name name of the file
+ * @return the checksum on success, NULL on error
+ */
+char *alpm_get_sha1sum(char *name)
+{
+ ASSERT(name != NULL, return(NULL));
+
+ return(_alpm_SHAFile(name));
+}
+
+/** Fetch a remote pkg.
+ * @param url
+ * @return the downloaded filename on success, NULL on error
+ */
+char *alpm_fetch_pkgurl(char *url)
+{
+ ASSERT(strstr(url, "://"), return(NULL));
+
+ return(_alpm_fetch_pkgurl(url));
+}
+
+/** Parses a configuration file.
+ * @param file path to the config file.
+ * @param callback a function to be called upon new database creation
+ * @param this_section the config current section being parsed
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int alpm_parse_config(char *file, alpm_cb_db_register callback, const char *this_section)
+{
+ FILE *fp = NULL;
+ char line[PATH_MAX+1];
+ char *ptr = NULL;
+ char *key = NULL;
+ int linenum = 0;
+ char section[256] = "";
+ PM_DB *db = NULL;
+
+ fp = fopen(file, "r");
+ if(fp == NULL) {
+ return(0);
+ }
+
+ if(this_section != NULL && strlen(this_section) > 0) {
+ strncpy(section, this_section, min(255, strlen(this_section)));
+ db = alpm_db_register(section, callback);
+ }
+
+ while(fgets(line, PATH_MAX, fp)) {
+ linenum++;
+ _alpm_strtrim(line);
+ if(strlen(line) == 0 || line[0] == '#') {
+ continue;
+ }
+ if(line[0] == '[' && line[strlen(line)-1] == ']') {
+ /* new config section */
+ ptr = line;
+ ptr++;
+ strncpy(section, ptr, min(255, strlen(ptr)-1));
+ section[min(255, strlen(ptr)-1)] = '\0';
+ _alpm_log(PM_LOG_DEBUG, _("config: new section '%s'\n"), section);
+ if(!strlen(section)) {
+ RET_ERR(PM_ERR_CONF_BAD_SECTION, -1);
+ }
+ if(!strcmp(section, "local")) {
+ RET_ERR(PM_ERR_CONF_LOCAL, -1);
+ }
+ if(strcmp(section, "options")) {
+ db = alpm_db_register(section, callback);
+ if(db == NULL) {
+ /* pm_errno is set by alpm_db_register */
+ return(-1);
+ }
+ }
+ } else {
+ /* directive */
+ ptr = line;
+ key = strsep(&ptr, "=");
+ if(key == NULL) {
+ RET_ERR(PM_ERR_CONF_BAD_SYNTAX, -1);
+ }
+ _alpm_strtrim(key);
+ key = _alpm_strtoupper(key);
+ if(!strlen(section) && strcmp(key, "INCLUDE")) {
+ RET_ERR(PM_ERR_CONF_DIRECTIVE_OUTSIDE_SECTION, -1);
+ }
+ if(ptr == NULL) {
+ if(!strcmp(key, "NOPASSIVEFTP")) {
+ alpm_set_option(PM_OPT_NOPASSIVEFTP, (long)1);
+ } else if(!strcmp(key, "USESYSLOG")) {
+ alpm_set_option(PM_OPT_USESYSLOG, (long)1);
+ _alpm_log(PM_LOG_DEBUG, _("config: usesyslog\n"));
+ } else if(!strcmp(key, "ILOVECANDY")) {
+ alpm_set_option(PM_OPT_CHOMP, (long)1);
+ } else {
+ RET_ERR(PM_ERR_CONF_BAD_SYNTAX, -1);
+ }
+ } else {
+ _alpm_strtrim(ptr);
+ if(!strcmp(key, "INCLUDE")) {
+ char conf[PATH_MAX];
+ strncpy(conf, ptr, PATH_MAX);
+ _alpm_log(PM_LOG_DEBUG, _("config: including %s\n"), conf);
+ alpm_parse_config(conf, callback, section);
+ } else if(!strcmp(section, "options")) {
+ if(!strcmp(key, "NOUPGRADE")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ if(alpm_set_option(PM_OPT_NOUPGRADE, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: noupgrade: %s\n"), p);
+ p = q;
+ p++;
+ }
+ if(alpm_set_option(PM_OPT_NOUPGRADE, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: noupgrade: %s\n"), p);
+ } else if(!strcmp(key, "NOEXTRACT")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ if(alpm_set_option(PM_OPT_NOEXTRACT, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: noextract: %s\n"), p);
+ p = q;
+ p++;
+ }
+ if(alpm_set_option(PM_OPT_NOEXTRACT, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: noextract: %s\n"), p);
+ } else if(!strcmp(key, "IGNOREPKG")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ if(alpm_set_option(PM_OPT_IGNOREPKG, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: ignorepkg: %s\n"), p);
+ p = q;
+ p++;
+ }
+ if(alpm_set_option(PM_OPT_IGNOREPKG, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: ignorepkg: %s\n"), p);
+ } else if(!strcmp(key, "HOLDPKG")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ if(alpm_set_option(PM_OPT_HOLDPKG, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: holdpkg: %s\n"), p);
+ p = q;
+ p++;
+ }
+ if(alpm_set_option(PM_OPT_HOLDPKG, (long)p) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: holdpkg: %s\n"), p);
+ } else if(!strcmp(key, "DBPATH")) {
+ /* shave off the leading slash, if there is one */
+ if(*ptr == '/') {
+ ptr++;
+ }
+ if(alpm_set_option(PM_OPT_DBPATH, (long)ptr) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: dbpath: %s\n"), ptr);
+ } else if(!strcmp(key, "CACHEDIR")) {
+ /* shave off the leading slash, if there is one */
+ if(*ptr == '/') {
+ ptr++;
+ }
+ if(alpm_set_option(PM_OPT_CACHEDIR, (long)ptr) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: cachedir: %s\n"), ptr);
+ } else if (!strcmp(key, "LOGFILE")) {
+ if(alpm_set_option(PM_OPT_LOGFILE, (long)ptr) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("config: log file: %s\n"), ptr);
+ } else if (!strcmp(key, "XFERCOMMAND")) {
+ if(alpm_set_option(PM_OPT_XFERCOMMAND, (long)ptr) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ } else if (!strcmp(key, "UPGRADEDELAY")) {
+ /* The config value is in days, we use seconds */
+ _alpm_log(PM_LOG_DEBUG, _("config: UpgradeDelay: %i\n"), (60*60*24) * atol(ptr));
+ if(alpm_set_option(PM_OPT_UPGRADEDELAY, (60*60*24) * atol(ptr)) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ } else if (!strcmp(key, "PROXYSERVER")) {
+ if(alpm_set_option(PM_OPT_PROXYHOST, (long)ptr) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ } else if (!strcmp(key, "PROXYPORT")) {
+ if(alpm_set_option(PM_OPT_PROXYPORT, (long)atoi(ptr)) == -1) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ } else {
+ RET_ERR(PM_ERR_CONF_BAD_SYNTAX, -1);
+ }
+ } else {
+ if(!strcmp(key, "SERVER")) {
+ /* add to the list */
+ _alpm_log(PM_LOG_DEBUG, _("config: %s: server: %s\n"), section, ptr);
+ if(alpm_db_setserver(db, strdup(ptr)) != 0) {
+ /* pm_errno is set by alpm_set_option */
+ return(-1);
+ }
+ } else {
+ RET_ERR(PM_ERR_CONF_BAD_SYNTAX, -1);
+ }
+ }
+ line[0] = '\0';
+ }
+ }
+ }
+ fclose(fp);
+
+ return(0);
}
+
/* @} */
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 61702ce7..211ec99b 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -2,6 +2,9 @@
* alpm.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -32,8 +35,8 @@ extern "C" {
#define PM_ROOT "/"
#define PM_DBPATH "var/lib/pacman"
#define PM_CACHEDIR "var/cache/pacman/pkg"
+#define PM_LOCK "/tmp/pacman.lck"
-#define PM_LOCK "/tmp/pacman.lck"
#define PM_EXT_PKG ".pkg.tar.gz"
#define PM_EXT_DB ".db.tar.gz"
@@ -92,7 +95,27 @@ enum {
PM_OPT_SYNCDB,
PM_OPT_NOUPGRADE,
PM_OPT_NOEXTRACT,
- PM_OPT_IGNOREPKG
+ PM_OPT_IGNOREPKG,
+ PM_OPT_UPGRADEDELAY,
+ /* Download */
+ PM_OPT_PROXYHOST,
+ PM_OPT_PROXYPORT,
+ PM_OPT_XFERCOMMAND,
+ PM_OPT_NOPASSIVEFTP,
+ PM_OPT_DLCB,
+ PM_OPT_DLFNM,
+ PM_OPT_DLOFFSET,
+ PM_OPT_DLT0,
+ PM_OPT_DLT,
+ PM_OPT_DLRATE,
+ PM_OPT_DLXFERED1,
+ PM_OPT_DLETA_H,
+ PM_OPT_DLETA_M,
+ PM_OPT_DLETA_S,
+ /* End of download */
+ PM_OPT_HOLDPKG,
+ PM_OPT_CHOMP,
+ PM_OPT_NEEDLES
};
int alpm_set_option(unsigned char parm, unsigned long data);
@@ -104,21 +127,28 @@ int alpm_get_option(unsigned char parm, long *data);
/* Info parameters */
enum {
- PM_DB_TREENAME = 1
+ PM_DB_TREENAME = 1,
+ PM_DB_FIRSTSERVER
};
-PM_DB *alpm_db_register(char *treename);
+/* Database registration callback */
+typedef void (*alpm_cb_db_register)(char *, PM_DB *);
+
+PM_DB *alpm_db_register(char *treename, alpm_cb_db_register);
int alpm_db_unregister(PM_DB *db);
void *alpm_db_getinfo(PM_DB *db, unsigned char parm);
+int alpm_db_setserver(PM_DB *db, char *url);
-int alpm_db_update(PM_DB *db, char *archive);
+int alpm_db_update(int level, PM_DB *db);
PM_PKG *alpm_db_readpkg(PM_DB *db, char *name);
PM_LIST *alpm_db_getpkgcache(PM_DB *db);
+PM_LIST *alpm_db_whatprovides(PM_DB *db, char *name);
PM_GRP *alpm_db_readgrp(PM_DB *db, char *name);
PM_LIST *alpm_db_getgrpcache(PM_DB *db);
+PM_LIST *alpm_db_search(PM_DB *db);
/*
* Packages
@@ -135,13 +165,17 @@ enum {
PM_PKG_LICENSE,
PM_PKG_ARCH,
PM_PKG_BUILDDATE,
+ PM_PKG_BUILDTYPE,
PM_PKG_INSTALLDATE,
PM_PKG_PACKAGER,
PM_PKG_SIZE,
+ PM_PKG_USIZE,
PM_PKG_REASON,
PM_PKG_MD5SUM, /* Sync DB only */
+ PM_PKG_SHA1SUM, /* Sync DB only */
/* Depends entry */
PM_PKG_DEPENDS,
+ PM_PKG_REMOVES,
PM_PKG_REQUIREDBY,
PM_PKG_CONFLICTS,
PM_PKG_PROVIDES,
@@ -159,10 +193,17 @@ enum {
#define PM_PKG_REASON_EXPLICIT 0 /* explicitly requested by the user */
#define PM_PKG_REASON_DEPEND 1 /* installed as a dependency for another package */
+/* package name formats */
+#define PM_PKG_WITHOUT_ARCH 0 /* pkgname-pkgver-pkgrel, used under PM_DBPATH */
+#define PM_PKG_WITH_ARCH 1 /* ie, pkgname-pkgver-pkgrel-arch, used under PM_CACHEDIR */
+
void *alpm_pkg_getinfo(PM_PKG *pkg, unsigned char parm);
int alpm_pkg_load(char *filename, PM_PKG **pkg);
int alpm_pkg_free(PM_PKG *pkg);
int alpm_pkg_checkmd5sum(PM_PKG *pkg);
+int alpm_pkg_checksha1sum(PM_PKG *pkg);
+char *alpm_fetch_pkgurl(char *url);
+int alpm_parse_config(char *file, alpm_cb_db_register callback, const char *this_section);
int alpm_pkg_vercmp(const char *ver1, const char *ver2);
/*
@@ -209,16 +250,19 @@ enum {
};
/* Flags */
-#define PM_TRANS_FLAG_FORCE 0x001
-#define PM_TRANS_FLAG_DBONLY 0x002
-#define PM_TRANS_FLAG_NOSAVE 0x004
-#define PM_TRANS_FLAG_FRESHEN 0x008
-#define PM_TRANS_FLAG_CASCADE 0x010
-#define PM_TRANS_FLAG_RECURSE 0x020
-#define PM_TRANS_FLAG_NODEPS 0x040
-#define PM_TRANS_FLAG_ALLDEPS 0x080
-#define PM_TRANS_FLAG_NOCONFLICTS 0x100
-#define PM_TRANS_FLAG_NOSCRIPTLET 0x200
+#define PM_TRANS_FLAG_NODEPS 0x01
+#define PM_TRANS_FLAG_FORCE 0x02
+#define PM_TRANS_FLAG_NOSAVE 0x04
+#define PM_TRANS_FLAG_FRESHEN 0x08
+#define PM_TRANS_FLAG_CASCADE 0x10
+#define PM_TRANS_FLAG_RECURSE 0x20
+#define PM_TRANS_FLAG_DBONLY 0x40
+#define PM_TRANS_FLAG_DEPENDSONLY 0x80
+#define PM_TRANS_FLAG_ALLDEPS 0x100
+#define PM_TRANS_FLAG_DOWNLOADONLY 0x200
+#define PM_TRANS_FLAG_NOSCRIPTLET 0x400
+#define PM_TRANS_FLAG_NOCONFLICTS 0x800
+#define PM_TRANS_FLAG_PRINTURIS 0x1000
/* Transaction Events */
enum {
@@ -226,6 +270,8 @@ enum {
PM_TRANS_EVT_CHECKDEPS_DONE,
PM_TRANS_EVT_FILECONFLICTS_START,
PM_TRANS_EVT_FILECONFLICTS_DONE,
+ PM_TRANS_EVT_CLEANUP_START,
+ PM_TRANS_EVT_CLEANUP_DONE,
PM_TRANS_EVT_RESOLVEDEPS_START,
PM_TRANS_EVT_RESOLVEDEPS_DONE,
PM_TRANS_EVT_INTERCONFLICTS_START,
@@ -235,16 +281,34 @@ enum {
PM_TRANS_EVT_REMOVE_START,
PM_TRANS_EVT_REMOVE_DONE,
PM_TRANS_EVT_UPGRADE_START,
- PM_TRANS_EVT_UPGRADE_DONE
+ PM_TRANS_EVT_UPGRADE_DONE,
+ PM_TRANS_EVT_EXTRACT_DONE,
+ PM_TRANS_EVT_INTEGRITY_START,
+ PM_TRANS_EVT_INTEGRITY_DONE,
+ PM_TRANS_EVT_SCRIPTLET_INFO,
+ PM_TRANS_EVT_SCRIPTLET_START,
+ PM_TRANS_EVT_SCRIPTLET_DONE,
+ PM_TRANS_EVT_PRINTURI,
+ PM_TRANS_EVT_RETRIEVE_START,
+ PM_TRANS_EVT_RETRIEVE_LOCAL
};
/* Transaction Conversations (ie, questions) */
enum {
- PM_TRANS_CONV_INSTALL_IGNOREPKG = 1,
- PM_TRANS_CONV_REPLACE_PKG,
- PM_TRANS_CONV_CONFLICT_PKG,
- PM_TRANS_CONV_LOCAL_NEWER,
- PM_TRANS_CONV_LOCAL_UPTODATE
+ PM_TRANS_CONV_INSTALL_IGNOREPKG = 0x01,
+ PM_TRANS_CONV_REPLACE_PKG = 0x02,
+ PM_TRANS_CONV_CONFLICT_PKG = 0x04,
+ PM_TRANS_CONV_CORRUPTED_PKG = 0x08,
+ PM_TRANS_CONV_LOCAL_NEWER = 0x10,
+ PM_TRANS_CONV_LOCAL_UPTODATE = 0x20,
+ PM_TRANS_CONV_REMOVE_HOLDPKG = 0x40
+};
+
+/* Transaction Progress */
+enum {
+ PM_TRANS_PROGRESS_ADD_START,
+ PM_TRANS_PROGRESS_UPGRADE_START,
+ PM_TRANS_PROGRESS_REMOVE_START
};
/* Transaction Event callback */
@@ -253,6 +317,9 @@ typedef void (*alpm_trans_cb_event)(unsigned char, void *, void *);
/* Transaction Conversation callback */
typedef void (*alpm_trans_cb_conv)(unsigned char, void *, void *, void *, int *);
+/* Transaction Progress callback */
+typedef void (*alpm_trans_cb_progress)(unsigned char, char *, int, int, int);
+
/* Info parameters */
enum {
PM_TRANS_TYPE = 1,
@@ -262,7 +329,7 @@ enum {
};
void *alpm_trans_getinfo(unsigned char parm);
-int alpm_trans_init(unsigned char type, unsigned int flags, alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv);
+int alpm_trans_init(unsigned char type, unsigned int flags, alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv, alpm_trans_cb_progress cb_progress);
int alpm_trans_sysupgrade(void);
int alpm_trans_addtarget(char *target);
int alpm_trans_prepare(PM_LIST **data);
@@ -326,13 +393,14 @@ int alpm_list_count(PM_LIST *list);
/* md5sums */
char *alpm_get_md5sum(char *name);
+char *alpm_get_sha1sum(char *name);
/*
* Errors
*/
extern enum __pmerrno_t {
- PM_ERR_MEMORY = 1,
+ PM_ERR_MEMORY = 2,
PM_ERR_SYSTEM,
PM_ERR_BADPERMS,
PM_ERR_NOT_A_FILE,
@@ -349,6 +417,9 @@ extern enum __pmerrno_t {
PM_ERR_DB_NOT_FOUND,
PM_ERR_DB_WRITE,
PM_ERR_DB_REMOVE,
+ /* Servers */
+ PM_ERR_SERVER_BAD_LOCATION,
+ PM_ERR_SERVER_PROTOCOL_UNSUPPORTED,
/* Configuration */
PM_ERR_OPT_LOGFILE,
PM_ERR_OPT_DBPATH,
@@ -363,6 +434,7 @@ extern enum __pmerrno_t {
PM_ERR_TRANS_NOT_PREPARED,
PM_ERR_TRANS_ABORT,
PM_ERR_TRANS_TYPE,
+ PM_ERR_TRANS_COMMITING,
/* Packages */
PM_ERR_PKG_NOT_FOUND,
PM_ERR_PKG_INVALID,
@@ -371,6 +443,7 @@ extern enum __pmerrno_t {
PM_ERR_PKG_INSTALLED,
PM_ERR_PKG_CANT_FRESH,
PM_ERR_PKG_INVALID_NAME,
+ PM_ERR_PKG_CORRUPTED,
/* Groups */
PM_ERR_GRP_NOT_FOUND,
/* Dependencies */
@@ -380,7 +453,21 @@ extern enum __pmerrno_t {
/* Misc */
PM_ERR_USER_ABORT,
PM_ERR_INTERNAL_ERROR,
- PM_ERR_LIBARCHIVE_ERROR
+ PM_ERR_LIBARCHIVE_ERROR,
+ PM_ERR_DISK_FULL,
+ PM_ERR_DB_SYNC,
+ PM_ERR_RETRIEVE,
+ PM_ERR_PKG_HOLD,
+ /* Configuration file */
+ PM_ERR_CONF_BAD_SECTION,
+ PM_ERR_CONF_LOCAL,
+ PM_ERR_CONF_BAD_SYNTAX,
+ PM_ERR_CONF_DIRECTIVE_OUTSIDE_SECTION,
+ PM_ERR_INVALID_REGEX,
+ PM_ERR_TRANS_DOWNLOADING,
+ /* Downloading */
+ PM_ERR_CONNECT_FAILED,
+ PM_ERR_FORK_FAILED
} pm_errno;
char *alpm_strerror(int err);
@@ -388,7 +475,6 @@ char *alpm_strerror(int err);
#ifdef __cplusplus
}
#endif
-
#endif /* _ALPM_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c
index d4a450c6..9c79a141 100644
--- a/lib/libalpm/backup.c
+++ b/lib/libalpm/backup.c
@@ -1,7 +1,10 @@
/*
* backup.c
*
- * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -26,7 +29,7 @@
#include "backup.h"
/* Look for a filename in a pmpkg_t.backup list. If we find it,
- * then we return the md5 hash (parsed from the same line)
+ * then we return the md5 or sha1 hash (parsed from the same line)
*/
char *_alpm_needbackup(char *file, PMList *backup)
{
@@ -36,7 +39,7 @@ char *_alpm_needbackup(char *file, PMList *backup)
return(NULL);
}
- /* run through the backup list and parse out the md5 hash for our file */
+ /* run through the backup list and parse out the md5 or sha1 hash for our file */
for(lp = backup; lp; lp = lp->next) {
char *str = strdup(lp->data);
char *ptr;
@@ -49,7 +52,7 @@ char *_alpm_needbackup(char *file, PMList *backup)
}
*ptr = '\0';
ptr++;
- /* now str points to the filename and ptr points to the md5 hash */
+ /* now str points to the filename and ptr points to the md5 or sha1 hash */
if(!strcmp(file, str)) {
char *md5 = strdup(ptr);
free(str);
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 1f18d71a..7f273821 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -1,7 +1,8 @@
/*
* be_files.c
*
- * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -25,9 +26,13 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#ifdef __sun__
+#include <strings.h>
+#endif
#include <sys/stat.h>
#include <dirent.h>
#include <libintl.h>
+#include <locale.h>
#ifdef CYGWIN
#include <limits.h> /* PATH_MAX */
#endif
@@ -36,8 +41,12 @@
#include "util.h"
#include "db.h"
#include "alpm.h"
+#include "error.h"
+#include "handle.h"
+
+extern pmhandle_t *handle;
-int _alpm_db_open(pmdb_t *db, int mode)
+int _alpm_db_open(pmdb_t *db)
{
if(db == NULL) {
return(-1);
@@ -155,6 +164,9 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
struct stat buf;
char path[PATH_MAX];
char line[512];
+ char *lang_tmp;
+ PMList *tmplist;
+ char *foo;
if(db == NULL || info == NULL || info->name[0] == 0 || info->version[0] == 0) {
return(-1);
@@ -171,7 +183,7 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version);
fp = fopen(path, "r");
if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
+ _alpm_log(PM_LOG_DEBUG, "%s (%s)", path, strerror(errno));
goto error;
}
while(!feof(fp)) {
@@ -180,10 +192,34 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
}
_alpm_strtrim(line);
if(!strcmp(line, "%DESC%")) {
- if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
- goto error;
+ while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
+ info->desc_localized = _alpm_list_add(info->desc_localized, strdup(line));
+ }
+
+ if (setlocale(LC_ALL, "") == NULL) { /* To fix segfault when locale invalid */
+ setenv("LC_ALL", "C", 1);
+ }
+ if((lang_tmp = (char *)malloc(strlen(setlocale(LC_ALL, "")))) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ snprintf(lang_tmp, strlen(setlocale(LC_ALL, "")), "%s", setlocale(LC_ALL, ""));
+
+ if(info->desc_localized && !info->desc_localized->next) {
+ snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data);
+ } else {
+ for (tmplist = info->desc_localized; tmplist; tmplist = tmplist->next) {
+ if (tmplist->data && strncmp(tmplist->data, lang_tmp, strlen(lang_tmp))) {
+ snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data);
+ } else {
+ foo = strdup(tmplist->data);
+ snprintf(info->desc, 512, "%s", foo+strlen(lang_tmp)+1);
+ FREE(foo);
+ break;
+ }
+ }
}
_alpm_strtrim(info->desc);
+ FREE(lang_tmp);
} else if(!strcmp(line, "%GROUPS%")) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
info->groups = _alpm_list_add(info->groups, strdup(line));
@@ -207,6 +243,11 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
goto error;
}
_alpm_strtrim(info->builddate);
+ } else if(!strcmp(line, "%BUILDTYPE%")) {
+ if(fgets(info->buildtype, sizeof(info->buildtype), fp) == NULL) {
+ goto error;
+ }
+ _alpm_strtrim(info->buildtype);
} else if(!strcmp(line, "%INSTALLDATE%")) {
if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) {
goto error;
@@ -236,6 +277,21 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
}
_alpm_strtrim(tmp);
info->size = atol(tmp);
+ } else if(!strcmp(line, "%USIZE%")) {
+ /* USIZE (uncompressed size) tag only appears in sync repositories,
+ * not the local one. */
+ char tmp[32];
+ if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ goto error;
+ }
+ _alpm_strtrim(tmp);
+ info->usize = atol(tmp);
+ } else if(!strcmp(line, "%SHA1SUM%")) {
+ /* SHA1SUM tag only appears in sync repositories,
+ * not the local one. */
+ if(fgets(info->sha1sum, sizeof(info->sha1sum), fp) == NULL) {
+ goto error;
+ }
} else if(!strcmp(line, "%MD5SUM%")) {
/* MD5SUM tag only appears in sync repositories,
* not the local one. */
@@ -267,7 +323,7 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version);
fp = fopen(path, "r");
if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
+ _alpm_log(PM_LOG_WARNING, "%s (%s)", path, strerror(errno));
goto error;
}
while(fgets(line, 256, fp)) {
@@ -291,7 +347,7 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info)
snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version);
fp = fopen(path, "r");
if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
+ _alpm_log(PM_LOG_WARNING, "%s (%s)", path, strerror(errno));
goto error;
}
while(!feof(fp)) {
@@ -383,8 +439,11 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq)
fprintf(fp, "%%NAME%%\n%s\n\n"
"%%VERSION%%\n%s\n\n", info->name, info->version);
if(info->desc[0]) {
- fprintf(fp, "%%DESC%%\n"
- "%s\n\n", info->desc);
+ fputs("%DESC%\n", fp);
+ for(lp = info->desc_localized; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char *)lp->data);
+ }
+ fprintf(fp, "\n");
}
if(info->groups) {
fputs("%GROUPS%\n", fp);
@@ -413,6 +472,10 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq)
fprintf(fp, "%%BUILDDATE%%\n"
"%s\n\n", info->builddate);
}
+ if(info->buildtype[0]) {
+ fprintf(fp, "%%BUILDTYPE%%\n"
+ "%s\n\n", info->buildtype);
+ }
if(info->installdate[0]) {
fprintf(fp, "%%INSTALLDATE%%\n"
"%s\n\n", info->installdate);
@@ -434,7 +497,14 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq)
fprintf(fp, "%%CSIZE%%\n"
"%ld\n\n", info->size);
}
- if(info->md5sum) {
+ if(info->usize) {
+ fprintf(fp, "%%USIZE%%\n"
+ "%ld\n\n", info->usize);
+ }
+ if(info->sha1sum) {
+ fprintf(fp, "%%SHA1SUM%%\n"
+ "%s\n\n", info->sha1sum);
+ } else if(info->md5sum) {
fprintf(fp, "%%MD5SUM%%\n"
"%s\n\n", info->md5sum);
}
@@ -523,9 +593,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq)
}
/* INSTALL */
- if(local & (inforeq & INFRQ_SCRIPLET)) {
- /* nothing needed here (script is automatically extracted) */
- }
+ /* nothing needed here (script is automatically extracted) */
cleanup:
umask(oldmask);
@@ -563,6 +631,9 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
/* INSTALL */
snprintf(path, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
unlink(path);
+ /* CHANGELOG */
+ snprintf(path, PATH_MAX, "%s/%s-%s/changelog", db->path, info->name, info->version);
+ unlink(path);
}
/* Package directory */
@@ -575,4 +646,63 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
return(0);
}
+/* reads dbpath/.lastupdate and populates *ts with the contents.
+ * *ts should be malloc'ed and should be at least 15 bytes.
+ *
+ * Returns 0 on success, 1 on error
+ *
+ */
+int _alpm_db_getlastupdate(pmdb_t *db, char *ts)
+{
+ FILE *fp;
+ char file[PATH_MAX];
+
+ if(db == NULL || ts == NULL) {
+ return(-1);
+ }
+
+ snprintf(file, PATH_MAX, "%s%s/%s/.lastupdate", handle->root, handle->dbpath, db->treename);
+
+ /* get the last update time, if it's there */
+ if((fp = fopen(file, "r")) == NULL) {
+ return(-1);
+ } else {
+ char line[256];
+ if(fgets(line, sizeof(line), fp)) {
+ STRNCPY(ts, line, 15); /* YYYYMMDDHHMMSS */
+ ts[14] = '\0';
+ } else {
+ fclose(fp);
+ return(-1);
+ }
+ }
+ fclose(fp);
+ return(0);
+}
+
+/* writes the dbpath/.lastupdate with the contents of *ts
+ */
+int _alpm_db_setlastupdate(pmdb_t *db, char *ts)
+{
+ FILE *fp;
+ char file[PATH_MAX];
+
+ if(db == NULL || ts == NULL || strlen(ts) == 0) {
+ return(-1);
+ }
+
+ snprintf(file, PATH_MAX, "%s%s/%s/.lastupdate", handle->root, handle->dbpath, db->treename);
+
+ if((fp = fopen(file, "w")) == NULL) {
+ return(-1);
+ }
+ if(fputs(ts, fp) <= 0) {
+ fclose(fp);
+ return(-1);
+ }
+ fclose(fp);
+
+ return(0);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 2e9cc050..8a11ca31 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -2,6 +2,9 @@
* conflict.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -19,6 +22,10 @@
* USA.
*/
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
@@ -28,6 +35,7 @@
#include <libintl.h>
/* pacman */
#include "util.h"
+#include "error.h"
#include "log.h"
#include "cache.h"
#include "deps.h"
@@ -148,7 +156,7 @@ PMList *_alpm_checkconflicts(pmdb_t *db, PMList *packages)
for(j = packages; j; j = j->next) {
pmpkg_t *pkg = j->data;
if(!strcmp(pkg->name, info->name)) {
- // Use the new, to-be-installed package's conflicts
+ /* Use the new, to-be-installed package's conflicts */
conflicts = pkg->conflicts;
usenewconflicts = 1;
}
@@ -253,13 +261,6 @@ PMList *_alpm_db_find_conflicts(pmdb_t *db, PMList *targets, char *root, PMList
}
if(!lstat(path, &buf)) {
int ok = 0;
- if(!S_ISLNK(buf.st_mode) && ((isdir && !S_ISDIR(buf.st_mode)) || (!isdir && S_ISDIR(buf.st_mode)))) {
- /* if the package target is a directory, and the filesystem target
- * is not (or vice versa) then it's a conflict
- */
- ok = 0;
- goto donecheck;
- }
/* re-fetch with stat() instead of lstat() */
stat(path, &buf);
if(S_ISDIR(buf.st_mode)) {
@@ -328,7 +329,6 @@ PMList *_alpm_db_find_conflicts(pmdb_t *db, PMList *targets, char *root, PMList
}
}
}
-donecheck:
if(!ok) {
pmconflict_t *conflict = malloc(sizeof(pmconflict_t));
if(conflict == NULL) {
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 0bdbbf73..668628b4 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -2,6 +2,10 @@
* db.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -19,6 +23,11 @@
* USA.
*/
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#include <sys/stat.h>
+#endif
+
#include "config.h"
#include <unistd.h>
#include <stdio.h>
@@ -35,9 +44,14 @@
#include "log.h"
#include "util.h"
#include "error.h"
+#include "server.h"
#include "db.h"
+#include "handle.h"
+#include "cache.h"
#include "alpm.h"
+extern pmhandle_t *handle;
+
pmdb_t *_alpm_db_new(char *root, char* dbpath, char *treename)
{
pmdb_t *db;
@@ -45,23 +59,24 @@ pmdb_t *_alpm_db_new(char *root, char* dbpath, char *treename)
db = (pmdb_t *)malloc(sizeof(pmdb_t));
if(db == NULL) {
_alpm_log(PM_LOG_ERROR, _("malloc failed: could not allocate %d bytes"),
- sizeof(pmdb_t));
+ sizeof(pmdb_t));
RET_ERR(PM_ERR_MEMORY, NULL);
}
db->path = (char *)malloc(strlen(root)+strlen(dbpath)+strlen(treename)+2);
if(db->path == NULL) {
_alpm_log(PM_LOG_ERROR, _("malloc failed: could not allocate %d bytes"),
- strlen(root)+strlen(dbpath)+strlen(treename)+2);
+ strlen(root)+strlen(dbpath)+strlen(treename)+2);
FREE(db);
RET_ERR(PM_ERR_MEMORY, NULL);
}
sprintf(db->path, "%s%s/%s", root, dbpath, treename);
- STRNCPY(db->treename, treename, DB_TREENAME_LEN);
+ STRNCPY(db->treename, treename, PATH_MAX);
db->pkgcache = NULL;
db->grpcache = NULL;
+ db->servers = NULL;
return(db);
}
@@ -70,12 +85,11 @@ void _alpm_db_free(void *data)
{
pmdb_t *db = data;
- if(db == NULL) {
- return;
- }
-
+ FREELISTSERVERS(db->servers);
free(db->path);
free(db);
+
+ return;
}
int _alpm_db_cmp(const void *db1, const void *db2)
@@ -83,4 +97,74 @@ int _alpm_db_cmp(const void *db1, const void *db2)
return(strcmp(((pmdb_t *)db1)->treename, ((pmdb_t *)db2)->treename));
}
+PMList *_alpm_db_search(pmdb_t *db, PMList *needles)
+{
+ PMList *i, *j, *k, *ret = NULL;
+
+ for(i = needles; i; i = i->next) {
+ char *targ;
+ int retval;
+
+ if(i->data == NULL) {
+ continue;
+ }
+ targ = strdup(i->data);
+
+ for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
+ pmpkg_t *pkg = j->data;
+ char *haystack;
+ int match = 0;
+
+ /* check name */
+ haystack = strdup(pkg->name);
+ retval = _alpm_reg_match(haystack, targ);
+ if(retval < 0) {
+ /* bad regexp */
+ FREE(haystack);
+ return(NULL);
+ } else if(retval) {
+ match = 1;
+ }
+ FREE(haystack);
+
+ /* check description */
+ if(!match) {
+ haystack = strdup(pkg->desc);
+ retval = _alpm_reg_match(haystack, targ);
+ if(retval < 0) {
+ /* bad regexp */
+ FREE(haystack);
+ return(NULL);
+ } else if(retval) {
+ match = 1;
+ }
+ FREE(haystack);
+ }
+
+ /* check provides */
+ if(!match) {
+ for(k = pkg->provides; k; k = k->next) {
+ haystack = strdup(k->data);
+ retval = _alpm_reg_match(haystack, targ);
+ if(retval < 0) {
+ /* bad regexp */
+ FREE(haystack);
+ return(NULL);
+ } else if(retval) {
+ match = 1;
+ }
+ FREE(haystack);
+ }
+ }
+
+ if(match) {
+ ret = _alpm_list_add(ret, pkg);
+ }
+ }
+
+ FREE(targ);
+ }
+
+ return(ret);
+}
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index b1a88103..a374e096 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -2,6 +2,8 @@
* db.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -21,6 +23,7 @@
#ifndef _ALPM_DB_H
#define _ALPM_DB_H
+#include <limits.h>
#include "package.h"
/* Database entries */
@@ -31,30 +34,32 @@
#define INFRQ_SCRIPLET 0x08
#define INFRQ_ALL 0xFF
-#define DB_TREENAME_LEN 128
-
#define DB_O_CREATE 0x01
/* Database */
typedef struct __pmdb_t {
char *path;
- char treename[DB_TREENAME_LEN];
+ char treename[PATH_MAX];
void *handle;
PMList *pkgcache;
PMList *grpcache;
+ PMList *servers;
} pmdb_t;
pmdb_t *_alpm_db_new(char *root, char *dbpath, char *treename);
void _alpm_db_free(void *data);
int _alpm_db_cmp(const void *db1, const void *db2);
+PMList *_alpm_db_search(pmdb_t *db, PMList *needles);
/* Prototypes for backends functions */
-int _alpm_db_open(pmdb_t *db, int mode);
+int _alpm_db_open(pmdb_t *db);
void _alpm_db_close(pmdb_t *db);
void _alpm_db_rewind(pmdb_t *db);
pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, unsigned int inforeq);
int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info);
int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq);
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info);
+int _alpm_db_getlastupdate(pmdb_t *db, char *ts);
+int _alpm_db_setlastupdate(pmdb_t *db, char *ts);
#endif /* _ALPM_DB_H */
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 978ffb68..f709096d 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -2,6 +2,8 @@
* deps.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -22,7 +24,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#ifdef __sun__
+#include <strings.h>
+#endif
#include <libintl.h>
+#include <math.h>
/* pacman */
#include "util.h"
#include "log.h"
@@ -95,7 +101,7 @@ int _alpm_depmiss_isin(pmdepmissing_t *needle, PMList *haystack)
PMList *_alpm_sortbydeps(PMList *targets, int mode)
{
PMList *newtargs = NULL;
- PMList *i, *j, *k;
+ PMList *i, *j, *k, *l;
int change = 1;
int numscans = 0;
int numtargs = 0;
@@ -109,11 +115,12 @@ PMList *_alpm_sortbydeps(PMList *targets, int mode)
numtargs++;
}
+ _alpm_log(PM_LOG_DEBUG, _("started sorting dependencies"));
while(change) {
PMList *tmptargs = NULL;
change = 0;
- if(numscans > numtargs) {
- _alpm_log(PM_LOG_WARNING, _("possible dependency cycle detected"));
+ if(numscans > sqrt(numtargs)) {
+ _alpm_log(PM_LOG_DEBUG, _("possible dependency cycle detected"));
continue;
}
numscans++;
@@ -138,6 +145,15 @@ PMList *_alpm_sortbydeps(PMList *targets, int mode)
}
break;
}
+ for(l = q->provides; l; l = l->next) {
+ if(!strcmp(dep.name, (char*)l->data)) {
+ if(!_alpm_pkg_isin((char*)l->data, tmptargs)) {
+ change = 1;
+ tmptargs = _alpm_list_add(tmptargs, q);
+ }
+ break;
+ }
+ }
}
}
if(!_alpm_pkg_isin(p->name, tmptargs)) {
@@ -147,6 +163,7 @@ PMList *_alpm_sortbydeps(PMList *targets, int mode)
FREELISTPTR(newtargs);
newtargs = tmptargs;
}
+ _alpm_log(PM_LOG_DEBUG, _("sorting dependencies finished"));
if(mode == PM_TRANS_TYPE_REMOVE) {
/* we're removing packages, so reverse the order */
@@ -164,7 +181,7 @@ PMList *_alpm_sortbydeps(PMList *targets, int mode)
* dependencies can include versions with depmod operators.
*
*/
-PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages)
+PMList *_alpm_checkdeps(pmtrans_t *trans, pmdb_t *db, unsigned char op, PMList *packages)
{
pmdepend_t depend;
PMList *i, *j, *k;
@@ -290,27 +307,11 @@ PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages)
}
}
}
- /* check database for provides matches */
- if(!found) {
- PMList *m;
- k = _alpm_db_whatprovides(db, depend.name);
- for(m = k; m && !found; m = m->next) {
- /* look for a match that isn't one of the packages we're trying
- * to install. this way, if we match against a to-be-installed
- * package, we'll defer to the NEW one, not the one already
- * installed. */
- pmpkg_t *p = m->data;
- PMList *n;
- int skip = 0;
- for(n = packages; n && !skip; n = n->next) {
- pmpkg_t *ptp = n->data;
- if(!strcmp(ptp->name, p->name)) {
- skip = 1;
- }
- }
- if(skip) {
- continue;
- }
+ /* check other targets */
+ for(k = packages; k && !found; k = k->next) {
+ pmpkg_t *p = (pmpkg_t *)k->data;
+ /* see if the package names match OR if p provides depend.name */
+ if(!strcmp(p->name, depend.name) || _alpm_list_is_strin(depend.name, p->provides)) {
if(depend.mod == PM_DEP_MOD_ANY) {
/* accept any version */
found = 1;
@@ -333,13 +334,13 @@ PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages)
FREE(ver);
}
}
- FREELISTPTR(k);
}
- /* check other targets */
- for(k = packages; k && !found; k = k->next) {
- pmpkg_t *p = (pmpkg_t *)k->data;
- /* see if the package names match OR if p provides depend.name */
- if(!strcmp(p->name, depend.name) || _alpm_list_is_strin(depend.name, p->provides)) {
+ /* check database for provides matches */
+ if(!found){
+ k = _alpm_db_whatprovides(db, depend.name);
+ if(k) {
+ /* grab the first one (there should only really be one, anyway) */
+ pmpkg_t *p = k->data;
if(depend.mod == PM_DEP_MOD_ANY) {
/* accept any version */
found = 1;
@@ -361,6 +362,7 @@ PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages)
}
FREE(ver);
}
+ FREELISTPTR(k);
}
}
/* else if still not found... */
@@ -384,14 +386,30 @@ PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages)
continue;
}
+ found=0;
for(j = tp->requiredby; j; j = j->next) {
if(!_alpm_list_is_strin((char *)j->data, packages)) {
- _alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"), (char *)j->data, tp->name);
- miss = _alpm_depmiss_new(tp->name, PM_DEP_TYPE_REQUIRED, PM_DEP_MOD_ANY, j->data, NULL);
- if(!_alpm_depmiss_isin(miss, baddeps)) {
- baddeps = _alpm_list_add(baddeps, miss);
+ /* check if a package in trans->packages provides this package */
+ for(k=trans->packages; !found && k; k=k->next) {
+ pmpkg_t *spkg = NULL;
+ if(trans->type == PM_TRANS_TYPE_SYNC) {
+ pmsyncpkg_t *sync = k->data;
+ spkg = sync->pkg;
} else {
- FREE(miss);
+ spkg = k->data;
+ }
+ if(spkg && _alpm_list_is_strin(tp->name, spkg->provides)) {
+ found=1;
+ }
+ }
+ if(!found) {
+ _alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"), (char *)j->data, tp->name);
+ miss = _alpm_depmiss_new(tp->name, PM_DEP_TYPE_REQUIRED, PM_DEP_MOD_ANY, j->data, NULL);
+ if(!_alpm_depmiss_isin(miss, baddeps)) {
+ baddeps = _alpm_list_add(baddeps, miss);
+ } else {
+ FREE(miss);
+ }
}
}
}
@@ -536,7 +554,7 @@ int _alpm_resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList
}
targ = _alpm_list_add(NULL, syncpkg);
- deps = _alpm_checkdeps(local, PM_TRANS_TYPE_ADD, targ);
+ deps = _alpm_checkdeps(trans, local, PM_TRANS_TYPE_ADD, targ);
FREELISTPTR(targ);
if(deps == NULL) {
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 35d66308..ffd848ea 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -2,6 +2,8 @@
* deps.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -40,7 +42,7 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, unsigned char type, unsign
const char *depname, const char *depversion);
int _alpm_depmiss_isin(pmdepmissing_t *needle, PMList *haystack);
PMList *_alpm_sortbydeps(PMList *targets, int mode);
-PMList *_alpm_checkdeps(pmdb_t *db, unsigned char op, PMList *packages);
+PMList *_alpm_checkdeps(pmtrans_t *trans, pmdb_t *db, unsigned char op, PMList *packages);
int _alpm_splitdep(char *depstr, pmdepend_t *depend);
PMList *_alpm_removedeps(pmdb_t *db, PMList *targs);
int _alpm_resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list,
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 9f36810c..fbeca9b4 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -2,6 +2,9 @@
* error.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -96,6 +99,8 @@ char *alpm_strerror(int err)
return _("package not installed or lesser version");
case PM_ERR_PKG_INVALID_NAME:
return _("package name is not valid");
+ case PM_ERR_PKG_CORRUPTED:
+ return _("corrupted package");
/* Groups */
case PM_ERR_GRP_NOT_FOUND:
return _("group not found");
@@ -109,10 +114,29 @@ char *alpm_strerror(int err)
/* Miscellaenous */
case PM_ERR_USER_ABORT:
return _("user aborted");
- case PM_ERR_INTERNAL_ERROR:
- return _("internal error");
case PM_ERR_LIBARCHIVE_ERROR:
return _("libarchive error");
+ case PM_ERR_INTERNAL_ERROR:
+ return _("internal error");
+ case PM_ERR_DISK_FULL:
+ return _("not enough space");
+ case PM_ERR_PKG_HOLD:
+ return _("not confirmed");
+ /* Config */
+ case PM_ERR_CONF_BAD_SECTION:
+ return _("bad section name");
+ case PM_ERR_CONF_LOCAL:
+ return _("'local' is reserved and cannot be used as a package tree");
+ case PM_ERR_CONF_BAD_SYNTAX:
+ return _("syntax error");
+ case PM_ERR_CONF_DIRECTIVE_OUTSIDE_SECTION:
+ return _("all directives must belong to a section");
+ case PM_ERR_INVALID_REGEX:
+ return _("valid regular expression");
+ case PM_ERR_CONNECT_FAILED:
+ return _("connection to remote host failed");
+ case PM_ERR_FORK_FAILED:
+ return _("forking process failed");
default:
return _("unexpected error");
}
diff --git a/lib/libalpm/error.h b/lib/libalpm/error.h
index 312c0c06..bee36076 100644
--- a/lib/libalpm/error.h
+++ b/lib/libalpm/error.h
@@ -21,7 +21,9 @@
#ifndef _ALPM_ERROR_H
#define _ALPM_ERROR_H
-#define RET_ERR(err, ret) do { pm_errno = (err); return(ret); } while(0)
+#define RET_ERR(err, ret) do { pm_errno = (err); \
+ _alpm_log(PM_LOG_ERROR, _("returning error %d: %s\n"), err, alpm_strerror(err)); \
+ return(ret); } while(0)
#endif /* _ALPM_ERROR_H */
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 9c5d971b..62abf6c1 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -2,6 +2,8 @@
* handle.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -28,6 +30,8 @@
#include <stdarg.h>
#include <syslog.h>
#include <libintl.h>
+#include <time.h>
+#include <ftplib.h>
/* pacman */
#include "util.h"
#include "log.h"
@@ -39,9 +43,17 @@
/* log */
extern alpm_cb_log pm_logcb;
+extern FtpCallback pm_dlcb;
extern unsigned char pm_logmask;
+/* progress bar */
+extern char *pm_dlfnm;
+extern int *pm_dloffset;
+extern struct timeval *pm_dlt0, *pm_dlt;
+extern float *pm_dlrate;
+extern int *pm_dlxfered1;
+extern unsigned char *pm_dleta_h, *pm_dleta_m, *pm_dleta_s;
-pmhandle_t *handle_new()
+pmhandle_t *_alpm_handle_new()
{
pmhandle_t *handle;
@@ -84,7 +96,7 @@ pmhandle_t *handle_new()
return(handle);
}
-int handle_free(pmhandle_t *handle)
+int _alpm_handle_free(pmhandle_t *handle)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
@@ -104,20 +116,25 @@ int handle_free(pmhandle_t *handle)
FREE(handle->dbpath);
FREE(handle->cachedir);
FREE(handle->logfile);
+ FREE(handle->proxyhost);
+ FREE(handle->xfercommand);
FREELIST(handle->dbs_sync);
FREELIST(handle->noupgrade);
FREELIST(handle->noextract);
FREELIST(handle->ignorepkg);
+ FREELIST(handle->holdpkg);
+ FREELIST(handle->needles);
free(handle);
return(0);
}
-int handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data)
+int _alpm_handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data)
{
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ char *p;
switch(val) {
case PM_OPT_DBPATH:
if(handle->dbpath) {
@@ -181,6 +198,24 @@ int handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data)
_alpm_log(PM_LOG_FLOW2, _("PM_OPT_IGNOREPKG flushed"));
}
break;
+ case PM_OPT_HOLDPKG:
+ if((char *)data && strlen((char *)data) != 0) {
+ handle->holdpkg = _alpm_list_add(handle->holdpkg, strdup((char *)data));
+ _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_HOLDPKG"), (char *)data);
+ } else {
+ FREELIST(handle->holdpkg);
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_HOLDPKG flushed"));
+ }
+ break;
+ case PM_OPT_NEEDLES:
+ if((char *)data && strlen((char *)data) != 0) {
+ handle->needles = _alpm_list_add(handle->needles, strdup((char *)data));
+ _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_NEEDLES"), (char *)data);
+ } else {
+ FREELIST(handle->needles);
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NEEDLES flushed"));
+ }
+ break;
case PM_OPT_USESYSLOG:
if(data != 0 && data != 1) {
RET_ERR(PM_ERR_OPT_USESYSLOG, -1);
@@ -199,10 +234,85 @@ int handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data)
case PM_OPT_LOGCB:
pm_logcb = (alpm_cb_log)data;
break;
+ case PM_OPT_DLCB:
+ pm_dlcb = (FtpCallback)data;
+ break;
+ case PM_OPT_DLFNM:
+ pm_dlfnm = (char *)data;
+ break;
+ case PM_OPT_DLOFFSET:
+ pm_dloffset = (int *)data;
+ break;
+ case PM_OPT_DLT0:
+ pm_dlt0 = (struct timeval *)data;
+ break;
+ case PM_OPT_DLT:
+ pm_dlt = (struct timeval *)data;
+ break;
+ case PM_OPT_DLRATE:
+ pm_dlrate = (float *)data;
+ break;
+ case PM_OPT_DLXFERED1:
+ pm_dlxfered1 = (int *)data;
+ break;
+ case PM_OPT_DLETA_H:
+ pm_dleta_h = (unsigned char *)data;
+ break;
+ case PM_OPT_DLETA_M:
+ pm_dleta_m = (unsigned char *)data;
+ break;
+ case PM_OPT_DLETA_S:
+ pm_dleta_s = (unsigned char *)data;
+ break;
+ case PM_OPT_UPGRADEDELAY:
+ handle->upgradedelay = data;
+ break;
case PM_OPT_LOGMASK:
pm_logmask = (unsigned char)data;
_alpm_log(PM_LOG_FLOW2, _("PM_OPT_LOGMASK set to '%02x'"), (unsigned char)data);
break;
+ case PM_OPT_PROXYHOST:
+ if(handle->proxyhost) {
+ FREE(handle->proxyhost);
+ }
+ p = strstr((char*)data, "://");
+ if(p) {
+ p += 3;
+ if(p == NULL || *p == '\0') {
+ RET_ERR(PM_ERR_SERVER_BAD_LOCATION, -1);
+ }
+ data = (long)p;
+ }
+#if defined(__APPLE__) || defined(__OpenBSD__)
+ handle->proxyhost = strdup((char*)data);
+#else
+ handle->proxyhost = strndup((char*)data, PATH_MAX);
+#endif
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_PROXYHOST set to '%s'"), handle->proxyhost);
+ break;
+ case PM_OPT_PROXYPORT:
+ handle->proxyport = (unsigned short)data;
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_PROXYPORT set to '%d'"), handle->proxyport);
+ break;
+ case PM_OPT_XFERCOMMAND:
+ if(handle->xfercommand) {
+ FREE(handle->xfercommand);
+ }
+#if defined(__APPLE__) || defined(__OpenBSD__)
+ handle->xfercommand = strdup((char*)data);
+#else
+ handle->xfercommand = strndup((char*)data, PATH_MAX);
+#endif
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_XFERCOMMAND set to '%s'"), handle->xfercommand);
+ break;
+ case PM_OPT_NOPASSIVEFTP:
+ handle->nopassiveftp = (unsigned short)data;
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NOPASSIVEFTP set to '%d'"), handle->nopassiveftp);
+ break;
+ case PM_OPT_CHOMP:
+ handle->chomp = (unsigned short)data;
+ _alpm_log(PM_LOG_FLOW2, _("PM_OPT_CHOMP set to '%d'"), handle->chomp);
+ break;
default:
RET_ERR(PM_ERR_WRONG_ARGS, -1);
}
@@ -210,7 +320,7 @@ int handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data)
return(0);
}
-int handle_get_option(pmhandle_t *handle, unsigned char val, long *data)
+int _alpm_handle_get_option(pmhandle_t *handle, unsigned char val, long *data)
{
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
@@ -225,9 +335,27 @@ int handle_get_option(pmhandle_t *handle, unsigned char val, long *data)
case PM_OPT_NOUPGRADE: *data = (long)handle->noupgrade; break;
case PM_OPT_NOEXTRACT: *data = (long)handle->noextract; break;
case PM_OPT_IGNOREPKG: *data = (long)handle->ignorepkg; break;
+ case PM_OPT_HOLDPKG: *data = (long)handle->holdpkg; break;
+ case PM_OPT_NEEDLES: *data = (long)handle->needles; break;
case PM_OPT_USESYSLOG: *data = handle->usesyslog; break;
case PM_OPT_LOGCB: *data = (long)pm_logcb; break;
+ case PM_OPT_DLCB: *data = (long)pm_dlcb; break;
+ case PM_OPT_UPGRADEDELAY: *data = (long)handle->upgradedelay; break;
case PM_OPT_LOGMASK: *data = pm_logmask; break;
+ case PM_OPT_DLFNM: *data = (long)pm_dlfnm; break;
+ case PM_OPT_DLOFFSET: *data = (long)pm_dloffset; break;
+ case PM_OPT_DLT0: *data = (long)pm_dlt0; break;
+ case PM_OPT_DLT: *data = (long)pm_dlt; break;
+ case PM_OPT_DLRATE: *data = (long)pm_dlrate; break;
+ case PM_OPT_DLXFERED1: *data = (long)pm_dlxfered1; break;
+ case PM_OPT_DLETA_H: *data = (long)pm_dleta_h; break;
+ case PM_OPT_DLETA_M: *data = (long)pm_dleta_m; break;
+ case PM_OPT_DLETA_S: *data = (long)pm_dleta_s; break;
+ case PM_OPT_PROXYHOST: *data = (long)handle->proxyhost; break;
+ case PM_OPT_PROXYPORT: *data = handle->proxyport; break;
+ case PM_OPT_XFERCOMMAND: *data = (long)handle->xfercommand; break;
+ case PM_OPT_NOPASSIVEFTP: *data = handle->nopassiveftp; break;
+ case PM_OPT_CHOMP: *data = handle->chomp; break;
default:
RET_ERR(PM_ERR_WRONG_ARGS, -1);
break;
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 7819bfad..b50e5800 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -47,15 +47,24 @@ typedef struct __pmhandle_t {
PMList *noupgrade; /* List of strings */
PMList *noextract; /* List of strings */
PMList *ignorepkg; /* List of strings */
+ PMList *holdpkg; /* List of strings */
unsigned char usesyslog;
+ time_t upgradedelay;
+ /* servers */
+ char *proxyhost;
+ unsigned short proxyport;
+ char *xfercommand;
+ unsigned short nopassiveftp;
+ unsigned short chomp; /* if eye-candy features should be enabled or not */
+ PMList *needles; /* for searching */
} pmhandle_t;
-#define FREEHANDLE(p) do { if (p) { handle_free(p); p = NULL; } } while (0)
+#define FREEHANDLE(p) do { if (p) { _alpm_handle_free(p); p = NULL; } } while (0)
-pmhandle_t *handle_new(void);
-int handle_free(pmhandle_t *handle);
-int handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data);
-int handle_get_option(pmhandle_t *handle, unsigned char val, long *data);
+pmhandle_t *_alpm_handle_new(void);
+int _alpm_handle_free(pmhandle_t *handle);
+int _alpm_handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data);
+int _alpm_handle_get_option(pmhandle_t *handle, unsigned char val, long *data);
#endif /* _ALPM_HANDLE_H */
diff --git a/lib/libalpm/md5.c b/lib/libalpm/md5.c
index b4f5a159..7e4fd677 100644
--- a/lib/libalpm/md5.c
+++ b/lib/libalpm/md5.c
@@ -49,8 +49,6 @@ documentation and/or software.
static void MD5Transform(UINT4 [4], unsigned char [64]);
static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode(UINT4 *, unsigned char *, unsigned int);
-/* static void MD5_memcpy(POINTER, POINTER, unsigned int); */
-/* static void MD5_memset(POINTER, int, unsigned int); */
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -95,7 +93,7 @@ Rotation is separate from addition to prevent recomputation.
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
-void MD5Init (context)
+void _alpm_MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
@@ -111,7 +109,7 @@ MD5_CTX *context; /* context */
operation, processing another message block, and updating the
context.
*/
-void MD5Update (context, input, inputLen)
+void _alpm_MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
@@ -151,7 +149,7 @@ unsigned int inputLen; /* length of input block */
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
-void MD5Final (digest, context)
+void _alpm_MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
@@ -165,10 +163,10 @@ MD5_CTX *context; /* context */
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update (context, PADDING, padLen);
+ _alpm_MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
- MD5Update (context, bits, 8);
+ _alpm_MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
@@ -305,32 +303,4 @@ unsigned int len;
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-
-/* static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
-
- output[i] = input[i];
-}
-*/
-/* Note: Replace "for loop" with standard memset if possible.
- */
-/* static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-*/
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/md5.h b/lib/libalpm/md5.h
index 20aae92b..dbd0ab92 100644
--- a/lib/libalpm/md5.h
+++ b/lib/libalpm/md5.h
@@ -23,7 +23,6 @@ These notices must be retained in any copies of any part of this
documentation and/or software.
*/
-
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
@@ -41,11 +40,11 @@ typedef struct {
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
-void MD5Init(MD5_CTX *);
-void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
-void MD5Final(unsigned char [16], MD5_CTX *);
+void _alpm_MD5Init(MD5_CTX *);
+void _alpm_MD5Update(MD5_CTX *, unsigned char *, unsigned int);
+void _alpm_MD5Final(unsigned char [16], MD5_CTX *);
-char* MDFile(char *);
-void MDPrint(unsigned char [16]);
+char* _alpm_MDFile(char *);
+void _alpm_MDPrint(unsigned char [16]);
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/md5driver.c b/lib/libalpm/md5driver.c
index b6ebfa83..5167a6b1 100644
--- a/lib/libalpm/md5driver.c
+++ b/lib/libalpm/md5driver.c
@@ -33,11 +33,11 @@ documentation and/or software.
#define TEST_BLOCK_COUNT 1000
#define MD_CTX MD5_CTX
-#define MDInit MD5Init
-#define MDUpdate MD5Update
-#define MDFinal MD5Final
+#define MDInit _alpm_MD5Init
+#define MDUpdate _alpm_MD5Update
+#define MDFinal _alpm_MD5Final
-char* MDFile(char *filename)
+char* _alpm_MDFile(char *filename)
{
FILE *file;
MD_CTX context;
@@ -73,7 +73,7 @@ char* MDFile(char *filename)
/* Prints a message digest in hexadecimal.
*/
-void MDPrint(unsigned char digest[16])
+void _alpm_MDPrint(unsigned char digest[16])
{
unsigned int i;
for (i = 0; i < 16; i++)
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index c8822240..77f85ab8 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -1,7 +1,10 @@
/*
* package.c
- *
+ *
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -26,6 +29,7 @@
#include <fcntl.h>
#include <string.h>
#include <libintl.h>
+#include <locale.h>
/* pacman */
#include "log.h"
#include "util.h"
@@ -38,10 +42,8 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
{
pmpkg_t* pkg = NULL;
- pkg = (pmpkg_t *)malloc(sizeof(pmpkg_t));
- if(pkg == NULL) {
- _alpm_log(PM_LOG_ERROR, "malloc failure: could not allocate %d bytes", sizeof(pmpkg_t));
- RET_ERR(PM_ERR_MEMORY, NULL);
+ if((pkg = (pmpkg_t *)malloc(sizeof(pmpkg_t))) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, (pmpkg_t *)-1);
}
if(name && name[0] != 0) {
@@ -57,12 +59,16 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
pkg->desc[0] = '\0';
pkg->url[0] = '\0';
pkg->license = NULL;
+ pkg->desc_localized = NULL;
pkg->builddate[0] = '\0';
+ pkg->buildtype[0] = '\0';
pkg->installdate[0] = '\0';
pkg->packager[0] = '\0';
pkg->md5sum[0] = '\0';
+ pkg->sha1sum[0] = '\0';
pkg->arch[0] = '\0';
pkg->size = 0;
+ pkg->usize = 0;
pkg->scriptlet = 0;
pkg->force = 0;
pkg->reason = PM_PKG_REASON_EXPLICIT;
@@ -71,6 +77,7 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
pkg->files = NULL;
pkg->backup = NULL;
pkg->depends = NULL;
+ pkg->removes = NULL;
pkg->groups = NULL;
pkg->provides = NULL;
pkg->replaces = NULL;
@@ -97,20 +104,25 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
STRNCPY(newpkg->desc, pkg->desc, PKG_DESC_LEN);
STRNCPY(newpkg->url, pkg->url, PKG_URL_LEN);
STRNCPY(newpkg->builddate, pkg->builddate, PKG_DATE_LEN);
+ STRNCPY(newpkg->buildtype, pkg->buildtype, PKG_DATE_LEN);
STRNCPY(newpkg->installdate, pkg->installdate, PKG_DATE_LEN);
STRNCPY(newpkg->packager, pkg->packager, PKG_PACKAGER_LEN);
STRNCPY(newpkg->md5sum, pkg->md5sum, PKG_MD5SUM_LEN);
+ STRNCPY(newpkg->sha1sum, pkg->sha1sum, PKG_SHA1SUM_LEN);
STRNCPY(newpkg->arch, pkg->arch, PKG_ARCH_LEN);
newpkg->size = pkg->size;
+ newpkg->usize = pkg->usize;
newpkg->force = pkg->force;
newpkg->scriptlet = pkg->scriptlet;
newpkg->reason = pkg->reason;
newpkg->license = _alpm_list_strdup(pkg->license);
+ newpkg->desc_localized = _alpm_list_strdup(pkg->desc_localized);
newpkg->requiredby = _alpm_list_strdup(pkg->requiredby);
newpkg->conflicts = _alpm_list_strdup(pkg->conflicts);
newpkg->files = _alpm_list_strdup(pkg->files);
newpkg->backup = _alpm_list_strdup(pkg->backup);
newpkg->depends = _alpm_list_strdup(pkg->depends);
+ newpkg->removes = _alpm_list_strdup(pkg->removes);
newpkg->groups = _alpm_list_strdup(pkg->groups);
newpkg->provides = _alpm_list_strdup(pkg->provides);
newpkg->replaces = _alpm_list_strdup(pkg->replaces);
@@ -131,9 +143,11 @@ void _alpm_pkg_free(void *data)
}
FREELIST(pkg->license);
+ FREELIST(pkg->desc_localized);
FREELIST(pkg->files);
FREELIST(pkg->backup);
FREELIST(pkg->depends);
+ FREELIST(pkg->removes);
FREELIST(pkg->conflicts);
FREELIST(pkg->requiredby);
FREELIST(pkg->groups);
@@ -185,7 +199,7 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
ptr = line;
key = strsep(&ptr, "=");
if(key == NULL || ptr == NULL) {
- _alpm_log(PM_LOG_ERROR, _("%s: syntax error in description file line %d"),
+ _alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
info->name[0] != '\0' ? info->name : "error", linenum);
} else {
_alpm_strtrim(key);
@@ -196,7 +210,18 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
} else if(!strcmp(key, "PKGVER")) {
STRNCPY(info->version, ptr, sizeof(info->version));
} else if(!strcmp(key, "PKGDESC")) {
- STRNCPY(info->desc, ptr, sizeof(info->desc));
+ char *lang_tmp;
+ info->desc_localized = _alpm_list_add(info->desc_localized, strdup(ptr));
+ if((lang_tmp = (char *)malloc(strlen(setlocale(LC_ALL, "")))) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ STRNCPY(lang_tmp, setlocale(LC_ALL, ""), strlen(setlocale(LC_ALL, "")));
+ if(info->desc_localized && !info->desc_localized->next) {
+ STRNCPY(info->desc, ptr, sizeof(info->desc));
+ } else if (ptr && !strncmp(ptr, lang_tmp, strlen(lang_tmp))) {
+ STRNCPY(info->desc, ptr+strlen(lang_tmp)+1, sizeof(info->desc));
+ }
+ FREE(lang_tmp);
} else if(!strcmp(key, "GROUP")) {
info->groups = _alpm_list_add(info->groups, strdup(ptr));
} else if(!strcmp(key, "URL")) {
@@ -205,6 +230,8 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
info->license = _alpm_list_add(info->license, strdup(ptr));
} else if(!strcmp(key, "BUILDDATE")) {
STRNCPY(info->builddate, ptr, sizeof(info->builddate));
+ } else if(!strcmp(key, "BUILDTYPE")) {
+ STRNCPY(info->buildtype, ptr, sizeof(info->buildtype));
} else if(!strcmp(key, "INSTALLDATE")) {
STRNCPY(info->installdate, ptr, sizeof(info->installdate));
} else if(!strcmp(key, "PACKAGER")) {
@@ -215,8 +242,14 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
char tmp[32];
STRNCPY(tmp, ptr, sizeof(tmp));
info->size = atol(tmp);
+ } else if(!strcmp(key, "USIZE")) {
+ char tmp[32];
+ STRNCPY(tmp, ptr, sizeof(tmp));
+ info->usize = atol(tmp);
} else if(!strcmp(key, "DEPEND")) {
info->depends = _alpm_list_add(info->depends, strdup(ptr));
+ } else if(!strcmp(key, "REMOVE")) {
+ info->removes = _alpm_list_add(info->removes, strdup(ptr));
} else if(!strcmp(key, "CONFLICT")) {
info->conflicts = _alpm_list_add(info->conflicts, strdup(ptr));
} else if(!strcmp(key, "REPLACES")) {
@@ -226,7 +259,7 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
} else if(!strcmp(key, "BACKUP")) {
info->backup = _alpm_list_add(info->backup, strdup(ptr));
} else {
- _alpm_log(PM_LOG_ERROR, _("%s: syntax error in description file line %d"),
+ _alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
info->name[0] != '\0' ? info->name : "error", linenum);
}
}
@@ -253,39 +286,34 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
RET_ERR(PM_ERR_WRONG_ARGS, NULL);
}
+ if ((archive = archive_read_new ()) == NULL)
+ RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+
+ archive_read_support_compression_all (archive);
+ archive_read_support_format_all (archive);
+
+ if (archive_read_open_file (archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK)
+ RET_ERR(PM_ERR_PKG_OPEN, NULL);
+
info = _alpm_pkg_new(NULL, NULL);
if(info == NULL) {
- return(NULL);
- }
- if(_alpm_pkg_splitname(pkgfile, info->name, info->version) == -1) {
- pm_errno = PM_ERR_PKG_INVALID_NAME;
- goto error;
- }
-
- if((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+ archive_read_finish (archive);
+ RET_ERR(PM_ERR_MEMORY, NULL);
}
- archive_read_support_compression_all(archive);
- archive_read_support_format_all(archive);
- if(archive_read_open_file(archive, pkgfile, 10240) != ARCHIVE_OK) {
- pm_errno = PM_ERR_NOT_A_FILE;
- goto error;
- }
- for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
+ for(i = 0; archive_read_next_header (archive, &entry) == ARCHIVE_OK; i++) {
if(config && filelist && scriptcheck) {
/* we have everything we need */
break;
}
- if(!strcmp(archive_entry_pathname(entry), ".PKGINFO")) {
+ if(!strcmp(archive_entry_pathname (entry), ".PKGINFO")) {
char *descfile;
int fd;
/* extract this file into /tmp. it has info for us */
descfile = strdup("/tmp/alpm_XXXXXX");
fd = mkstemp(descfile);
- _alpm_archive_read_entry_data_into_fd(archive, fd);
- close(fd);
+ archive_read_data_into_fd (archive, fd);
/* parse the info file */
if(parse_descfile(descfile, info, 0) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not parse the package description file"));
@@ -295,29 +323,43 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
close(fd);
goto error;
}
+ if(!strlen(info->name)) {
+ _alpm_log(PM_LOG_ERROR, _("missing package name in %s"), pkgfile);
+ pm_errno = PM_ERR_PKG_INVALID;
+ unlink(descfile);
+ FREE(descfile);
+ close(fd);
+ goto error;
+ }
+ if(!strlen(info->version)) {
+ _alpm_log(PM_LOG_ERROR, _("missing package version in %s"), pkgfile);
+ pm_errno = PM_ERR_PKG_INVALID;
+ unlink(descfile);
+ FREE(descfile);
+ close(fd);
+ goto error;
+ }
config = 1;
unlink(descfile);
FREE(descfile);
close(fd);
continue;
- } else if(!strcmp(archive_entry_pathname(entry), "._install") || !strcmp(archive_entry_pathname(entry), ".INSTALL")) {
+ } else if(!strcmp(archive_entry_pathname (entry), "._install") || !strcmp(archive_entry_pathname (entry), ".INSTALL")) {
info->scriptlet = 1;
scriptcheck = 1;
- } else if(!strcmp(archive_entry_pathname(entry), ".FILELIST")) {
+ } else if(!strcmp(archive_entry_pathname (entry), ".FILELIST")) {
/* Build info->files from the filelist */
FILE *fp;
char *fn;
char *str;
int fd;
- str = (char *)malloc(PATH_MAX);
- if(str == NULL) {
- RET_ERR(PM_ERR_MEMORY, NULL);
+ if((str = (char *)malloc(PATH_MAX)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, (pmpkg_t *)-1);
}
fn = strdup("/tmp/alpm_XXXXXX");
fd = mkstemp(fn);
- _alpm_archive_read_entry_data_into_fd(archive, fd);
- close(fd);
+ archive_read_data_into_fd (archive,fd);
fp = fopen(fn, "r");
while(!feof(fp)) {
if(fgets(str, PATH_MAX, fp) == NULL) {
@@ -340,18 +382,18 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
if(!filelist) {
/* no .FILELIST present in this package.. build the filelist the */
/* old-fashioned way, one at a time */
- expath = strdup(archive_entry_pathname(entry));
+ expath = strdup(archive_entry_pathname (entry));
info->files = _alpm_list_add(info->files, expath);
}
}
- if(archive_read_data_skip(archive)) {
+ if(archive_read_data_skip (archive)) {
_alpm_log(PM_LOG_ERROR, _("bad package file in %s"), pkgfile);
goto error;
}
expath = NULL;
}
- archive_read_finish(archive);
+ archive_read_finish (archive);
if(!config) {
_alpm_log(PM_LOG_ERROR, _("missing package info file in %s"), pkgfile);
@@ -367,7 +409,8 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
error:
FREEPKG(info);
- archive_read_finish(archive);
+ archive_read_finish (archive);
+
return(NULL);
}
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index ae286bce..31c217e0 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -2,6 +2,10 @@
* package.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -21,6 +25,9 @@
#ifndef _ALPM_PACKAGE_H
#define _ALPM_PACKAGE_H
+#if defined(__APPLE__) || defined(__sun__)
+#include <time.h>
+#endif
#include "list.h"
enum {
@@ -34,8 +41,10 @@ enum {
#define PKG_DESC_LEN 512
#define PKG_URL_LEN 256
#define PKG_DATE_LEN 32
+#define PKG_TYPE_LEN 32
#define PKG_PACKAGER_LEN 64
#define PKG_MD5SUM_LEN 33
+#define PKG_SHA1SUM_LEN 41
#define PKG_ARCH_LEN 32
typedef struct __pmpkg_t {
@@ -44,20 +53,26 @@ typedef struct __pmpkg_t {
char desc[PKG_DESC_LEN];
char url[PKG_URL_LEN];
char builddate[PKG_DATE_LEN];
+ char buildtype[PKG_TYPE_LEN];
char installdate[PKG_DATE_LEN];
char packager[PKG_PACKAGER_LEN];
char md5sum[PKG_MD5SUM_LEN];
+ char sha1sum[PKG_SHA1SUM_LEN];
char arch[PKG_ARCH_LEN];
unsigned long size;
+ unsigned long usize;
unsigned char scriptlet;
unsigned char force;
+ time_t date;
unsigned char reason;
+ PMList *desc_localized;
PMList *license;
PMList *replaces;
PMList *groups;
PMList *files;
PMList *backup;
PMList *depends;
+ PMList *removes;
PMList *requiredby;
PMList *conflicts;
PMList *provides;
diff --git a/lib/libalpm/po/LINGUAS b/lib/libalpm/po/LINGUAS
index cd849b16..cc891622 100644
--- a/lib/libalpm/po/LINGUAS
+++ b/lib/libalpm/po/LINGUAS
@@ -3,3 +3,6 @@
# This file is in the public domain.
#
# Set of available languages.
+de
+fr
+hu
diff --git a/lib/libalpm/po/Makefile.in.in b/lib/libalpm/po/Makefile.in.in
index dd08e989..6f2e2e94 100644
--- a/lib/libalpm/po/Makefile.in.in
+++ b/lib/libalpm/po/Makefile.in.in
@@ -18,19 +18,18 @@ SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
-top_builddir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
datadir = @datadir@
+datarootdir = @datarootdir@
localedir = $(datadir)/locale
gettextsrcdir = $(datadir)/gettext/po
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
-MKINSTALLDIRS = @MKINSTALLDIRS@
-mkinstalldirs = $(SHELL) $(MKINSTALLDIRS)
+mkinstalldirs = @INSTALL@ -d
GMSGFMT = @GMSGFMT@
MSGFMT = @MSGFMT@
diff --git a/lib/libalpm/po/Makevars b/lib/libalpm/po/Makevars
index 12e3233f..8499e269 100644
--- a/lib/libalpm/po/Makevars
+++ b/lib/libalpm/po/Makevars
@@ -20,7 +20,7 @@ XGETTEXT_OPTIONS = \
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
-COPYRIGHT_HOLDER = Judd Vinet
+COPYRIGHT_HOLDER = Yoyodyne, Inc.
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
@@ -36,7 +36,7 @@ COPYRIGHT_HOLDER = Judd Vinet
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
-MSGID_BUGS_ADDRESS = pacman-dev@archlinux.org
+MSGID_BUGS_ADDRESS = bug-gnu-gettext@gnu.org
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
diff --git a/lib/libalpm/po/POTFILES.in b/lib/libalpm/po/POTFILES.in
index 804d6270..093b3baa 100644
--- a/lib/libalpm/po/POTFILES.in
+++ b/lib/libalpm/po/POTFILES.in
@@ -16,6 +16,7 @@ md5driver.c
package.c
provide.c
remove.c
+sha1.c
sync.c
trans.c
util.c
diff --git a/lib/libalpm/po/libalpm.pot b/lib/libalpm/po/libalpm.pot
index 03bc06ad..2b294973 100644
--- a/lib/libalpm/po/libalpm.pot
+++ b/lib/libalpm/po/libalpm.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-05-31 12:01-0700\n"
+"POT-Creation-Date: 2006-09-03 13:36+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,281 +16,334 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../add.c:85
+#: ../add.c:95
#, c-format
msgid "could not parse token %s"
msgstr ""
-#: ../add.c:117
+#: ../add.c:127
#, c-format
msgid "loading target '%s'"
msgstr ""
-#: ../add.c:159
+#: ../add.c:169
#, c-format
msgid "replacing older version %s-%s by %s in target list"
msgstr ""
-#: ../add.c:168
+#: ../add.c:178
#, c-format
msgid "newer version %s-%s is in the target list -- skipping"
msgstr ""
-#: ../add.c:175
+#: ../add.c:185
#, c-format
msgid "reading '%s' metadata"
msgstr ""
#. look for unsatisfied dependencies
-#: ../add.c:214 ../remove.c:83
+#: ../add.c:227 ../remove.c:104
msgid "looking for unsatisfied dependencies"
msgstr ""
#. no unsatisfied deps, so look for conflicts
-#: ../add.c:226 ../sync.c:449
+#: ../add.c:239 ../sync.c:504
msgid "looking for conflicts"
msgstr ""
#. re-order w.r.t. dependencies
-#: ../add.c:238 ../remove.c:119
+#: ../add.c:251 ../remove.c:140
msgid "sorting by dependencies"
msgstr ""
-#: ../add.c:254
+#: ../add.c:263
+msgid "cleaning up"
+msgstr ""
+
+#: ../add.c:280
msgid "looking for file conflicts"
msgstr ""
-#: ../add.c:310
+#: ../add.c:345
#, c-format
msgid "upgrading package %s-%s"
msgstr ""
-#: ../add.c:316 ../alpm.c:447 ../conflict.c:273 ../conflict.c:303
+#: ../add.c:355 ../alpm.c:567 ../conflict.c:274 ../conflict.c:304
#, c-format
msgid "loading FILES info for '%s'"
msgstr ""
-#: ../add.c:324 ../alpm.c:427 ../alpm.c:555
+#: ../add.c:365 ../alpm.c:547 ../alpm.c:679 ../alpm.c:726
#, c-format
msgid "loading DESC info for '%s'"
msgstr ""
-#: ../add.c:336
+#: ../add.c:378
#, c-format
msgid "removing old package first (%s-%s)"
msgstr ""
-#: ../add.c:365
+#: ../add.c:408
#, c-format
msgid "adding package %s-%s"
msgstr ""
-#: ../add.c:372
+#: ../add.c:419
#, c-format
msgid "adding new package %s-%s"
msgstr ""
-#: ../add.c:376
+#: ../add.c:423
msgid "extracting files"
msgstr ""
-#: ../add.c:411
+#: ../add.c:438 ../util.c:456
+msgid "could not get current working directory"
+msgstr ""
+
+#: ../add.c:492
#, c-format
msgid "notice: %s is in NoExtract -- skipping extraction"
msgstr ""
-#: ../add.c:442 ../add.c:561 ../util.c:235
+#: ../add.c:528 ../add.c:681
#, c-format
msgid "could not extract %s (%s)"
msgstr ""
-#: ../add.c:473
+#: ../add.c:571
#, c-format
msgid "checking md5 hashes for %s"
msgstr ""
-#: ../add.c:474
+#: ../add.c:572 ../add.c:579
#, c-format
msgid "current: %s"
msgstr ""
-#: ../add.c:475
+#: ../add.c:573 ../add.c:580
#, c-format
msgid "new: %s"
msgstr ""
-#: ../add.c:477
+#: ../add.c:575 ../add.c:582
#, c-format
msgid "original: %s"
msgstr ""
-#: ../add.c:489
+#: ../add.c:578
+#, c-format
+msgid "checking sha1 hashes for %s"
+msgstr ""
+
+#: ../add.c:596
#, c-format
msgid "could not rename %s (%s)"
msgstr ""
-#: ../add.c:490
+#: ../add.c:597
#, c-format
msgid "error: could not rename %s (%s)"
msgstr ""
-#: ../add.c:493 ../add.c:530
+#: ../add.c:601 ../add.c:645
#, c-format
msgid "could not copy %s to %s (%s)"
msgstr ""
-#: ../add.c:494
+#: ../add.c:602
#, c-format
msgid "error: could not copy %s to %s (%s)"
msgstr ""
-#: ../add.c:497
+#: ../add.c:606
#, c-format
msgid "%s saved as %s.pacorig"
msgstr ""
-#: ../add.c:498
+#: ../add.c:607
#, c-format
msgid "warning: %s saved as %s"
msgstr ""
-#: ../add.c:508 ../add.c:511 ../add.c:517
+#: ../add.c:617 ../add.c:620 ../add.c:626
msgid "action: installing new file"
msgstr ""
-#: ../add.c:515
+#: ../add.c:624
msgid "action: leaving existing file in place"
msgstr ""
-#: ../add.c:520
-msgid "action: leaving file in place, installing new one as .pacnew"
+#: ../add.c:630
+msgid "action: keeping current file and installing new one with .pacnew ending"
msgstr ""
-#: ../add.c:523 ../add.c:548
+#: ../add.c:634
#, c-format
-msgid "extracting %s as %s.pacnew"
+msgid "could not install %s as %s: %s"
msgstr ""
-#: ../add.c:524 ../add.c:549
+#: ../add.c:635
#, c-format
-msgid "warning: extracting %s%s as %s"
+msgid "error: could not install %s as %s: %s"
msgstr ""
-#: ../add.c:528 ../add.c:544
+#: ../add.c:637
+#, c-format
+msgid "%s installed as %s"
+msgstr ""
+
+#: ../add.c:638
+#, c-format
+msgid "warning: %s installed as %s"
+msgstr ""
+
+#: ../add.c:643 ../add.c:663
#, c-format
msgid "extracting %s"
msgstr ""
-#: ../add.c:546
+#: ../add.c:665
#, c-format
msgid "%s is in NoUpgrade -- skipping"
msgstr ""
-#: ../add.c:562
+#: ../add.c:667
+#, c-format
+msgid "extracting %s as %s.pacnew"
+msgstr ""
+
+#: ../add.c:668
+#, c-format
+msgid "warning: extracting %s%s as %s"
+msgstr ""
+
+#: ../add.c:682
#, c-format
msgid "error: could not extract %s (%s)"
msgstr ""
-#: ../add.c:573
+#: ../add.c:693
msgid "appending backup entry"
msgstr ""
-#: ../add.c:593 ../add.c:595
+#: ../add.c:725 ../add.c:727
#, c-format
msgid "errors occurred while %s %s"
msgstr ""
-#: ../add.c:594 ../add.c:596
+#: ../add.c:726 ../add.c:728
msgid "upgrading"
msgstr ""
-#: ../add.c:594 ../add.c:596
+#: ../add.c:726 ../add.c:728
msgid "installing"
msgstr ""
-#: ../add.c:617 ../add.c:668
+#: ../add.c:749 ../add.c:800
#, c-format
msgid "adding '%s' in requiredby field for '%s'"
msgstr ""
#. remove the package from the database
-#: ../add.c:628 ../remove.c:247
+#: ../add.c:760 ../remove.c:284
msgid "updating database"
msgstr ""
-#: ../add.c:629
+#: ../add.c:761
#, c-format
msgid "adding database entry '%s'"
msgstr ""
-#: ../add.c:631
+#: ../add.c:763
#, c-format
msgid "could not update database entry %s-%s"
msgstr ""
-#: ../add.c:633
+#: ../add.c:765
#, c-format
msgid "error updating database for %s-%s!"
msgstr ""
-#: ../add.c:637
+#: ../add.c:769
#, c-format
msgid "could not add entry '%s' in cache"
msgstr ""
#. update dependency packages' REQUIREDBY fields
-#: ../add.c:642 ../remove.c:257
+#: ../add.c:774 ../remove.c:294
msgid "updating dependency packages 'requiredby' fields"
msgstr ""
-#: ../add.c:663 ../remove.c:285
+#: ../add.c:795 ../remove.c:322
#, c-format
msgid "could not find dependency '%s'"
msgstr ""
-#: ../add.c:671 ../remove.c:295
+#: ../add.c:803 ../remove.c:332
#, c-format
msgid "could not update 'requiredby' database entry %s-%s"
msgstr ""
-#. run ldconfig if it exists
-#: ../add.c:692 ../remove.c:307
+#: ../add.c:830 ../remove.c:345
#, c-format
msgid "running \"ldconfig -r %s\""
msgstr ""
-#: ../alpm.c:193
+#: ../alpm.c:201
#, c-format
msgid "registering database '%s'"
msgstr ""
-#: ../alpm.c:198
+#: ../alpm.c:206
#, c-format
msgid "database directory '%s' does not exist -- try creating it"
msgstr ""
-#: ../alpm.c:209
+#: ../alpm.c:217
#, c-format
msgid "opening database '%s'"
msgstr ""
-#: ../alpm.c:253
+#: ../alpm.c:261
#, c-format
msgid "unregistering database '%s'"
msgstr ""
-#: ../alpm.c:258
+#: ../alpm.c:266
#, c-format
msgid "closing database '%s'"
msgstr ""
+#: ../alpm.c:344
+#, c-format
+msgid ""
+"adding new server to database '%s': protocol '%s', server '%s', path '%s'"
+msgstr ""
+
+#: ../alpm.c:348
+#, c-format
+msgid "serverlist flushed for '%s'"
+msgstr ""
+
+#: ../alpm.c:383
+#, c-format
+msgid "failed to get lastupdate time for %s (no big deal)\n"
+msgstr ""
+
+#: ../alpm.c:402
+#, c-format
+msgid "sync: new mtime for %s: %s\n"
+msgstr ""
+
#. remove the old dir
-#: ../alpm.c:308
+#: ../alpm.c:408
#, c-format
msgid "flushing database %s/%s"
msgstr ""
-#: ../alpm.c:312
+#: ../alpm.c:412
#, c-format
msgid "could not remove database entry %s/%s"
msgstr ""
@@ -299,777 +352,1006 @@ msgstr ""
#. ORE
#. we should not simply unpack the archive, but better parse it and
#. db_write each entry (see sync_load_dbarchive to get archive content)
-#: ../alpm.c:326
+#: ../alpm.c:426
#, c-format
msgid "unpacking %s"
msgstr ""
-#: ../alpm.c:454
+#: ../alpm.c:574
#, c-format
msgid "loading SCRIPLET info for '%s'"
msgstr ""
-#: ../alpm.c:549
+#: ../alpm.c:673
#, c-format
-msgid "could not get md5 checksum for package %s-%s\n"
+msgid "could not get sha1 checksum for package %s-%s\n"
msgstr ""
-#: ../alpm.c:560
+#: ../alpm.c:684 ../alpm.c:731
#, c-format
msgid "checksums for package %s-%s are matching"
msgstr ""
-#: ../alpm.c:563
+#: ../alpm.c:687
+#, c-format
+msgid "sha1sums do not match for package %s-%s\n"
+msgstr ""
+
+#: ../alpm.c:720
+#, c-format
+msgid "could not get md5 checksum for package %s-%s\n"
+msgstr ""
+
+#: ../alpm.c:734
#, c-format
msgid "md5sums do not match for package %s-%s\n"
msgstr ""
-#: ../alpm.c:810
+#: ../alpm.c:993
#, c-format
msgid "could not remove lock file %s"
msgstr ""
-#: ../alpm.c:811
+#: ../alpm.c:994
#, c-format
msgid "warning: could not remove lock file %s"
msgstr ""
-#: ../be_files.c:142
+#: ../alpm.c:1232
+#, c-format
+msgid "config: new section '%s'\n"
+msgstr ""
+
+#: ../alpm.c:1275
+msgid "config: usesyslog\n"
+msgstr ""
+
+#: ../alpm.c:1286
+#, c-format
+msgid "config: including %s\n"
+msgstr ""
+
+#: ../alpm.c:1298 ../alpm.c:1306
+#, c-format
+msgid "config: noupgrade: %s\n"
+msgstr ""
+
+#: ../alpm.c:1316 ../alpm.c:1324
+#, c-format
+msgid "config: noextract: %s\n"
+msgstr ""
+
+#: ../alpm.c:1334 ../alpm.c:1342
+#, c-format
+msgid "config: ignorepkg: %s\n"
+msgstr ""
+
+#: ../alpm.c:1352 ../alpm.c:1360
+#, c-format
+msgid "config: holdpkg: %s\n"
+msgstr ""
+
+#: ../alpm.c:1370
+#, c-format
+msgid "config: dbpath: %s\n"
+msgstr ""
+
+#: ../alpm.c:1380
+#, c-format
+msgid "config: cachedir: %s\n"
+msgstr ""
+
+#: ../alpm.c:1386
+#, c-format
+msgid "config: log file: %s\n"
+msgstr ""
+
+#. The config value is in days, we use seconds
+#: ../alpm.c:1394
+#, c-format
+msgid "config: UpgradeDelay: %i\n"
+msgstr ""
+
+#. add to the list
+#: ../alpm.c:1415
+#, c-format
+msgid "config: %s: server: %s\n"
+msgstr ""
+
+#: ../be_files.c:151
#, c-format
msgid "invalid name for dabatase entry '%s'"
msgstr ""
-#: ../be_files.c:379
+#: ../be_files.c:432
#, c-format
msgid "db_write: could not open file %s/desc"
msgstr ""
-#: ../be_files.c:450
+#: ../be_files.c:517
#, c-format
msgid "db_write: could not open file %s/files"
msgstr ""
-#: ../be_files.c:476
+#: ../be_files.c:543
#, c-format
msgid "db_write: could not open file %s/depends"
msgstr ""
-#: ../cache.c:55
+#: ../cache.c:57
#, c-format
msgid "loading package cache (infolevel=%#x) for repository '%s'"
msgstr ""
-#: ../cache.c:75
+#: ../cache.c:77
#, c-format
msgid "freeing package cache for repository '%s'"
msgstr ""
-#: ../cache.c:110
+#: ../cache.c:112
#, c-format
msgid "adding entry '%s' in '%s' cache"
msgstr ""
-#: ../cache.c:132
+#: ../cache.c:134
#, c-format
msgid "removing entry '%s' from '%s' cache"
msgstr ""
-#: ../cache.c:163
+#: ../cache.c:165
#, c-format
msgid "loading group cache for repository '%s'"
msgstr ""
#. CHECK 1: check targets against database
-#: ../conflict.c:63
+#: ../conflict.c:71
#, c-format
msgid "checkconflicts: targ '%s' vs db"
msgstr ""
#. conflict
#. confict
-#: ../conflict.c:72 ../conflict.c:86
+#: ../conflict.c:80 ../conflict.c:94
#, c-format
msgid "targs vs db: found %s as a conflict for %s"
msgstr ""
#. CHECK 2: check targets against targets
-#: ../conflict.c:99
+#: ../conflict.c:107
#, c-format
msgid "checkconflicts: targ '%s' vs targs"
msgstr ""
#. otp is listed in tp's conflict list
-#: ../conflict.c:108 ../conflict.c:121
+#: ../conflict.c:116 ../conflict.c:129
#, c-format
msgid "targs vs targs: found %s as a conflict for %s"
msgstr ""
#. CHECK 3: check database against targets
-#: ../conflict.c:135
+#: ../conflict.c:143
#, c-format
msgid "checkconflicts: db vs targ '%s'"
msgstr ""
-#: ../conflict.c:162 ../conflict.c:177
+#: ../conflict.c:170 ../conflict.c:185
#, c-format
msgid "db vs targs: found %s as a conflict for %s"
msgstr ""
-#: ../conflict.c:226 ../conflict.c:335 ../deps.c:48 ../deps.c:568
-#: ../deps.c:608 ../group.c:40 ../handle.c:50 ../package.c:93 ../sync.c:58
-#: ../sync.c:580 ../sync.c:596 ../sync.c:692 ../trans.c:46
+#: ../conflict.c:234 ../conflict.c:335 ../deps.c:54 ../deps.c:601
+#: ../deps.c:641 ../group.c:42 ../handle.c:62 ../package.c:98 ../sync.c:65
+#: ../sync.c:635 ../sync.c:651 ../sync.c:747 ../trans.c:49 ../util.c:598
+#: ../util.c:605
#, c-format
msgid "malloc failure: could not allocate %d bytes"
msgstr ""
-#: ../db.c:47 ../db.c:54
+#: ../db.c:57 ../db.c:64
#, c-format
msgid "malloc failed: could not allocate %d bytes"
msgstr ""
-#: ../deps.c:116
+#: ../deps.c:118
+msgid "started sorting dependencies"
+msgstr ""
+
+#: ../deps.c:123
msgid "possible dependency cycle detected"
msgstr ""
-#: ../deps.c:243 ../deps.c:374
+#: ../deps.c:166
+msgid "sorting dependencies finished"
+msgstr ""
+
+#: ../deps.c:260 ../deps.c:406
#, c-format
msgid "checkdeps: found %s as required by %s"
msgstr ""
-#: ../deps.c:353
+#: ../deps.c:370
#, c-format
msgid "checkdeps: found %s as a dependency for %s"
msgstr ""
-#: ../deps.c:461
+#: ../deps.c:494
#, c-format
msgid "cannot find package \"%s\" or anything that provides it!"
msgstr ""
-#: ../deps.c:466
+#: ../deps.c:499
msgid "dep is NULL!"
msgstr ""
-#: ../deps.c:478
+#: ../deps.c:511
#, c-format
msgid "excluding %s -- explicitly installed"
msgstr ""
#. add it to the target list
-#: ../deps.c:495
+#: ../deps.c:528
#, c-format
msgid "loading ALL info for '%s'"
msgstr ""
-#: ../deps.c:498
+#: ../deps.c:531
#, c-format
msgid "adding '%s' to the targets"
msgstr ""
-#: ../deps.c:540
+#: ../deps.c:573
#, c-format
msgid "%s provides dependency %s -- skipping"
msgstr ""
-#: ../deps.c:564
+#: ../deps.c:597
#, c-format
msgid ""
"cannot resolve dependencies for \"%s\" (\"%s\" is not in the package set)"
msgstr ""
#. this dep is already in the target list
-#: ../deps.c:581
+#: ../deps.c:614
#, c-format
msgid "dependency %s is already in the target list -- skipping"
msgstr ""
-#: ../deps.c:601
+#: ../deps.c:634
#, c-format
msgid "pulling dependency %s (needed by %s)"
msgstr ""
-#: ../deps.c:605
+#: ../deps.c:638
#, c-format
msgid "cannot resolve dependencies for \"%s\""
msgstr ""
#. cycle detected -- skip it
-#: ../deps.c:621
+#: ../deps.c:654
#, c-format
msgid "dependency cycle detected: %s"
msgstr ""
-#: ../error.c:31
+#: ../error.c:34
msgid "out of memory!"
msgstr ""
-#: ../error.c:33 ../error.c:115
+#: ../error.c:36 ../error.c:135
msgid "unexpected error"
msgstr ""
-#: ../error.c:35
+#: ../error.c:38
msgid "insufficient privileges"
msgstr ""
-#: ../error.c:37
+#: ../error.c:40
msgid "wrong or NULL argument passed"
msgstr ""
-#: ../error.c:39
+#: ../error.c:42
msgid "could not find or read file"
msgstr ""
-#: ../error.c:42
+#: ../error.c:45
msgid "library not initialized"
msgstr ""
-#: ../error.c:44
+#: ../error.c:47
msgid "library already initialized"
msgstr ""
-#: ../error.c:46
+#: ../error.c:49
msgid "unable to lock database"
msgstr ""
-#: ../error.c:49
+#: ../error.c:52
msgid "could not open database"
msgstr ""
-#: ../error.c:51
+#: ../error.c:54
msgid "could not create database"
msgstr ""
-#: ../error.c:53
+#: ../error.c:56
msgid "database not initialized"
msgstr ""
-#: ../error.c:55
+#: ../error.c:58
msgid "database already registered"
msgstr ""
-#: ../error.c:57
+#: ../error.c:60
msgid "could not find database"
msgstr ""
-#: ../error.c:59
+#: ../error.c:62
msgid "could not update database"
msgstr ""
-#: ../error.c:61
+#: ../error.c:64
msgid "could not remove database entry"
msgstr ""
-#: ../error.c:68
+#: ../error.c:71
msgid "could not set parameter"
msgstr ""
-#: ../error.c:71 ../error.c:77
+#: ../error.c:74 ../error.c:80
msgid "transaction not initialized"
msgstr ""
-#: ../error.c:73
+#: ../error.c:76
msgid "transaction already initialized"
msgstr ""
-#: ../error.c:75
+#: ../error.c:78
msgid "duplicate target"
msgstr ""
-#: ../error.c:79
+#: ../error.c:82
msgid "transaction not prepared"
msgstr ""
-#: ../error.c:81
+#: ../error.c:84
msgid "transaction aborted"
msgstr ""
-#: ../error.c:83
+#: ../error.c:86
msgid "operation not compatible with the transaction type"
msgstr ""
-#: ../error.c:86
+#: ../error.c:89
msgid "could not find or read package"
msgstr ""
-#: ../error.c:88
+#: ../error.c:91
msgid "invalid or corrupted package"
msgstr ""
-#: ../error.c:90
+#: ../error.c:93
msgid "cannot open package file"
msgstr ""
-#: ../error.c:92
+#: ../error.c:95
msgid "cannot load package data"
msgstr ""
-#: ../error.c:94
+#: ../error.c:97
msgid "package already installed"
msgstr ""
-#: ../error.c:96
+#: ../error.c:99
msgid "package not installed or lesser version"
msgstr ""
-#: ../error.c:98
+#: ../error.c:101
msgid "package name is not valid"
msgstr ""
-#: ../error.c:101
+#: ../error.c:103
+msgid "corrupted package"
+msgstr ""
+
+#: ../error.c:106
msgid "group not found"
msgstr ""
-#: ../error.c:104
+#: ../error.c:109
msgid "could not satisfy dependencies"
msgstr ""
-#: ../error.c:106
+#: ../error.c:111
msgid "conflicting dependencies"
msgstr ""
-#: ../error.c:108
+#: ../error.c:113
msgid "conflicting files"
msgstr ""
-#: ../error.c:111
+#: ../error.c:116
msgid "user aborted"
msgstr ""
-#: ../error.c:113
+#: ../error.c:118
+msgid "libarchive error"
+msgstr ""
+
+#: ../error.c:120
msgid "internal error"
msgstr ""
-#: ../handle.c:127
+#: ../error.c:122
+msgid "not enough space"
+msgstr ""
+
+#: ../error.c:124
+msgid "not confirmed"
+msgstr ""
+
+#: ../error.c:127
+msgid "bad section name"
+msgstr ""
+
+#: ../error.c:129
+msgid "'local' is reserved and cannot be used as a package tree"
+msgstr ""
+
+#: ../error.c:131
+msgid "syntax error"
+msgstr ""
+
+#: ../error.c:133
+msgid "all directives must belong to a section"
+msgstr ""
+
+#: ../handle.c:143
#, c-format
msgid "PM_OPT_DBPATH set to '%s'"
msgstr ""
-#: ../handle.c:134
+#: ../handle.c:150
#, c-format
msgid "PM_OPT_CACHEDIR set to '%s'"
msgstr ""
-#: ../handle.c:151
+#: ../handle.c:167
#, c-format
msgid "can't open log file %s"
msgstr ""
-#: ../handle.c:155
+#: ../handle.c:171
#, c-format
msgid "PM_OPT_LOGFILE set to '%s'"
msgstr ""
-#: ../handle.c:160
+#: ../handle.c:176
#, c-format
msgid "'%s' added to PM_OPT_NOUPGRADE"
msgstr ""
-#: ../handle.c:163
+#: ../handle.c:179
msgid "PM_OPT_NOUPGRADE flushed"
msgstr ""
-#: ../handle.c:169
+#: ../handle.c:185
#, c-format
msgid "'%s' added to PM_OPT_NOEXTRACT"
msgstr ""
-#: ../handle.c:172
+#: ../handle.c:188
msgid "PM_OPT_NOEXTRACT flushed"
msgstr ""
-#: ../handle.c:178
+#: ../handle.c:194
#, c-format
msgid "'%s' added to PM_OPT_IGNOREPKG"
msgstr ""
-#: ../handle.c:181
+#: ../handle.c:197
msgid "PM_OPT_IGNOREPKG flushed"
msgstr ""
-#: ../handle.c:197
+#: ../handle.c:203
+#, c-format
+msgid "'%s' added to PM_OPT_HOLDPKG"
+msgstr ""
+
+#: ../handle.c:206
+msgid "PM_OPT_HOLDPKG flushed"
+msgstr ""
+
+#: ../handle.c:222
#, c-format
msgid "PM_OPT_USESYSLOG set to '%d'"
msgstr ""
-#: ../handle.c:204
+#: ../handle.c:262
#, c-format
msgid "PM_OPT_LOGMASK set to '%02x'"
msgstr ""
-#: ../md5driver.c:48
+#: ../handle.c:281
+#, c-format
+msgid "PM_OPT_PROXYHOST set to '%s'"
+msgstr ""
+
+#: ../handle.c:285
+#, c-format
+msgid "PM_OPT_PROXYPORT set to '%d'"
+msgstr ""
+
+#: ../handle.c:296
+#, c-format
+msgid "PM_OPT_XFERCOMMAND set to '%s'"
+msgstr ""
+
+#: ../handle.c:300
+#, c-format
+msgid "PM_OPT_NOPASSIVEFTP set to '%d'"
+msgstr ""
+
+#: ../handle.c:304
+#, c-format
+msgid "PM_OPT_CHOMP set to '%d'"
+msgstr ""
+
+#: ../md5driver.c:48 ../sha1.c:395
#, c-format
msgid "%s can't be opened\n"
msgstr ""
-#: ../package.c:173
+#: ../package.c:185
#, c-format
msgid "could not open file %s"
msgstr ""
-#: ../package.c:190 ../package.c:231
+#: ../package.c:202 ../package.c:262
#, c-format
msgid "%s: syntax error in description file line %d"
msgstr ""
-#: ../package.c:291
+#: ../package.c:319
msgid "could not parse the package description file"
msgstr ""
-#: ../package.c:331
+#: ../package.c:327
+#, c-format
+msgid "missing package name in %s"
+msgstr ""
+
+#: ../package.c:335
+#, c-format
+msgid "missing package version in %s"
+msgstr ""
+
+#: ../package.c:374
#, c-format
msgid "could not remove tempfile %s"
msgstr ""
-#: ../package.c:348
+#: ../package.c:391
#, c-format
msgid "bad package file in %s"
msgstr ""
-#: ../package.c:357
+#: ../package.c:399
#, c-format
msgid "missing package info file in %s"
msgstr ""
-#: ../remove.c:63
+#: ../remove.c:76
#, c-format
msgid "could not find %s in database"
msgstr ""
-#: ../remove.c:67
+#: ../remove.c:88
#, c-format
msgid "adding %s in the targets list"
msgstr ""
-#: ../remove.c:93
+#: ../remove.c:114
#, c-format
msgid "pulling %s in the targets list"
msgstr ""
-#: ../remove.c:96
+#: ../remove.c:117
#, c-format
msgid "could not find %s in database -- skipping"
msgstr ""
-#: ../remove.c:114
+#: ../remove.c:135
msgid "finding removable dependencies"
msgstr ""
-#: ../remove.c:154
+#: ../remove.c:180
#, c-format
msgid "removing package %s-%s"
msgstr ""
-#: ../remove.c:164
+#: ../remove.c:191
msgid "removing files"
msgstr ""
-#: ../remove.c:183
+#: ../remove.c:217
#, c-format
msgid "file %s does not exist"
msgstr ""
#. this is okay, other packages are probably using it.
-#: ../remove.c:189
+#: ../remove.c:223
#, c-format
msgid "keeping directory %s"
msgstr ""
-#: ../remove.c:191
+#: ../remove.c:225
#, c-format
msgid "removing directory %s"
msgstr ""
-#: ../remove.c:205
+#: ../remove.c:239
#, c-format
msgid "skipping removal of %s as it has moved to another package"
msgstr ""
-#: ../remove.c:217 ../remove.c:218
+#: ../remove.c:251 ../remove.c:252
#, c-format
msgid "%s saved as %s"
msgstr ""
-#: ../remove.c:220 ../remove.c:227
+#: ../remove.c:254 ../remove.c:261
#, c-format
msgid "unlinking %s"
msgstr ""
-#: ../remove.c:222 ../remove.c:229
+#: ../remove.c:256 ../remove.c:266
#, c-format
msgid "cannot remove file %s"
msgstr ""
-#: ../remove.c:248
+#: ../remove.c:285
#, c-format
msgid "removing database entry '%s'"
msgstr ""
-#: ../remove.c:250
+#: ../remove.c:287
#, c-format
msgid "could not remove database entry %s-%s"
msgstr ""
-#: ../remove.c:253
+#: ../remove.c:290
#, c-format
msgid "could not remove entry '%s' from cache"
msgstr ""
-#: ../remove.c:293
+#: ../remove.c:330
#, c-format
msgid "updating 'requiredby' field for package '%s'"
msgstr ""
#. check for "recommended" package replacements
-#: ../sync.c:142
+#: ../sync.c:160
msgid "checking for package replacements"
msgstr ""
-#: ../sync.c:151
+#: ../sync.c:169
#, c-format
msgid "checking replacement '%s' for package '%s'"
msgstr ""
-#: ../sync.c:153
+#: ../sync.c:171
#, c-format
msgid "%s-%s: ignoring package upgrade (to be replaced by %s-%s)"
msgstr ""
-#: ../sync.c:187
+#: ../sync.c:205
#, c-format
msgid "%s-%s elected for upgrade (to be replaced by %s-%s)"
msgstr ""
#. match installed packages with the sync dbs and compare versions
-#: ../sync.c:199
+#: ../sync.c:217
msgid "checking for package upgrades"
msgstr ""
-#: ../sync.c:211
+#: ../sync.c:229
#, c-format
msgid "'%s' not found in sync db -- skipping"
msgstr ""
-#: ../sync.c:225
+#: ../sync.c:243 ../sync.c:530
#, c-format
msgid "'%s' is already elected for removal -- skipping"
msgstr ""
#. local version is newer
-#: ../sync.c:234
+#: ../sync.c:252
#, c-format
msgid "%s-%s: local version is newer"
msgstr ""
#. package should be ignored (IgnorePkg)
-#: ../sync.c:240
+#: ../sync.c:258
#, c-format
msgid "%s-%s: ignoring package upgrade (%s)"
msgstr ""
-#: ../sync.c:243
+#. package too new (UpgradeDelay)
+#: ../sync.c:262
+#, c-format
+msgid "%s-%s: delaying upgrade of package (%s)\n"
+msgstr ""
+
+#: ../sync.c:266
#, c-format
msgid "%s-%s elected for upgrade (%s => %s)"
msgstr ""
#. Search provides
-#: ../sync.c:294 ../sync.c:313
+#: ../sync.c:317 ../sync.c:336
#, c-format
msgid "target '%s' not found -- looking for provisions"
msgstr ""
-#: ../sync.c:299 ../sync.c:318
+#: ../sync.c:322 ../sync.c:341
#, c-format
msgid "found '%s' as a provision for '%s'"
msgstr ""
-#: ../sync.c:337
+#: ../sync.c:360
#, c-format
msgid "%s-%s: local version is newer -- skipping"
msgstr ""
-#: ../sync.c:345
+#: ../sync.c:368
#, c-format
msgid "%s-%s is up to date -- skipping"
msgstr ""
-#: ../sync.c:365
+#: ../sync.c:388
#, c-format
msgid "adding target '%s' to the transaction set"
msgstr ""
-#: ../sync.c:405
+#: ../sync.c:433
msgid "resolving targets dependencies"
msgstr ""
-#: ../sync.c:424
+#: ../sync.c:453
#, c-format
msgid "adding package %s-%s to the transaction targets"
msgstr ""
-#: ../sync.c:430
+#: ../sync.c:485
msgid "looking for unresolvable dependencies"
msgstr ""
-#: ../sync.c:460
+#: ../sync.c:515
#, c-format
msgid "package '%s' is conflicting with '%s'"
msgstr ""
+#: ../sync.c:537
+#, c-format
+msgid "'%s' not found in transaction set -- skipping"
+msgstr ""
+
#. so just treat it like a "replaces" item so the REQUIREDBY
#. * fields are inherited properly.
#.
-#: ../sync.c:494
+#: ../sync.c:548
#, c-format
msgid "package '%s' provides its own conflict"
msgstr ""
-#: ../sync.c:517 ../sync.c:522
+#: ../sync.c:571 ../sync.c:576
#, c-format
msgid "'%s' is in the target list -- keeping it"
msgstr ""
-#: ../sync.c:532 ../sync.c:570
+#: ../sync.c:588 ../sync.c:625
#, c-format
msgid "removing '%s' from target list"
msgstr ""
#. It's a conflict -- see if they want to remove it
#.
-#: ../sync.c:542
+#: ../sync.c:597
#, c-format
msgid "resolving package '%s' conflict"
msgstr ""
#. append to the replaces list
-#: ../sync.c:565
+#: ../sync.c:620
#, c-format
msgid "electing '%s' for removal"
msgstr ""
#. abort
-#: ../sync.c:576 ../sync.c:592
+#: ../sync.c:631 ../sync.c:647
msgid "unresolvable package conflicts detected"
msgstr ""
-#: ../sync.c:658
+#: ../sync.c:699
+msgid "checking dependencies of packages designated for removal"
+msgstr ""
+
+#: ../sync.c:713
msgid "something has gone horribly wrong"
msgstr ""
#. found matching provisio -- we're good to go
-#: ../sync.c:677
+#: ../sync.c:732
#, c-format
msgid "found '%s' as a provision for '%s' -- conflict aborted"
msgstr ""
-#: ../sync.c:736
+#: ../sync.c:825
+#, c-format
+msgid "%s-%s-%s%s is already in the cache\n"
+msgstr ""
+
+#. no cache directory.... try creating it
+#: ../sync.c:837
+#, c-format
+msgid "no %s cache exists. creating...\n"
+msgstr ""
+
+#: ../sync.c:838
+#, c-format
+msgid "warning: no %s cache exists. creating..."
+msgstr ""
+
+#. couldn't mkdir the cache directory, so fall back to /tmp and unlink
+#. * the package afterwards.
+#.
+#: ../sync.c:843
+msgid "couldn't create package cache, using /tmp instead\n"
+msgstr ""
+
+#: ../sync.c:844
+msgid "warning: couldn't create package cache, using /tmp instead"
+msgstr ""
+
+#: ../sync.c:847
+#, c-format
+msgid "failed to set option CACHEDIR (%s)\n"
+msgstr ""
+
+#: ../sync.c:854
+#, c-format
+msgid "failed to retrieve some files from %s\n"
+msgstr ""
+
+#: ../sync.c:883 ../sync.c:895
+#, c-format
+msgid "can't get md5 or sha1 checksum for package %s\n"
+msgstr ""
+
+#: ../sync.c:914
+#, c-format
+msgid "archive %s was corrupted (bad MD5 or SHA1 checksum)\n"
+msgstr ""
+
+#: ../sync.c:916
+#, c-format
+msgid "archive %s is corrupted (bad MD5 or SHA1 checksum)\n"
+msgstr ""
+
+#: ../sync.c:936
msgid "could not create removal transaction"
msgstr ""
-#: ../sync.c:743
+#: ../sync.c:942
msgid "could not initialize the removal transaction"
msgstr ""
-#: ../sync.c:763
+#: ../sync.c:962
msgid "removing conflicting and to-be-replaced packages"
msgstr ""
-#: ../sync.c:765
+#: ../sync.c:964
msgid "could not prepare removal transaction"
msgstr ""
-#: ../sync.c:771
+#: ../sync.c:970
msgid "could not commit removal transaction"
msgstr ""
#. install targets
-#: ../sync.c:778
+#: ../sync.c:977
msgid "installing packages"
msgstr ""
-#: ../sync.c:781
+#: ../sync.c:980
msgid "could not create transaction"
msgstr ""
-#: ../sync.c:787
+#: ../sync.c:985
msgid "could not initialize transaction"
msgstr ""
-#: ../sync.c:806
+#: ../sync.c:1004
msgid "could not prepare transaction"
msgstr ""
-#: ../sync.c:810
+#: ../sync.c:1009
msgid "could not commit transaction"
msgstr ""
-#: ../sync.c:817
-msgid "updating database for replaced packages dependencies"
+#: ../sync.c:1016
+msgid "updating database for replaced packages' dependencies"
msgstr ""
-#: ../sync.c:846
+#: ../sync.c:1045
#, c-format
msgid "could not update requiredby for database entry %s-%s"
msgstr ""
-#: ../sync.c:855
+#: ../sync.c:1054
#, c-format
msgid "could not update new database entry %s-%s"
msgstr ""
-#: ../util.c:227
+#: ../util.c:285
#, c-format
-msgid "bad tar archive: %s"
+msgid "could not extract %s: %s\n"
msgstr ""
-#: ../util.c:383
+#: ../util.c:436
msgid "could not create temp directory"
msgstr ""
-#: ../util.c:403
-msgid "could not get current working directory"
-msgstr ""
-
-#: ../util.c:410
+#: ../util.c:463
#, c-format
msgid "could not change directory to %s (%s)"
msgstr ""
-#: ../util.c:413
+#: ../util.c:466
#, c-format
msgid "executing %s script..."
msgstr ""
-#: ../util.c:426
+#: ../util.c:479
#, c-format
msgid "could not fork a new process (%s)"
msgstr ""
-#: ../util.c:432
+#: ../util.c:486
#, c-format
msgid "chrooting in %s"
msgstr ""
-#: ../util.c:434
+#: ../util.c:488
#, c-format
msgid "could not change the root directory (%s)"
msgstr ""
-#: ../util.c:438
+#: ../util.c:492
#, c-format
msgid "could not change directory to / (%s)"
msgstr ""
-#: ../util.c:442
+#: ../util.c:496
#, c-format
msgid "executing \"%s\""
msgstr ""
-#: ../util.c:447
+#: ../util.c:499
+#, c-format
+msgid "call to popen failed (%s)"
+msgstr ""
+
+#: ../util.c:521
#, c-format
msgid "call to waitpid failed (%s)"
msgstr ""
-#: ../util.c:455
+#: ../util.c:529
#, c-format
msgid "could not remove tmpdir %s"
msgstr ""
+
+#: ../util.c:593
+#, c-format
+msgid "check_freespace: total pkg size: %lld, disk space: %lld"
+msgstr ""
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 4df9c7ba..d67807a7 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -2,6 +2,10 @@
* remove.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -19,6 +23,13 @@
* USA.
*/
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__)
+#include <sys/stat.h>
+#endif
+
#include "config.h"
#include <stdlib.h>
#include <errno.h>
@@ -28,12 +39,14 @@
#include <limits.h>
#include <zlib.h>
#include <libintl.h>
-#include <libtar.h>
/* pacman */
+#include "list.h"
+#include "trans.h"
#include "util.h"
#include "error.h"
#include "versioncmp.h"
#include "md5.h"
+#include "sha1.h"
#include "log.h"
#include "backup.h"
#include "package.h"
@@ -64,6 +77,15 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
+ /* ignore holdpkgs on upgrade */
+ if((trans == handle->trans) && _alpm_list_is_strin(info->name, handle->holdpkg)) {
+ int resp = 0;
+ QUESTION(trans, PM_TRANS_CONV_REMOVE_HOLDPKG, info, NULL, NULL, &resp);
+ if(!resp) {
+ RET_ERR(PM_ERR_PKG_HOLD, -1);
+ }
+ }
+
_alpm_log(PM_LOG_FLOW2, _("adding %s in the targets list"), info->name);
trans->packages = _alpm_list_add(trans->packages, info);
@@ -81,7 +103,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_FLOW1, _("looking for unsatisfied dependencies"));
- lp = _alpm_checkdeps(db, trans->type, trans->packages);
+ lp = _alpm_checkdeps(trans, db, trans->type, trans->packages);
if(lp != NULL) {
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
while(lp) {
@@ -98,7 +120,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data)
}
}
FREELIST(lp);
- lp = _alpm_checkdeps(db, trans->type, trans->packages);
+ lp = _alpm_checkdeps(trans, db, trans->type, trans->packages);
}
} else {
if(data) {
@@ -146,6 +168,7 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
for(targ = trans->packages; targ; targ = targ->next) {
+ int position = 0;
char pm_install[PATH_MAX];
info = (pmpkg_t*)targ->data;
@@ -160,21 +183,29 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
/* run the pre-remove scriptlet if it exists */
if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
snprintf(pm_install, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
- _alpm_runscriptlet(handle->root, pm_install, "pre_remove", info->version, NULL);
+ _alpm_runscriptlet(handle->root, pm_install, "pre_remove", info->version, NULL, trans);
}
}
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
+ int filenum = _alpm_list_count(info->files);
_alpm_log(PM_LOG_FLOW1, _("removing files"));
/* iterate through the list backwards, unlinking files */
for(lp = _alpm_list_last(info->files); lp; lp = lp->prev) {
int nb = 0;
+ double percent;
char *file = lp->data;
- char *md5 = _alpm_needbackup(file, info->backup);
- if(md5) {
+ char *md5 =_alpm_needbackup(file, info->backup);
+ char *sha1 =_alpm_needbackup(file, info->backup);
+
+ if (position != 0) {
+ percent = (double)position / filenum;
+ }
+ if(md5 && sha1) {
nb = 1;
- free(md5);
+ FREE(md5);
+ FREE(sha1);
}
if(!nb && trans->type == PM_TRANS_TYPE_UPGRADE) {
/* check noupgrade */
@@ -229,6 +260,9 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
}
} else {
_alpm_log(PM_LOG_FLOW2, _("unlinking %s"), file);
+ /* Need at here because we count only real unlinked files ? */
+ PROGRESS(trans, PM_TRANS_PROGRESS_REMOVE_START, info->name, (double)(percent * 100), _alpm_list_count(trans->packages), (_alpm_list_count(trans->packages) - _alpm_list_count(targ) +1));
+ position++;
if(unlink(line)) {
_alpm_log(PM_LOG_ERROR, _("cannot remove file %s"), file);
}
@@ -243,7 +277,7 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
char pm_install[PATH_MAX];
snprintf(pm_install, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
- _alpm_runscriptlet(handle->root, pm_install, "post_remove", info->version, NULL);
+ _alpm_runscriptlet(handle->root, pm_install, "post_remove", info->version, NULL, trans);
}
}
@@ -301,6 +335,7 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
}
}
+ PROGRESS(trans, PM_TRANS_PROGRESS_REMOVE_START, info->name, 100, _alpm_list_count(trans->packages), (_alpm_list_count(trans->packages) - _alpm_list_count(targ) +1));
if(trans->type != PM_TRANS_TYPE_UPGRADE) {
EVENT(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL);
}
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 05746bbc..27bb380e 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -2,6 +2,9 @@
* sync.c
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -24,6 +27,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
+#include <time.h>
#ifdef CYGWIN
#include <limits.h> /* PATH_MAX */
#endif
@@ -31,7 +35,6 @@
#include <libintl.h>
/* pacman */
#include "log.h"
-#include "util.h"
#include "error.h"
#include "list.h"
#include "package.h"
@@ -41,10 +44,16 @@
#include "conflict.h"
#include "provide.h"
#include "trans.h"
+#include "util.h"
#include "sync.h"
#include "versioncmp.h"
#include "handle.h"
+#include "util.h"
#include "alpm.h"
+#include "md5.h"
+#include "sha1.h"
+#include "handle.h"
+#include "server.h"
extern pmhandle_t *handle;
@@ -102,34 +111,13 @@ static pmsyncpkg_t *find_pkginsync(char *needle, PMList *haystack)
return(sync);
}
-/* It returns a PMList of packages extracted from the given archive
- * (the archive must have been generated by gensync)
- */
-PMList *_alpm_sync_load_dbarchive(char *archive)
+static int istoonew(pmpkg_t *pkg)
{
- PMList *lp = NULL;
- register struct archive *_archive;
- struct archive_entry *entry;
-
- if((_archive = archive_read_new()) == NULL) {
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
- goto error;
- }
- archive_read_support_compression_all(_archive);
- archive_read_support_format_all(_archive);
-
- if(archive_read_open_file(_archive, archive, 10240) != ARCHIVE_OK) {
- pm_errno = PM_ERR_NOT_A_FILE;
- goto error;
- }
-
- archive_read_finish(_archive);
-
- return(lp);
-
-error:
- archive_read_finish(_archive);
- return(NULL);
+ time_t t;
+ if (!handle->upgradedelay)
+ return 0;
+ time(&t);
+ return((pkg->date + handle->upgradedelay) > t);
}
int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
@@ -197,7 +185,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
_alpm_log(PM_LOG_FLOW1, _("checking for package upgrades"));
for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
int cmp;
- int replace = 0;
+ int replace=0;
pmpkg_t *local = i->data;
pmpkg_t *spkg = NULL;
pmsyncpkg_t *sync;
@@ -209,19 +197,19 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
_alpm_log(PM_LOG_DEBUG, _("'%s' not found in sync db -- skipping"), local->name);
continue;
}
-
+
/* we don't care about a to-be-replaced package's newer version */
- for(j = trans->packages; j && !replace; j = j->next) {
+ for(j = trans->packages; j && !replace; j=j->next) {
sync = j->data;
if(sync->type == PM_SYNC_TYPE_REPLACE) {
if(_alpm_pkg_isin(spkg->name, sync->data)) {
- replace = 1;
+ replace=1;
}
}
}
if(replace) {
_alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"),
- spkg->name);
+ local->name);
continue;
}
@@ -237,9 +225,14 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
/* package should be ignored (IgnorePkg) */
_alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (%s)"),
local->name, local->version, spkg->version);
+ } else if(istoonew(spkg)) {
+ /* package too new (UpgradeDelay) */
+ _alpm_log(PM_LOG_FLOW1, _("%s-%s: delaying upgrade of package (%s)\n"),
+ local->name, local->version, spkg->version);
+ /* check if spkg->name is already in the packages list. */
} else {
_alpm_log(PM_LOG_FLOW2, _("%s-%s elected for upgrade (%s => %s)"),
- local->name, local->version, local->version, spkg->version);
+ local->name, local->version, local->version, spkg->version);
if(!find_pkginsync(spkg->name, trans->packages)) {
pmpkg_t *dummy = _alpm_pkg_new(local->name, local->version);
if(dummy == NULL) {
@@ -367,20 +360,25 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, c
return(0);
}
-/* Helper function for _alpm_list_remove
+/* Helper functions for _alpm_list_remove
*/
static int ptr_cmp(const void *s1, const void *s2)
{
return(strcmp(((pmsyncpkg_t *)s1)->pkg->name, ((pmsyncpkg_t *)s2)->pkg->name));
}
+static int pkg_cmp(const void *p1, const void *p2)
+{
+ return(strcmp(((pmpkg_t *)p1)->name, ((pmsyncpkg_t *)p2)->pkg->name));
+}
+
int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data)
{
PMList *deps = NULL;
PMList *list = NULL; /* list allowing checkdeps usage with data from trans->packages */
PMList *trail = NULL; /* breadcrum list to avoid running into circles */
- PMList *asked = NULL;
- PMList *i, *j;
+ PMList *asked = NULL;
+ PMList *i, *j, *k, *l;
int ret = 0;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
@@ -409,6 +407,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
goto cleanup;
}
}
+
for(i = list; i; i = i->next) {
/* add the dependencies found by resolvedeps to the transaction set */
pmpkg_t *spkg = i->data;
@@ -420,13 +419,39 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
}
trans->packages = _alpm_list_add(trans->packages, sync);
_alpm_log(PM_LOG_FLOW2, _("adding package %s-%s to the transaction targets"),
- spkg->name, spkg->version);
+ spkg->name, spkg->version);
+ } else {
+ /* remove the original targets from the list if requested */
+ if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
+ pmpkg_t *p;
+ trans->packages = _alpm_list_remove(trans->packages, spkg, pkg_cmp, (void**)&p);
+ FREEPKG(p);
+ }
}
}
+
+ /* re-order w.r.t. dependencies */
+ k = l = NULL;
+ for(i=trans->packages; i; i=i->next) {
+ pmsyncpkg_t *s = (pmsyncpkg_t*)i->data;
+ k = _alpm_list_add(k, s->pkg);
+ }
+ k = _alpm_sortbydeps(k, PM_TRANS_TYPE_ADD);
+ for(i=k; i; i=i->next) {
+ for(j=trans->packages; j; j=j->next) {
+ pmsyncpkg_t *s = (pmsyncpkg_t*)j->data;
+ if(s->pkg==i->data) {
+ l = _alpm_list_add(l, s);
+ }
+ }
+ }
+ FREELISTPTR(trans->packages);
+ trans->packages = l;
+
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
_alpm_log(PM_LOG_FLOW1, _("looking for unresolvable dependencies"));
- deps = _alpm_checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
+ deps = _alpm_checkdeps(trans, db_local, PM_TRANS_TYPE_UPGRADE, list);
if(deps) {
if(data) {
*data = deps;
@@ -470,19 +495,18 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
}
}
if(found) {
- _alpm_log(PM_LOG_FLOW2, "'%s' is already elected for removal -- skipping",
- miss->depend.name);
+ _alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"),
+ miss->depend.name);
continue;
}
sync = find_pkginsync(miss->target, trans->packages);
if(sync == NULL) {
- _alpm_log(PM_LOG_DEBUG, "'%s' not found in transaction set -- skipping",
+ _alpm_log(PM_LOG_DEBUG, _("'%s' not found in transaction set -- skipping"),
miss->target);
continue;
}
local = _alpm_db_get_pkgfromcache(db_local, miss->depend.name);
-
/* check if this package also "provides" the package it's conflicting with
*/
if(_alpm_list_is_strin(miss->depend.name, sync->pkg->provides)) {
@@ -513,16 +537,18 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
depend = _alpm_list_is_strin(miss->depend.name, trans->targets);
if(depend && !target) {
_alpm_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"),
- miss->depend.name);
+ miss->depend.name);
/* remove miss->target */
rmpkg = miss->target;
} else if(target && !depend) {
_alpm_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"),
- miss->target);
+ miss->target);
/* remove miss->depend.name */
rmpkg = miss->depend.name;
} else {
- /* something's not right, bail out with a conflict error */
+ /* miss->depend.name is not needed, miss->target already provides
+ * it, let's resolve the conflict */
+ rmpkg = miss->depend.name;
}
if(rmpkg) {
pmsyncpkg_t *rsync = find_pkginsync(rmpkg, trans->packages);
@@ -534,9 +560,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
}
}
}
-
/* It's a conflict -- see if they want to remove it
- */
+ */
_alpm_log(PM_LOG_DEBUG, _("resolving package '%s' conflict"), miss->target);
if(local) {
int doremove = 0;
@@ -639,8 +664,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
}
}
if(list) {
- _alpm_log(PM_LOG_FLOW1, "checking dependencies of packages designated for removal");
- deps = _alpm_checkdeps(db_local, PM_TRANS_TYPE_REMOVE, list);
+ _alpm_log(PM_LOG_FLOW1, _("checking dependencies of packages designated for removal"));
+ deps = _alpm_checkdeps(trans, db_local, PM_TRANS_TYPE_REMOVE, list);
if(deps) {
int errorout = 0;
for(i = deps; i; i = i->next) {
@@ -673,7 +698,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
if(!strcmp(m->data, o->data)) {
/* found matching provisio -- we're good to go */
_alpm_log(PM_LOG_FLOW2, _("found '%s' as a provision for '%s' -- conflict aborted"),
- sp->pkg->name, (char *)o->data);
+ sp->pkg->name, (char *)o->data);
pfound = 1;
}
}
@@ -710,25 +735,172 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PML
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
}
+#ifndef __sun__
+ /* check for free space only in case the packages will be extracted */
+ if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) {
+ if(_alpm_check_freespace(trans, data) == -1) {
+ /* pm_errno is set by check_freespace */
+ ret = -1;
+ goto cleanup;
+ }
+ }
+#endif
+
cleanup:
FREELISTPTR(list);
FREELISTPTR(trail);
FREELIST(asked);
- FREELIST(deps);
return(ret);
}
int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
{
- PMList *i;
+ PMList *i, *j, *files = NULL;
pmtrans_t *tr = NULL;
- int replaces = 0;
+ int replaces = 0, retval = 0;
+ char ldir[PATH_MAX];
+ int varcache = 1;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ trans->state = STATE_DOWNLOADING;
+ /* group sync records by repository and download */
+ snprintf(ldir, PATH_MAX, "%s%s", handle->root, handle->cachedir);
+
+ for(i = handle->dbs_sync; i; i = i->next) {
+ pmdb_t *current = i->data;
+
+ for(j = trans->packages; j; j = j->next) {
+ pmsyncpkg_t *sync = j->data;
+ pmpkg_t *spkg = sync->pkg;
+ pmdb_t *dbs = spkg->data;
+
+ if(current == dbs) {
+ char path[PATH_MAX];
+
+ if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
+ snprintf(path, PATH_MAX, "%s-%s" PM_EXT_PKG, spkg->name, spkg->version);
+ EVENT(trans, PM_TRANS_EVT_PRINTURI, alpm_db_getinfo(current, PM_DB_FIRSTSERVER), path);
+ } else {
+ struct stat buf;
+ snprintf(path, PATH_MAX, "%s/%s-%s" PM_EXT_PKG, ldir, spkg->name, spkg->version);
+ if(stat(path, &buf)) {
+ /* file is not in the cache dir, so add it to the list */
+ snprintf(path, PATH_MAX, "%s-%s" PM_EXT_PKG, spkg->name, spkg->version);
+ files = _alpm_list_add(files, strdup(path));
+ } else {
+ _alpm_log(PM_LOG_DEBUG, _("%s-%s%s is already in the cache\n"),
+ spkg->name, spkg->version, PM_EXT_PKG);
+ }
+ }
+ }
+ }
+
+ if(files) {
+ struct stat buf;
+ EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL);
+ if(stat(ldir, &buf)) {
+ /* no cache directory.... try creating it */
+ _alpm_log(PM_LOG_WARNING, _("no %s cache exists. creating...\n"), ldir);
+ alpm_logaction(_("warning: no %s cache exists. creating..."), ldir);
+ if(_alpm_makepath(ldir)) {
+ /* couldn't mkdir the cache directory, so fall back to /tmp and unlink
+ * the package afterwards.
+ */
+ _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n"));
+ alpm_logaction(_("warning: couldn't create package cache, using /tmp instead"));
+ snprintf(ldir, PATH_MAX, "%s/tmp", handle->root);
+ if(_alpm_handle_set_option(handle, PM_OPT_CACHEDIR, (long)"/tmp") == -1) {
+ _alpm_log(PM_LOG_WARNING, _("failed to set option CACHEDIR (%s)\n"), alpm_strerror(pm_errno));
+ RET_ERR(PM_ERR_RETRIEVE, -1);
+ }
+ varcache = 0;
+ }
+ }
+ if(_alpm_downloadfiles(current->servers, ldir, files)) {
+ _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename);
+ RET_ERR(PM_ERR_RETRIEVE, -1);
+ }
+ FREELIST(files);
+ }
+ }
+ if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
+ return(0);
+ }
+
+ /* Check integrity of files */
+ EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL);
+
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ pmpkg_t *spkg = sync->pkg;
+ char str[PATH_MAX], pkgname[PATH_MAX];
+ char *md5sum1, *md5sum2, *sha1sum1, *sha1sum2;
+ char *ptr=NULL;
+
+ snprintf(pkgname, PATH_MAX, "%s-%s" PM_EXT_PKG,
+ spkg->name, spkg->version);
+ md5sum1 = spkg->md5sum;
+ sha1sum1 = spkg->sha1sum;
+
+ if((md5sum1 == NULL) && (sha1sum1 == NULL)) {
+ if((ptr = (char *)malloc(512)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ snprintf(ptr, 512, _("can't get md5 or sha1 checksum for package %s\n"), pkgname);
+ *data = _alpm_list_add(*data, ptr);
+ retval = 1;
+ continue;
+ }
+ snprintf(str, PATH_MAX, "%s/%s/%s", handle->root, handle->cachedir, pkgname);
+ md5sum2 = _alpm_MDFile(str);
+ sha1sum2 = _alpm_SHAFile(str);
+ if(md5sum2 == NULL && sha1sum2 == NULL) {
+ if((ptr = (char *)malloc(512)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ snprintf(ptr, 512, _("can't get md5 or sha1 checksum for package %s\n"), pkgname);
+ *data = _alpm_list_add(*data, ptr);
+ retval = 1;
+ continue;
+ }
+ if((strcmp(md5sum1, md5sum2) != 0) && (strcmp(sha1sum1, sha1sum2) != 0)) {
+ int doremove=0;
+ if((ptr = (char *)malloc(512)) == NULL) {
+ RET_ERR(PM_ERR_MEMORY, -1);
+ }
+ if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
+ doremove=1;
+ } else {
+ QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, pkgname, NULL, NULL, &doremove);
+ }
+ if(doremove) {
+ char str[PATH_MAX];
+ snprintf(str, PATH_MAX, "%s%s/%s-%s" PM_EXT_PKG, handle->root, handle->cachedir, spkg->name, spkg->version);
+ unlink(str);
+ snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 or SHA1 checksum)\n"), pkgname);
+ } else {
+ snprintf(ptr, 512, _("archive %s is corrupted (bad MD5 or SHA1 checksum)\n"), pkgname);
+ }
+ *data = _alpm_list_add(*data, ptr);
+ retval = 1;
+ }
+ FREE(md5sum2);
+ FREE(sha1sum2);
+ }
+ if(retval) {
+ pm_errno = PM_ERR_PKG_CORRUPTED;
+ goto error;
+ }
+ EVENT(trans, PM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL);
+ if(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY) {
+ return(0);
+ }
+
/* remove conflicting and to-be-replaced packages */
+ trans->state = STATE_COMMITING;
tr = _alpm_trans_new();
if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not create removal transaction"));
@@ -736,8 +908,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
goto error;
}
- if(_alpm_trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS,
- trans->cb_event, trans->cb_conv) == -1) {
+ if(_alpm_trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL, NULL) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not initialize the removal transaction"));
goto error;
}
@@ -780,8 +951,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
pm_errno = PM_ERR_MEMORY;
goto error;
}
- if(_alpm_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags | PM_TRANS_FLAG_NODEPS,
- trans->cb_event, trans->cb_conv) == -1) {
+ if(_alpm_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags | PM_TRANS_FLAG_NODEPS, trans->cb_event, trans->cb_conv, trans->cb_progress) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not initialize transaction"));
goto error;
}
@@ -802,6 +972,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
}
if(_alpm_trans_prepare(tr, data) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not prepare transaction"));
+ /* pm_errno is set by trans_prepare */
goto error;
}
if(_alpm_trans_commit(tr, NULL) == -1) {
@@ -812,7 +983,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
/* propagate replaced packages' requiredby fields to their new owners */
if(replaces) {
- _alpm_log(PM_LOG_FLOW1, _("updating database for replaced packages dependencies"));
+ _alpm_log(PM_LOG_FLOW1, _("updating database for replaced packages' dependencies"));
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
if(sync->type == PM_SYNC_TYPE_REPLACE) {
@@ -857,10 +1028,18 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, PMList **data)
}
}
+ if(!varcache && !(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
+ /* delete packages */
+ for(i = files; i; i = i->next) {
+ unlink(i->data);
+ }
+ }
return(0);
error:
FREETRANS(tr);
+ /* commiting failed, so this is still just a prepared transaction */
+ trans->state = STATE_PREPARED;
return(-1);
}
diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h
index 29d601b9..ffcfb6f6 100644
--- a/lib/libalpm/sync.h
+++ b/lib/libalpm/sync.h
@@ -2,6 +2,8 @@
* sync.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -36,8 +38,6 @@ typedef struct __pmsyncpkg_t {
pmsyncpkg_t *_alpm_sync_new(int type, pmpkg_t *spkg, void *data);
void _alpm_sync_free(void *data);
-PMList *_alpm_sync_load_dbarchive(char *archive);
-
int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync);
int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, char *name);
int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data);
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index ee546480..69fc69bb 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -1,7 +1,10 @@
/*
* trans.c
- *
+ *
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -54,6 +57,7 @@ pmtrans_t *_alpm_trans_new()
trans->flags = 0;
trans->cb_event = NULL;
trans->cb_conv = NULL;
+ trans->cb_progress = NULL;
trans->state = STATE_IDLE;
return(trans);
@@ -83,7 +87,7 @@ void _alpm_trans_free(void *data)
free(trans);
}
-int _alpm_trans_init(pmtrans_t *trans, unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv)
+int _alpm_trans_init(pmtrans_t *trans, unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv, alpm_trans_cb_progress progress)
{
/* Sanity checks */
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -92,6 +96,7 @@ int _alpm_trans_init(pmtrans_t *trans, unsigned char type, unsigned int flags, a
trans->flags = flags;
trans->cb_event = event;
trans->cb_conv = conv;
+ trans->cb_progress = progress;
trans->state = STATE_INITIALIZED;
return(0);
@@ -183,6 +188,9 @@ int _alpm_trans_prepare(pmtrans_t *trans, PMList **data)
int _alpm_trans_commit(pmtrans_t *trans, PMList **data)
{
+ if(data!=NULL)
+ *data = NULL;
+
/* Sanity checks */
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -191,7 +199,7 @@ int _alpm_trans_commit(pmtrans_t *trans, PMList **data)
return(0);
}
- trans->state = STATE_COMMITTING;
+ trans->state = STATE_COMMITING;
switch(trans->type) {
case PM_TRANS_TYPE_ADD:
@@ -215,7 +223,7 @@ int _alpm_trans_commit(pmtrans_t *trans, PMList **data)
break;
}
- trans->state = STATE_COMMITTED;
+ trans->state = STATE_COMMITED;
return(0);
}
diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h
index b60301c5..a0b72127 100644
--- a/lib/libalpm/trans.h
+++ b/lib/libalpm/trans.h
@@ -2,6 +2,9 @@
* trans.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -25,8 +28,9 @@ enum {
STATE_IDLE = 0,
STATE_INITIALIZED,
STATE_PREPARED,
- STATE_COMMITTING,
- STATE_COMMITTED,
+ STATE_DOWNLOADING,
+ STATE_COMMITING,
+ STATE_COMMITED,
STATE_INTERRUPTED
};
@@ -41,6 +45,7 @@ typedef struct __pmtrans_t {
PMList *skiplist; /* PMList of (char *) */
alpm_trans_cb_event cb_event;
alpm_trans_cb_conv cb_conv;
+ alpm_trans_cb_progress cb_progress;
} pmtrans_t;
#define FREETRANS(p) \
@@ -62,10 +67,16 @@ do { \
(t)->cb_conv(q, d1, d2, d3, r); \
} \
} while(0)
+#define PROGRESS(t, e, p, per, h, r) \
+do { \
+ if((t) && (t)->cb_progress) { \
+ (t)->cb_progress(e, p, per, h, r); \
+ } \
+} while(0)
pmtrans_t *_alpm_trans_new(void);
void _alpm_trans_free(void *data);
-int _alpm_trans_init(pmtrans_t *trans, unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv);
+int _alpm_trans_init(pmtrans_t *trans, unsigned char type, unsigned int flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv, alpm_trans_cb_progress progress);
int _alpm_trans_sysupgrade(pmtrans_t *trans);
int _alpm_trans_addtarget(pmtrans_t *trans, char *target);
int _alpm_trans_prepare(pmtrans_t *trans, PMList **data);
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 50b5c5de..c5ad162b 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1,7 +1,11 @@
/*
* util.c
- *
+ *
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -19,9 +23,19 @@
* USA.
*/
+#if defined(__APPLE__) || defined(__OpenBSD__)
+#include <sys/syslimits.h>
+#endif
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__)
+#include <sys/stat.h>
+#endif
+
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
+#ifdef __sun__
+#include <alloca.h>
+#endif
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
@@ -36,12 +50,75 @@
#ifdef CYGWIN
#include <limits.h> /* PATH_MAX */
#endif
+#include <sys/statvfs.h>
+#ifndef __sun__
+#include <mntent.h>
+#endif
+#include <regex.h>
+
/* pacman */
#include "log.h"
+#include "list.h"
+#include "trans.h"
+#include "sync.h"
#include "util.h"
#include "error.h"
#include "alpm.h"
+#ifdef __sun__
+/* This is a replacement for strsep which is not portable (missing on Solaris).
+ * Copyright (c) 2001 by François Gouget <fgouget_at_codeweavers.com> */
+char* strsep(char** str, const char* delims)
+{
+ char* token;
+
+ if (*str==NULL) {
+ /* No more tokens */
+ return NULL;
+ }
+
+ token=*str;
+ while (**str!='\0') {
+ if (strchr(delims,**str)!=NULL) {
+ **str='\0';
+ (*str)++;
+ return token;
+ }
+ (*str)++;
+ }
+ /* There is no other token */
+ *str=NULL;
+ return token;
+}
+
+/* Backported from Solaris Express 4/06
+ * Copyright (c) 2006 Sun Microsystems, Inc. */
+char * mkdtemp(char *template)
+{
+ char *t = alloca(strlen(template) + 1);
+ char *r;
+
+ /* Save template */
+ (void) strcpy(t, template);
+ for (; ; ) {
+ r = mktemp(template);
+
+ if (*r == '\0')
+ return (NULL);
+
+ if (mkdir(template, 0700) == 0)
+ return (r);
+
+ /* Other errors indicate persistent conditions. */
+ if (errno != EEXIST)
+ return (NULL);
+
+ /* Reset template */
+ (void) strcpy(template, t);
+ }
+}
+#endif
+
/* does the same thing as 'mkdir -p' */
int _alpm_makepath(char *path)
{
@@ -122,7 +199,7 @@ char *_alpm_strtrim(char *str)
return(str);
}
- while(isspace(*pch)) {
+ while(isspace((int)*pch)) {
pch++;
}
if(pch != str) {
@@ -135,7 +212,7 @@ char *_alpm_strtrim(char *str)
}
pch = (char *)(str + (strlen(str) - 1));
- while(isspace(*pch)) {
+ while(isspace((int)*pch)) {
pch--;
}
*++pch = '\0';
@@ -148,6 +225,15 @@ char *_alpm_strtrim(char *str)
int _alpm_lckmk(char *file)
{
int fd, count = 0;
+ char *dir, *ptr;
+
+ /* create the dir of the lockfile first */
+ dir = strdup(file);
+ ptr = strrchr(dir, '/');
+ if(ptr) {
+ *ptr = '\0';
+ }
+ _alpm_makepath(dir);
while((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -1 && errno == EACCES) {
if(++count < 1) {
@@ -170,56 +256,43 @@ int _alpm_lckrm(char *file)
return(0);
}
+/* Compression functions
+ */
+
int _alpm_unpack(char *archive, const char *prefix, const char *fn)
{
register struct archive *_archive;
struct archive_entry *entry;
char expath[PATH_MAX];
- if((_archive = archive_read_new()) == NULL) {
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
- return(1);
- }
+ if ((_archive = archive_read_new ()) == NULL)
+ RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
+
archive_read_support_compression_all(_archive);
- archive_read_support_format_all(_archive);
- /* open the .tar.gz package */
- if(archive_read_open_file(_archive, archive, 10240) != ARCHIVE_OK) {
- perror(archive);
- return(1);
- }
- while(!archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
- if(fn && strcmp(fn, archive_entry_pathname(entry))) {
- if(archive_read_data_skip(_archive) != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("bad archive: %s"), archive);
+ archive_read_support_format_all (_archive);
+
+ if (archive_read_open_file (_archive, archive, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK)
+ RET_ERR(PM_ERR_PKG_OPEN, -1);
+
+ while (archive_read_next_header (_archive, &entry) == ARCHIVE_OK) {
+ if (fn && strcmp (fn, archive_entry_pathname (entry))) {
+ if (archive_read_data_skip (_archive) != ARCHIVE_OK)
return(1);
- }
continue;
}
- snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname(entry));
- if(archive_read_extract(_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), archive_entry_pathname(entry), archive_error_string(_archive));
- return(1);
+ snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname (entry));
+ archive_entry_set_pathname (entry, expath);
+ if (archive_read_extract (_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) {
+ fprintf(stderr, _("could not extract %s: %s\n"), archive_entry_pathname (entry), archive_error_string (_archive));
+ return(1);
}
- if(fn) break;
- }
- archive_read_finish(_archive);
- return(0);
-}
-
-int _alpm_archive_read_entry_data_into_fd(struct archive *archive, int fd)
-{
- register size_t length;
- char cache[10240];
-
- if(fd == -1) {
- return ARCHIVE_RETRY;
- }
- while((length = archive_read_data(archive, &cache, sizeof(cache))) > 0) {
- write(fd, cache, length);
+ if (fn)
+ break;
}
- return ARCHIVE_OK;
+ archive_read_finish (_archive);
+ return(0);
}
/* does the same thing as 'rm -rf' */
@@ -338,7 +411,7 @@ static int grep(const char *fn, const char *needle)
return(0);
}
-int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, char *oldver)
+int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, char *oldver, pmtrans_t *trans)
{
char scriptfn[PATH_MAX];
char cmdline[PATH_MAX];
@@ -410,6 +483,7 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha
}
if(pid == 0) {
+ FILE *pp;
_alpm_log(PM_LOG_DEBUG, _("chrooting in %s"), root);
if(chroot(root) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)"), strerror(errno));
@@ -421,7 +495,27 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha
}
umask(0022);
_alpm_log(PM_LOG_DEBUG, _("executing \"%s\""), cmdline);
- execl("/bin/sh", "sh", "-c", cmdline, (char *)0);
+ pp = popen(cmdline, "r");
+ if(!pp) {
+ _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)"), strerror(errno));
+ retval = 1;
+ goto cleanup;
+ }
+ while(!feof(pp)) {
+ char line[1024];
+ if(fgets(line, 1024, pp) == NULL)
+ break;
+ /* "START <event desc>" */
+ if((strlen(line) > strlen(STARTSTR)) && !strncmp(line, STARTSTR, strlen(STARTSTR))) {
+ EVENT(trans, PM_TRANS_EVT_SCRIPTLET_START, _alpm_strtrim(line + strlen(STARTSTR)), NULL);
+ /* "DONE <ret code>" */
+ } else if((strlen(line) > strlen(DONESTR)) && !strncmp(line, DONESTR, strlen(DONESTR))) {
+ EVENT(trans, PM_TRANS_EVT_SCRIPTLET_DONE, (void*)atol(_alpm_strtrim(line + strlen(DONESTR))), NULL);
+ } else {
+ EVENT(trans, PM_TRANS_EVT_SCRIPTLET_INFO, _alpm_strtrim(line), NULL);
+ }
+ }
+ pclose(pp);
exit(0);
} else {
if(waitpid(pid, 0, 0) == -1) {
@@ -442,4 +536,90 @@ cleanup:
return(retval);
}
+#ifndef __sun__
+static long long get_freespace()
+{
+ struct mntent *mnt;
+ char *table = MOUNTED;
+ FILE *fp;
+ long long ret=0;
+
+ fp = setmntent (table, "r");
+ if(!fp)
+ return(-1);
+ while ((mnt = getmntent (fp)))
+ {
+ struct statvfs64 buf;
+
+ statvfs64(mnt->mnt_dir, &buf);
+ ret += buf.f_bavail * buf.f_bsize;
+ }
+ return(ret);
+}
+
+int _alpm_check_freespace(pmtrans_t *trans, PMList **data)
+{
+ PMList *i;
+ long long pkgsize=0, freespace;
+
+ for(i = trans->packages; i; i = i->next) {
+ if(trans->type == PM_TRANS_TYPE_SYNC)
+ {
+ pmsyncpkg_t *sync = i->data;
+ if(sync->type != PM_SYNC_TYPE_REPLACE) {
+ pmpkg_t *pkg = sync->pkg;
+ pkgsize += pkg->usize;
+ }
+ }
+ else
+ {
+ pmpkg_t *pkg = i->data;
+ pkgsize += pkg->size;
+ }
+ }
+ freespace = get_freespace();
+ _alpm_log(PM_LOG_DEBUG, _("check_freespace: total pkg size: %lld, disk space: %lld"), pkgsize, freespace);
+ if(pkgsize > freespace) {
+ if(data) {
+ long long *ptr;
+ if((ptr = (long long*)malloc(sizeof(long long)))==NULL) {
+ _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long));
+ pm_errno = PM_ERR_MEMORY;
+ return(-1);
+ }
+ *ptr = pkgsize;
+ *data = _alpm_list_add(*data, ptr);
+ if((ptr = (long long*)malloc(sizeof(long long)))==NULL) {
+ _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long));
+ FREELIST(*data);
+ pm_errno = PM_ERR_MEMORY;
+ return(-1);
+ }
+ *ptr = freespace;
+ *data = _alpm_list_add(*data, ptr);
+ }
+ pm_errno = PM_ERR_DISK_FULL;
+ return(-1);
+ }
+ else {
+ return(0);
+ }
+}
+
+/* match a string against a regular expression */
+int _alpm_reg_match(char *string, char *pattern)
+{
+ int result;
+ regex_t reg;
+
+ if(regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE) != 0) {
+ RET_ERR(PM_ERR_INVALID_REGEX, -1);
+ }
+ result = regexec(&reg, string, 0, 0, 0);
+ regfree(&reg);
+ return(!(result));
+}
+
+#endif
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 9b0c9a0d..205facae 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -2,6 +2,10 @@
* util.h
*
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
+ * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -22,8 +26,13 @@
#define _ALPM_UTIL_H
#include <stdio.h>
+#if defined(__OpenBSD__)
+#include "/usr/local/include/archive.h"
+#include "/usr/local/include/archive_entry.h"
+#else
#include <archive.h>
#include <archive_entry.h>
+#endif
#define FREE(p) do { if (p) { free(p); p = NULL; } } while(0)
@@ -34,10 +43,17 @@
s1[(len)-1] = 0; \
} while(0)
-#define _(str) dgettext("libalpm", str)
-
#define ARCHIVE_EXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME
+#ifdef ENABLE_NLS
+#define _(str) dgettext ("libalpm", str)
+#else
+#define _(s) s
+#endif
+
+#define STARTSTR "START "
+#define DONESTR "DONE "
+
int _alpm_makepath(char *path);
int _alpm_copyfile(char *src, char *dest);
char *_alpm_strtoupper(char *str);
@@ -46,10 +62,19 @@ int _alpm_lckmk(char *file);
int _alpm_lckrm(char *file);
int _alpm_unpack(char *archive, const char *prefix, const char *fn);
int _alpm_rmrf(char *path);
-int _alpm_archive_read_entry_data_into_fd(struct archive *archive, int fd);
int _alpm_logaction(unsigned char usesyslog, FILE *f, char *fmt, ...);
int _alpm_ldconfig(char *root);
-int _alpm_runscriptlet(char *util, char *installfn, char *script, char *ver, char *oldver);
+#ifdef _ALPM_TRANS_H
+int _alpm_runscriptlet(char *util, char *installfn, char *script, char *ver, char *oldver, pmtrans_t *trans);
+#ifndef __sun__
+int _alpm_check_freespace(pmtrans_t *trans, PMList **data);
+#endif
+#endif
+int _alpm_reg_match(char *string, char *pattern);
+#ifdef __sun__
+char* strsep(char** str, const char* delims);
+char* mkdtemp(char *template);
+#endif
#endif /* _ALPM_UTIL_H */
diff --git a/lib/libalpm/versioncmp.c b/lib/libalpm/versioncmp.c
index 71b1f4ad..652b7efb 100644
--- a/lib/libalpm/versioncmp.c
+++ b/lib/libalpm/versioncmp.c
@@ -1,7 +1,9 @@
/*
* versioncmp.c
- *
+ *
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -141,122 +143,96 @@ static int strverscmp (s1, s2)
#endif
/* this function was taken from rpm 4.0.4 and rewritten */
-int _alpm_versioncmp(const char *a, const char *b) {
- char *str1, *ostr1, *str2, *ostr2;
+int _alpm_versioncmp(const char *a, const char *b)
+{
+ char str1[64], str2[64];
+ char *ptr1, *ptr2;
char *one, *two;
char *rel1 = NULL, *rel2 = NULL;
char oldch1, oldch2;
int is1num, is2num;
- int rc, rv;
-
- if (!strcmp(a,b)) {
+ int rc;
+
+ if(!strcmp(a,b)) {
return(0);
}
- str1 = strdup(a);
- ostr1 = str1;
- str2 = strdup(b);
- ostr2 = str2;
+ strncpy(str1, a, 64);
+ str1[63] = 0;
+ strncpy(str2, b, 64);
+ str2[63] = 0;
/* lose the release number */
for(one = str1; *one && *one != '-'; one++);
- if(*one) {
+ if(one) {
*one = '\0';
rel1 = ++one;
- if (*rel1 == '\0')
- rel1 = NULL;
}
for(two = str2; *two && *two != '-'; two++);
- if(*two) {
+ if(two) {
*two = '\0';
rel2 = ++two;
- if (*rel2 == '\0')
- rel2 = NULL;
}
one = str1;
two = str2;
while(*one || *two) {
- while(*one && !isalnum(*one)) one++;
- while(*two && !isalnum(*two)) two++;
+ while(*one && !isalnum((int)*one)) one++;
+ while(*two && !isalnum((int)*two)) two++;
- str1 = one;
- str2 = two;
+ ptr1 = one;
+ ptr2 = two;
/* find the next segment for each string */
- if(isdigit(*str1)) {
+ if(isdigit((int)*ptr1)) {
is1num = 1;
- while(*str1 && isdigit(*str1)) str1++;
+ while(*ptr1 && isdigit((int)*ptr1)) ptr1++;
} else {
is1num = 0;
- while(*str1 && isalpha(*str1)) str1++;
+ while(*ptr1 && isalpha((int)*ptr1)) ptr1++;
}
- if(isdigit(*str2)) {
+ if(isdigit((int)*ptr2)) {
is2num = 1;
- while(*str2 && isdigit(*str2)) str2++;
+ while(*ptr2 && isdigit((int)*ptr2)) ptr2++;
} else {
is2num = 0;
- while(*str2 && isalpha(*str2)) str2++;
+ while(*ptr2 && isalpha((int)*ptr2)) ptr2++;
}
- oldch1 = *str1;
- *str1 = '\0';
- oldch2 = *str2;
- *str2 = '\0';
+ oldch1 = *ptr1;
+ *ptr1 = '\0';
+ oldch2 = *ptr2;
+ *ptr2 = '\0';
/* see if we ran out of segments on one string */
- if(one == str1 && two != str2) {
- free(ostr1);
- free(ostr2);
+ if(one == ptr1 && two != ptr2) {
return(is2num ? -1 : 1);
}
- if(one != str1 && two == str2) {
- free(ostr1);
- free(ostr2);
+ if(one != ptr1 && two == ptr2) {
return(is1num ? 1 : -1);
}
/* see if we have a type mismatch (ie, one is alpha and one is digits) */
- if(is1num && !is2num) {
- free(ostr1);
- free(ostr2);
- return(1);
- }
- if(!is1num && is2num) {
- free(ostr1);
- free(ostr2);
- return(-1);
- }
+ if(is1num && !is2num) return(1);
+ if(!is1num && is2num) return(-1);
if(is1num) while(*one == '0') one++;
if(is2num) while(*two == '0') two++;
rc = strverscmp(one, two);
- if(rc) {
- free(ostr1);
- free(ostr2);
- return(rc);
- }
+ if(rc) return(rc);
- *str1 = oldch1;
- *str2 = oldch2;
- one = str1;
- two = str2;
+ *ptr1 = oldch1;
+ *ptr2 = oldch2;
+ one = ptr1;
+ two = ptr2;
}
if((!*one) && (!*two)) {
/* compare release numbers */
- if(rel1 && rel2) {
- rv = _alpm_versioncmp(rel1, rel2);
- free(ostr1);
- free(ostr2);
- return rv;
- } else {
- free(ostr1);
- free(ostr2);
- return(0);
- }
+ if(rel1 && rel2) return(_alpm_versioncmp(rel1, rel2));
+ return(0);
}
return(*one ? 1 : -1);
diff --git a/lib/libalpm/versioncmp.h b/lib/libalpm/versioncmp.h
index 49b70cd6..ada2921a 100644
--- a/lib/libalpm/versioncmp.h
+++ b/lib/libalpm/versioncmp.h
@@ -1,7 +1,9 @@
/*
* versioncmp.h
*
- * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
+ * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.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
@@ -18,8 +20,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
-#ifndef _PM_VERSIONCMP_H
-#define _PM_VERSIONCMP_H
+#ifndef _PM_RPMVERCMP_H
+#define _PM_RPMVERCMP_H
int _alpm_versioncmp(const char *a, const char *b);