diff options
author | Aaron Griffin <aaron@archlinux.org> | 2006-10-15 19:31:03 +0000 |
---|---|---|
committer | Aaron Griffin <aaron@archlinux.org> | 2006-10-15 19:31:03 +0000 |
commit | d37ad048732fbcef38aec001993553896dbe4198 (patch) | |
tree | c80472214aae0cd94c32ac00d613d38d51bc1adf /lib | |
parent | 83381bd21748d79f46247fab17877bc5c440a8de (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')
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(®, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE) != 0) { + RET_ERR(PM_ERR_INVALID_REGEX, -1); + } + result = regexec(®, string, 0, 0, 0); + regfree(®); + 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); |