2006-03-02 14:06:52 -05:00
|
|
|
/*
|
|
|
|
* be_files.c
|
2007-11-16 21:18:45 -05:00
|
|
|
*
|
2006-10-15 15:31:03 -04:00
|
|
|
* Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu>
|
|
|
|
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
2007-11-16 21:18:45 -05:00
|
|
|
*
|
2006-03-02 14:06:52 -05:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2007-12-10 23:55:22 -05:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2006-03-02 14:06:52 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
2007-03-05 17:13:33 -05:00
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2009-11-14 14:26:37 -05:00
|
|
|
#include <stdint.h> /* intmax_t */
|
2006-03-02 14:06:52 -05:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <dirent.h>
|
2007-09-19 01:21:56 -04:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <time.h>
|
2006-03-02 14:06:52 -05:00
|
|
|
#include <limits.h> /* PATH_MAX */
|
2007-11-20 12:01:56 -05:00
|
|
|
#include <locale.h> /* setlocale */
|
2007-03-05 17:13:33 -05:00
|
|
|
|
2009-10-09 13:11:27 -04:00
|
|
|
/* libarchive */
|
|
|
|
#include <archive.h>
|
|
|
|
#include <archive_entry.h>
|
|
|
|
|
2007-03-05 17:13:33 -05:00
|
|
|
/* libalpm */
|
|
|
|
#include "db.h"
|
|
|
|
#include "alpm_list.h"
|
2008-05-11 20:29:23 -04:00
|
|
|
#include "cache.h"
|
2006-03-02 14:06:52 -05:00
|
|
|
#include "log.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "alpm.h"
|
2006-10-15 15:31:03 -04:00
|
|
|
#include "handle.h"
|
2006-11-20 04:10:23 -05:00
|
|
|
#include "package.h"
|
2007-10-19 13:17:51 -04:00
|
|
|
#include "delta.h"
|
2007-11-13 00:01:14 -05:00
|
|
|
#include "deps.h"
|
2008-05-11 20:29:23 -04:00
|
|
|
#include "dload.h"
|
2006-10-15 15:31:03 -04:00
|
|
|
|
2006-10-25 14:15:25 -04:00
|
|
|
|
2009-01-19 16:54:00 -05:00
|
|
|
static int checkdbdir(pmdb_t *db)
|
|
|
|
{
|
|
|
|
struct stat buf;
|
2009-09-14 23:44:51 -04:00
|
|
|
const char *path = _alpm_db_path(db);
|
2009-01-19 16:54:00 -05:00
|
|
|
|
|
|
|
if(stat(path, &buf) != 0) {
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
|
|
|
|
path);
|
|
|
|
if(_alpm_makepath(path) != 0) {
|
|
|
|
RET_ERR(PM_ERR_SYSTEM, -1);
|
|
|
|
}
|
|
|
|
} else if(!S_ISDIR(buf.st_mode)) {
|
2009-09-16 20:03:23 -04:00
|
|
|
_alpm_log(PM_LOG_WARNING, _("removing invalid database: %s\n"), path);
|
2009-01-19 16:54:00 -05:00
|
|
|
if(unlink(path) != 0 || _alpm_makepath(path) != 0) {
|
|
|
|
RET_ERR(PM_ERR_SYSTEM, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2009-10-09 13:11:27 -04:00
|
|
|
/* create list of directories in db */
|
|
|
|
static int dirlist_from_tar(const char *archive, alpm_list_t **dirlist)
|
|
|
|
{
|
|
|
|
struct archive *_archive;
|
|
|
|
struct archive_entry *entry;
|
|
|
|
|
|
|
|
if((_archive = archive_read_new()) == NULL)
|
|
|
|
RET_ERR(PM_ERR_LIBARCHIVE, -1);
|
|
|
|
|
|
|
|
archive_read_support_compression_all(_archive);
|
|
|
|
archive_read_support_format_all(_archive);
|
|
|
|
|
|
|
|
if(archive_read_open_filename(_archive, archive,
|
|
|
|
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive,
|
|
|
|
archive_error_string(_archive));
|
|
|
|
RET_ERR(PM_ERR_PKG_OPEN, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
|
|
|
|
const struct stat *st;
|
|
|
|
const char *entryname; /* the name of the file in the archive */
|
|
|
|
|
|
|
|
st = archive_entry_stat(entry);
|
|
|
|
entryname = archive_entry_pathname(entry);
|
|
|
|
|
|
|
|
if(S_ISDIR(st->st_mode)) {
|
|
|
|
char *name = strdup(entryname);
|
|
|
|
*dirlist = alpm_list_add(*dirlist, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
archive_read_finish(_archive);
|
|
|
|
|
|
|
|
*dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create list of directories in db */
|
|
|
|
static int dirlist_from_fs(const char *syncdbpath, alpm_list_t **dirlist)
|
|
|
|
{
|
|
|
|
DIR *dbdir;
|
|
|
|
struct dirent *ent = NULL;
|
|
|
|
struct stat sbuf;
|
|
|
|
char path[PATH_MAX];
|
|
|
|
|
|
|
|
dbdir = opendir(syncdbpath);
|
|
|
|
if (dbdir != NULL) {
|
|
|
|
while((ent = readdir(dbdir)) != NULL) {
|
|
|
|
char *name = ent->d_name;
|
|
|
|
size_t len;
|
|
|
|
char *entry;
|
|
|
|
|
|
|
|
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* stat the entry, make sure it's a directory */
|
|
|
|
snprintf(path, PATH_MAX, "%s%s", syncdbpath, name);
|
|
|
|
if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = strlen(name);
|
|
|
|
MALLOC(entry, len + 2, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
strcpy(entry, name);
|
|
|
|
entry[len] = '/';
|
|
|
|
entry[len+1] = '\0';
|
|
|
|
*dirlist = alpm_list_add(*dirlist, entry);
|
|
|
|
}
|
2009-12-04 19:50:09 -05:00
|
|
|
closedir(dbdir);
|
2009-10-09 13:11:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
*dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove old directories from dbdir */
|
|
|
|
static int remove_olddir(const char *syncdbpath, alpm_list_t *dirlist)
|
|
|
|
{
|
|
|
|
alpm_list_t *i;
|
|
|
|
for (i = dirlist; i; i = i->next) {
|
|
|
|
const char *name = i->data;
|
|
|
|
char *dbdir;
|
|
|
|
size_t len = strlen(syncdbpath) + strlen(name) + 2;
|
|
|
|
MALLOC(dbdir, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
snprintf(dbdir, len, "%s%s", syncdbpath, name);
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "removing: %s\n", dbdir);
|
|
|
|
if(_alpm_rmrf(dbdir) != 0) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not remove database directory %s\n"), dbdir);
|
|
|
|
free(dbdir);
|
|
|
|
RET_ERR(PM_ERR_DB_REMOVE, -1);
|
|
|
|
}
|
|
|
|
free(dbdir);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
/** Update a package database
|
2009-04-09 01:42:14 -04:00
|
|
|
*
|
|
|
|
* An update of the package database \a db will be attempted. Unless
|
|
|
|
* \a force is true, the update will only be performed if the remote
|
|
|
|
* database was modified since the last update.
|
|
|
|
*
|
|
|
|
* A transaction is necessary for this operation, in order to obtain a
|
|
|
|
* database lock. During this transaction the front-end will be informed
|
|
|
|
* of the download progress of the database via the download callback.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* @code
|
|
|
|
* pmdb_t *db;
|
|
|
|
* int result;
|
|
|
|
* db = alpm_list_getdata(alpm_option_get_syncdbs());
|
2009-07-15 13:14:01 -04:00
|
|
|
* if(alpm_trans_init(0, NULL, NULL, NULL) == 0) {
|
2009-04-09 01:42:14 -04:00
|
|
|
* result = alpm_db_update(0, db);
|
|
|
|
* alpm_trans_release();
|
|
|
|
*
|
|
|
|
* if(result > 0) {
|
|
|
|
* printf("Unable to update database: %s\n", alpm_strerrorlast());
|
|
|
|
* } else if(result < 0) {
|
|
|
|
* printf("Database already up to date\n");
|
|
|
|
* } else {
|
|
|
|
* printf("Database updated\n");
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* @ingroup alpm_databases
|
|
|
|
* @note After a successful update, the \link alpm_db_get_pkgcache()
|
|
|
|
* package cache \endlink will be invalidated
|
2008-05-11 20:29:23 -04:00
|
|
|
* @param force if true, then forces the update, otherwise update only in case
|
|
|
|
* the database isn't up to date
|
|
|
|
* @param db pointer to the package database to update
|
|
|
|
* @return 0 on success, > 0 on error (pm_errno is set accordingly), < 0 if up
|
|
|
|
* to date
|
2006-10-25 14:15:25 -04:00
|
|
|
*/
|
2008-05-11 20:29:23 -04:00
|
|
|
int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
|
2006-10-25 14:15:25 -04:00
|
|
|
{
|
2008-05-30 02:52:27 -04:00
|
|
|
char *dbfile, *dbfilepath;
|
2010-03-14 20:16:26 -04:00
|
|
|
const char *dbpath, *syncdbpath;
|
2010-03-16 00:03:29 -04:00
|
|
|
alpm_list_t *newdirlist = NULL, *olddirlist = NULL;
|
|
|
|
alpm_list_t *onlynew = NULL, *onlyold = NULL;
|
2008-05-30 02:52:27 -04:00
|
|
|
size_t len;
|
2008-05-11 20:29:23 -04:00
|
|
|
int ret;
|
|
|
|
|
2007-01-30 03:14:10 -05:00
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
/* Sanity checks */
|
|
|
|
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
|
|
|
|
ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1));
|
|
|
|
/* Verify we are in a transaction. This is done _mainly_ because we need a DB
|
|
|
|
* lock - if we update without a db lock, we may kludge some other pacman
|
|
|
|
* process that _has_ a lock.
|
|
|
|
*/
|
|
|
|
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));
|
|
|
|
|
|
|
|
if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
|
|
|
|
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
|
|
|
}
|
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
len = strlen(db->treename) + strlen(DBEXT) + 1;
|
|
|
|
MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
sprintf(dbfile, "%s" DBEXT, db->treename);
|
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
dbpath = alpm_option_get_dbpath();
|
|
|
|
|
download: major refactor to address lingering issues
Sorry for this being such a huge patch, but I believe it is necessary for
quite a few reasons which I will attempt to explain herein. I've been
mulling this over for a while, but wasn't super happy with making the
download interface more complex. Instead, if we carefully order things in
the internal download code, we can actually make the interface simpler.
1. FS#15657 - This involves `name.db.tar.gz.part` files being left around the
filesystem, and then causing all sorts of issues when someone attempts to
rerun the operation they canceled. We need to ensure that if we resume a
download, we are resuming it on exactly the same file; if we cannot be
almost postive of that then we need to start over.
2. http://www.mail-archive.com/pacman-dev@archlinux.org/msg03536.html - Here
we have a lighttpd bug to ruin the day. If we send both a Range: header and
If-Modified-Since: header across the wire in a GET request, lighttpd doesn't
do what we want in several cases. If the file hadn't been modified, it
returns a '304 Not Modified' instead of a '206 Partial Content'. We need to
do a stat (e.g. HEAD in HTTP terms) operation here, and the proceed
accordingly based off the values we get back from it.
3. The mtime stuff was rather ugly, and relied on the called function to
write back to a passed in reference, which isn't the greatest. Instead, use
the power of the filesystem to contain this info. Every file downloaded
internally is now carefully timestamped with the remote file time. This
should allow the resume logic to work. In order to guarantee this, we need
to implement a signal handler that catches interrupts, notifies the running
code, and causes it to set the mtimes on the file. It then rethrows the
signal so the pacman signal handler (or any frontend) works as expected.
4. We did a lot of funky stuff in trying to track the DB last modified time.
It is a lot easier to just keep the downloaded DB file around and track the
time on that rather than in a funky dot file. It also kills a lot of code.
5. For GPG verification of the databases down the road, we are going to need
the DB file around for at least a short bit of time anyway, so this gets us
closer to that.
Signed-off-by: Dan McGee <dan@archlinux.org>
[Xav: fixed printf with off_t]
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
2009-11-12 00:39:26 -05:00
|
|
|
ret = _alpm_download_single_file(dbfile, db->servers, dbpath, force);
|
2008-05-30 02:52:27 -04:00
|
|
|
free(dbfile);
|
2008-05-11 20:29:23 -04:00
|
|
|
|
|
|
|
if(ret == 1) {
|
download: major refactor to address lingering issues
Sorry for this being such a huge patch, but I believe it is necessary for
quite a few reasons which I will attempt to explain herein. I've been
mulling this over for a while, but wasn't super happy with making the
download interface more complex. Instead, if we carefully order things in
the internal download code, we can actually make the interface simpler.
1. FS#15657 - This involves `name.db.tar.gz.part` files being left around the
filesystem, and then causing all sorts of issues when someone attempts to
rerun the operation they canceled. We need to ensure that if we resume a
download, we are resuming it on exactly the same file; if we cannot be
almost postive of that then we need to start over.
2. http://www.mail-archive.com/pacman-dev@archlinux.org/msg03536.html - Here
we have a lighttpd bug to ruin the day. If we send both a Range: header and
If-Modified-Since: header across the wire in a GET request, lighttpd doesn't
do what we want in several cases. If the file hadn't been modified, it
returns a '304 Not Modified' instead of a '206 Partial Content'. We need to
do a stat (e.g. HEAD in HTTP terms) operation here, and the proceed
accordingly based off the values we get back from it.
3. The mtime stuff was rather ugly, and relied on the called function to
write back to a passed in reference, which isn't the greatest. Instead, use
the power of the filesystem to contain this info. Every file downloaded
internally is now carefully timestamped with the remote file time. This
should allow the resume logic to work. In order to guarantee this, we need
to implement a signal handler that catches interrupts, notifies the running
code, and causes it to set the mtimes on the file. It then rethrows the
signal so the pacman signal handler (or any frontend) works as expected.
4. We did a lot of funky stuff in trying to track the DB last modified time.
It is a lot easier to just keep the downloaded DB file around and track the
time on that rather than in a funky dot file. It also kills a lot of code.
5. For GPG verification of the databases down the road, we are going to need
the DB file around for at least a short bit of time anyway, so this gets us
closer to that.
Signed-off-by: Dan McGee <dan@archlinux.org>
[Xav: fixed printf with off_t]
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
2009-11-12 00:39:26 -05:00
|
|
|
/* files match, do nothing */
|
2008-05-11 20:29:23 -04:00
|
|
|
pm_errno = 0;
|
|
|
|
return(1);
|
|
|
|
} else if(ret == -1) {
|
|
|
|
/* pm_errno was set by the download code */
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
|
|
|
|
return(-1);
|
2009-10-09 13:11:27 -04:00
|
|
|
}
|
|
|
|
|
2010-03-14 20:16:26 -04:00
|
|
|
syncdbpath = _alpm_db_path(db);
|
2009-10-09 13:11:27 -04:00
|
|
|
|
|
|
|
/* form the path to the db location */
|
|
|
|
len = strlen(dbpath) + strlen(db->treename) + strlen(DBEXT) + 1;
|
|
|
|
MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
sprintf(dbfilepath, "%s%s" DBEXT, dbpath, db->treename);
|
|
|
|
|
|
|
|
if(force) {
|
|
|
|
/* if forcing update, remove the old dir and extract the db */
|
2009-09-14 23:44:51 -04:00
|
|
|
if(_alpm_rmrf(syncdbpath) != 0) {
|
2009-01-19 16:54:00 -05:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
|
|
|
|
RET_ERR(PM_ERR_DB_REMOVE, -1);
|
download: major refactor to address lingering issues
Sorry for this being such a huge patch, but I believe it is necessary for
quite a few reasons which I will attempt to explain herein. I've been
mulling this over for a while, but wasn't super happy with making the
download interface more complex. Instead, if we carefully order things in
the internal download code, we can actually make the interface simpler.
1. FS#15657 - This involves `name.db.tar.gz.part` files being left around the
filesystem, and then causing all sorts of issues when someone attempts to
rerun the operation they canceled. We need to ensure that if we resume a
download, we are resuming it on exactly the same file; if we cannot be
almost postive of that then we need to start over.
2. http://www.mail-archive.com/pacman-dev@archlinux.org/msg03536.html - Here
we have a lighttpd bug to ruin the day. If we send both a Range: header and
If-Modified-Since: header across the wire in a GET request, lighttpd doesn't
do what we want in several cases. If the file hadn't been modified, it
returns a '304 Not Modified' instead of a '206 Partial Content'. We need to
do a stat (e.g. HEAD in HTTP terms) operation here, and the proceed
accordingly based off the values we get back from it.
3. The mtime stuff was rather ugly, and relied on the called function to
write back to a passed in reference, which isn't the greatest. Instead, use
the power of the filesystem to contain this info. Every file downloaded
internally is now carefully timestamped with the remote file time. This
should allow the resume logic to work. In order to guarantee this, we need
to implement a signal handler that catches interrupts, notifies the running
code, and causes it to set the mtimes on the file. It then rethrows the
signal so the pacman signal handler (or any frontend) works as expected.
4. We did a lot of funky stuff in trying to track the DB last modified time.
It is a lot easier to just keep the downloaded DB file around and track the
time on that rather than in a funky dot file. It also kills a lot of code.
5. For GPG verification of the databases down the road, we are going to need
the DB file around for at least a short bit of time anyway, so this gets us
closer to that.
Signed-off-by: Dan McGee <dan@archlinux.org>
[Xav: fixed printf with off_t]
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
2009-11-12 00:39:26 -05:00
|
|
|
} else {
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "database dir %s removed\n", _alpm_db_path(db));
|
2008-05-11 20:29:23 -04:00
|
|
|
}
|
2010-03-14 20:16:26 -04:00
|
|
|
} else {
|
|
|
|
/* if not forcing, only remove and extract what is necessary */
|
|
|
|
ret = dirlist_from_tar(dbfilepath, &newdirlist);
|
2008-05-30 02:52:27 -04:00
|
|
|
if(ret) {
|
2010-03-14 20:16:26 -04:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = dirlist_from_fs(syncdbpath, &olddirlist);
|
|
|
|
if(ret) {
|
|
|
|
goto cleanup;
|
2008-05-11 20:29:23 -04:00
|
|
|
}
|
2009-10-09 13:11:27 -04:00
|
|
|
|
2010-03-16 00:03:29 -04:00
|
|
|
alpm_list_diff_sorted(olddirlist, newdirlist, _alpm_str_cmp, &onlyold, &onlynew);
|
2009-10-09 13:11:27 -04:00
|
|
|
|
2010-03-14 20:16:26 -04:00
|
|
|
ret = remove_olddir(syncdbpath, onlyold);
|
|
|
|
if(ret) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-10-09 13:11:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Cache needs to be rebuilt */
|
|
|
|
_alpm_db_free_pkgcache(db);
|
|
|
|
|
|
|
|
checkdbdir(db);
|
2010-03-16 00:03:29 -04:00
|
|
|
ret = _alpm_unpack(dbfilepath, syncdbpath, onlynew, 0);
|
2009-10-09 13:11:27 -04:00
|
|
|
|
|
|
|
cleanup:
|
2010-03-16 00:03:29 -04:00
|
|
|
FREELIST(newdirlist);
|
|
|
|
FREELIST(olddirlist);
|
|
|
|
alpm_list_free(onlynew);
|
|
|
|
alpm_list_free(onlyold);
|
|
|
|
|
2009-10-09 13:11:27 -04:00
|
|
|
free(dbfilepath);
|
|
|
|
|
|
|
|
if(ret) {
|
|
|
|
RET_ERR(PM_ERR_SYSTEM, -1);
|
2006-10-25 14:15:25 -04:00
|
|
|
}
|
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
return(0);
|
2006-10-25 14:15:25 -04:00
|
|
|
}
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2008-01-11 01:01:58 -05:00
|
|
|
static int splitname(const char *target, pmpkg_t *pkg)
|
2007-06-17 23:25:07 -04:00
|
|
|
{
|
|
|
|
/* the format of a db entry is as follows:
|
|
|
|
* package-version-rel/
|
|
|
|
* package name can contain hyphens, so parse from the back- go back
|
|
|
|
* two hyphens and we have split the version from the name.
|
|
|
|
*/
|
|
|
|
char *tmp, *p, *q;
|
|
|
|
|
2008-01-11 01:01:58 -05:00
|
|
|
if(target == NULL || pkg == NULL) {
|
2007-06-17 23:25:07 -04:00
|
|
|
return(-1);
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
|
2007-06-17 23:25:07 -04:00
|
|
|
p = tmp + strlen(tmp);
|
|
|
|
|
|
|
|
/* do the magic parsing- find the beginning of the version string
|
|
|
|
* by doing two iterations of same loop to lop off two hyphens */
|
|
|
|
for(q = --p; *q && *q != '-'; q--);
|
|
|
|
for(p = --q; *p && *p != '-'; p--);
|
|
|
|
if(*p != '-' || p == tmp) {
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy into fields and return */
|
2008-01-11 01:01:58 -05:00
|
|
|
if(pkg->version) {
|
|
|
|
FREE(pkg->version);
|
2007-06-17 23:25:07 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
|
2007-06-17 23:25:07 -04:00
|
|
|
/* insert a terminator at the end of the name (on hyphen)- then copy it */
|
|
|
|
*p = '\0';
|
2008-01-11 01:01:58 -05:00
|
|
|
if(pkg->name) {
|
|
|
|
FREE(pkg->name);
|
2007-06-17 23:25:07 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
|
2007-06-17 23:25:07 -04:00
|
|
|
|
|
|
|
free(tmp);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
int _alpm_db_populate(pmdb_t *db)
|
2006-03-02 14:06:52 -05:00
|
|
|
{
|
2008-05-12 19:56:14 -04:00
|
|
|
int count = 0;
|
2006-03-02 14:06:52 -05:00
|
|
|
struct dirent *ent = NULL;
|
|
|
|
struct stat sbuf;
|
|
|
|
char path[PATH_MAX];
|
2009-09-14 23:44:51 -04:00
|
|
|
const char *dbpath;
|
2009-01-19 14:45:12 -05:00
|
|
|
DIR *dbdir;
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2007-01-30 03:14:10 -05:00
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2009-09-14 23:44:51 -04:00
|
|
|
dbpath = _alpm_db_path(db);
|
|
|
|
dbdir = opendir(dbpath);
|
2009-01-19 14:45:12 -05:00
|
|
|
if(dbdir == NULL) {
|
2009-01-19 16:54:00 -05:00
|
|
|
return(0);
|
2009-01-19 14:45:12 -05:00
|
|
|
}
|
|
|
|
while((ent = readdir(dbdir)) != NULL) {
|
2008-05-12 19:56:14 -04:00
|
|
|
const char *name = ent->d_name;
|
|
|
|
pmpkg_t *pkg;
|
2008-01-11 01:01:58 -05:00
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* stat the entry, make sure it's a directory */
|
2009-09-14 23:44:51 -04:00
|
|
|
snprintf(path, PATH_MAX, "%s%s", dbpath, name);
|
2008-05-12 19:56:14 -04:00
|
|
|
if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
|
|
|
|
continue;
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-01-31 01:48:06 -05:00
|
|
|
|
2008-05-13 20:03:54 -04:00
|
|
|
pkg = _alpm_pkg_new();
|
2007-01-31 01:48:06 -05:00
|
|
|
if(pkg == NULL) {
|
2009-01-19 14:45:12 -05:00
|
|
|
closedir(dbdir);
|
2008-05-12 19:56:14 -04:00
|
|
|
return(-1);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-06-17 23:25:07 -04:00
|
|
|
/* split the db entry name */
|
2008-05-12 19:56:14 -04:00
|
|
|
if(splitname(name, pkg) != 0) {
|
2007-06-17 23:25:07 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
|
2008-05-12 19:56:14 -04:00
|
|
|
name);
|
|
|
|
_alpm_pkg_free(pkg);
|
2007-05-18 02:19:00 -04:00
|
|
|
continue;
|
2007-01-31 01:48:06 -05:00
|
|
|
}
|
2007-03-03 03:13:59 -05:00
|
|
|
|
2009-11-13 10:42:42 -05:00
|
|
|
/* duplicated database entries are not allowed */
|
|
|
|
if(_alpm_pkg_find(db->pkgcache, pkg->name)) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name);
|
|
|
|
_alpm_pkg_free(pkg);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
pkg->origin = PKG_FROM_CACHE;
|
|
|
|
pkg->origin_data.db = db;
|
|
|
|
|
2007-03-03 03:13:59 -05:00
|
|
|
/* explicitly read with only 'BASE' data, accessors will handle the rest */
|
|
|
|
if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) {
|
2008-05-12 19:56:14 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
|
2007-04-26 21:08:34 -04:00
|
|
|
_alpm_pkg_free(pkg);
|
2008-05-12 19:56:14 -04:00
|
|
|
continue;
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
/* add to the collection */
|
|
|
|
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
|
|
|
pkg->name, db->treename);
|
|
|
|
db->pkgcache = alpm_list_add(db->pkgcache, pkg);
|
|
|
|
count++;
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2009-01-19 14:45:12 -05:00
|
|
|
closedir(dbdir);
|
2008-05-12 19:56:14 -04:00
|
|
|
db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
|
|
|
|
return(count);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
/* Note: the return value must be freed by the caller */
|
|
|
|
static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
char *pkgpath;
|
2009-09-14 23:44:51 -04:00
|
|
|
const char *dbpath;
|
2008-05-30 02:52:27 -04:00
|
|
|
|
2009-09-14 23:44:51 -04:00
|
|
|
dbpath = _alpm_db_path(db);
|
|
|
|
len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3;
|
2008-05-30 02:52:27 -04:00
|
|
|
MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL));
|
2009-09-14 23:44:51 -04:00
|
|
|
sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version);
|
2008-05-30 02:52:27 -04:00
|
|
|
return(pkgpath);
|
|
|
|
}
|
|
|
|
|
2007-02-21 03:34:36 -05:00
|
|
|
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
2006-03-02 14:06:52 -05:00
|
|
|
{
|
|
|
|
FILE *fp = NULL;
|
2008-05-04 20:34:03 -04:00
|
|
|
char path[PATH_MAX];
|
2007-01-18 11:52:57 -05:00
|
|
|
char line[513];
|
2009-10-17 17:12:19 -04:00
|
|
|
int sline = sizeof(line)-1;
|
2008-05-30 02:52:27 -04:00
|
|
|
char *pkgpath = NULL;
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2007-01-30 03:14:10 -05:00
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
2006-10-25 14:15:25 -04:00
|
|
|
if(db == NULL) {
|
|
|
|
RET_ERR(PM_ERR_DB_NULL, -1);
|
|
|
|
}
|
|
|
|
|
2008-01-11 01:01:58 -05:00
|
|
|
if(info == NULL || info->name == NULL || info->version == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n");
|
2006-03-02 14:06:52 -05:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2006-11-01 01:30:47 -05:00
|
|
|
if(info->origin == PKG_FROM_FILE) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "request to read database info for a file-based package '%s', skipping...\n", info->name);
|
2006-11-01 01:30:47 -05:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2007-03-11 23:02:57 -04:00
|
|
|
/* bitmask logic here:
|
|
|
|
* infolevel: 00001111
|
|
|
|
* inforeq: 00010100
|
|
|
|
* & result: 00000100
|
|
|
|
* == to inforeq? nope, we need to load more info. */
|
|
|
|
if((info->infolevel & inforeq) == inforeq) {
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
/* already loaded all of this info, do nothing */
|
2006-11-22 04:03:41 -05:00
|
|
|
return(0);
|
|
|
|
}
|
2008-01-01 20:57:02 -05:00
|
|
|
_alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n",
|
|
|
|
info->name, inforeq);
|
2006-11-01 01:30:47 -05:00
|
|
|
|
2006-11-20 04:10:23 -05:00
|
|
|
/* clear out 'line', to be certain - and to make valgrind happy */
|
2009-10-17 17:12:19 -04:00
|
|
|
memset(line, 0, sline+1);
|
2006-11-20 04:10:23 -05:00
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
pkgpath = get_pkgpath(db, info);
|
|
|
|
|
2008-06-15 20:15:36 -04:00
|
|
|
if(access(pkgpath, F_OK)) {
|
2006-03-02 14:06:52 -05:00
|
|
|
/* directory doesn't exist or can't be opened */
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n",
|
2007-07-10 14:24:58 -04:00
|
|
|
info->name, info->version, db->treename);
|
2008-05-30 02:52:27 -04:00
|
|
|
goto error;
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* DESC */
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
if(inforeq & INFRQ_DESC && !(info->infolevel & INFRQ_DESC)) {
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sdesc", pkgpath);
|
2007-01-24 03:51:50 -05:00
|
|
|
if((fp = fopen(path, "r")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
while(!feof(fp)) {
|
|
|
|
if(fgets(line, 256, fp) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
_alpm_strtrim(line);
|
2008-05-03 13:59:11 -04:00
|
|
|
if(strcmp(line, "%NAME%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2008-05-03 13:59:11 -04:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if(strcmp(_alpm_strtrim(line), info->name) != 0) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name "
|
|
|
|
"mismatch on package %s\n"), db->treename, info->name);
|
|
|
|
}
|
|
|
|
} else if(strcmp(line, "%VERSION%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2008-05-03 13:59:11 -04:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if(strcmp(_alpm_strtrim(line), info->version) != 0) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
|
|
|
|
"mismatch on package %s\n"), db->treename, info->name);
|
|
|
|
}
|
|
|
|
} else if(strcmp(line, "%FILENAME%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-11-22 04:03:41 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->filename, _alpm_strtrim(line), goto error);
|
2008-05-03 13:59:11 -04:00
|
|
|
} else if(strcmp(line, "%DESC%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2007-02-12 20:46:33 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->desc, _alpm_strtrim(line), goto error);
|
|
|
|
} else if(strcmp(line, "%GROUPS%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->groups = alpm_list_add(info->groups, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%URL%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->url, _alpm_strtrim(line), goto error);
|
|
|
|
} else if(strcmp(line, "%LICENSE%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->licenses = alpm_list_add(info->licenses, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%ARCH%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->arch, _alpm_strtrim(line), goto error);
|
|
|
|
} else if(strcmp(line, "%BUILDDATE%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
_alpm_strtrim(line);
|
2007-09-19 01:21:56 -04:00
|
|
|
|
2009-09-25 18:58:42 -04:00
|
|
|
char first = tolower((unsigned char)line[0]);
|
2007-09-19 01:21:56 -04:00
|
|
|
if(first > 'a' && first < 'z') {
|
2009-05-10 23:35:56 -04:00
|
|
|
struct tm tmp_tm = {0}; /* initialize to null in case of failure */
|
2007-11-09 00:18:07 -05:00
|
|
|
setlocale(LC_TIME, "C");
|
2008-01-11 01:01:58 -05:00
|
|
|
strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
|
2007-09-19 01:21:56 -04:00
|
|
|
info->builddate = mktime(&tmp_tm);
|
2007-11-09 00:18:07 -05:00
|
|
|
setlocale(LC_TIME, "");
|
2007-09-19 01:21:56 -04:00
|
|
|
} else {
|
2008-01-11 01:01:58 -05:00
|
|
|
info->builddate = atol(line);
|
2007-09-19 01:21:56 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%INSTALLDATE%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
_alpm_strtrim(line);
|
2007-09-19 01:21:56 -04:00
|
|
|
|
2009-09-25 18:58:42 -04:00
|
|
|
char first = tolower((unsigned char)line[0]);
|
2007-09-19 01:21:56 -04:00
|
|
|
if(first > 'a' && first < 'z') {
|
2009-05-10 23:35:56 -04:00
|
|
|
struct tm tmp_tm = {0}; /* initialize to null in case of failure */
|
2007-11-09 00:18:07 -05:00
|
|
|
setlocale(LC_TIME, "C");
|
2008-01-11 01:01:58 -05:00
|
|
|
strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
|
2007-09-19 01:21:56 -04:00
|
|
|
info->installdate = mktime(&tmp_tm);
|
2007-11-09 00:18:07 -05:00
|
|
|
setlocale(LC_TIME, "");
|
2007-09-19 01:21:56 -04:00
|
|
|
} else {
|
2008-01-11 01:01:58 -05:00
|
|
|
info->installdate = atol(line);
|
2007-09-19 01:21:56 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%PACKAGER%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->packager, _alpm_strtrim(line), goto error);
|
|
|
|
} else if(strcmp(line, "%REASON%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-11-17 22:47:55 -05:00
|
|
|
info->reason = (pmpkgreason_t)atol(_alpm_strtrim(line));
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) {
|
2006-03-02 14:06:52 -05:00
|
|
|
/* NOTE: the CSIZE and SIZE fields both share the "size" field
|
|
|
|
* in the pkginfo_t struct. This can be done b/c CSIZE
|
|
|
|
* is currently only used in sync databases, and SIZE is
|
|
|
|
* only used in local databases.
|
|
|
|
*/
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
info->size = atol(_alpm_strtrim(line));
|
2007-11-11 16:02:33 -05:00
|
|
|
/* also store this value to isize if isize is unset */
|
|
|
|
if(info->isize == 0) {
|
2008-01-11 01:01:58 -05:00
|
|
|
info->isize = info->size;
|
2007-11-11 16:02:33 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%ISIZE%") == 0) {
|
2006-11-22 04:03:41 -05:00
|
|
|
/* ISIZE (installed size) tag only appears in sync repositories,
|
2006-10-15 15:31:03 -04:00
|
|
|
* not the local one. */
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-10-15 15:31:03 -04:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
info->isize = atol(_alpm_strtrim(line));
|
|
|
|
} else if(strcmp(line, "%MD5SUM%") == 0) {
|
2006-03-02 14:06:52 -05:00
|
|
|
/* MD5SUM tag only appears in sync repositories,
|
|
|
|
* not the local one. */
|
2009-10-17 17:12:19 -04:00
|
|
|
if(fgets(line, sline, fp) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
STRDUP(info->md5sum, _alpm_strtrim(line), goto error);
|
|
|
|
} else if(strcmp(line, "%REPLACES%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->replaces = alpm_list_add(info->replaces, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%FORCE%") == 0) {
|
2006-03-02 14:06:52 -05:00
|
|
|
info->force = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FILES */
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
if(inforeq & INFRQ_FILES && !(info->infolevel & INFRQ_FILES)) {
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sfiles", pkgpath);
|
2007-01-24 03:51:50 -05:00
|
|
|
if((fp = fopen(path, "r")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
while(fgets(line, 256, fp)) {
|
|
|
|
_alpm_strtrim(line);
|
2008-01-11 01:01:58 -05:00
|
|
|
if(strcmp(line, "%FILES%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->files = alpm_list_add(info->files, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%BACKUP%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->backup = alpm_list_add(info->backup, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DEPENDS */
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
if(inforeq & INFRQ_DEPENDS && !(info->infolevel & INFRQ_DEPENDS)) {
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sdepends", pkgpath);
|
2007-01-24 03:51:50 -05:00
|
|
|
if((fp = fopen(path, "r")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
while(!feof(fp)) {
|
|
|
|
fgets(line, 255, fp);
|
|
|
|
_alpm_strtrim(line);
|
2008-01-11 01:01:58 -05:00
|
|
|
if(strcmp(line, "%DEPENDS%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-21 19:28:05 -05:00
|
|
|
pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line));
|
2007-11-13 00:01:14 -05:00
|
|
|
info->depends = alpm_list_add(info->depends, dep);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->optdepends = alpm_list_add(info->optdepends, linedup);
|
2007-09-26 00:02:30 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%CONFLICTS%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->conflicts = alpm_list_add(info->conflicts, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
|
|
|
info->provides = alpm_list_add(info->provides, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-02-28 11:37:24 -05:00
|
|
|
}
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
2007-10-19 13:17:51 -04:00
|
|
|
/* DELTAS */
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
if(inforeq & INFRQ_DELTAS && !(info->infolevel & INFRQ_DELTAS)) {
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sdeltas", pkgpath);
|
2007-10-19 13:17:51 -04:00
|
|
|
if((fp = fopen(path, "r"))) {
|
|
|
|
while(!feof(fp)) {
|
|
|
|
fgets(line, 255, fp);
|
|
|
|
_alpm_strtrim(line);
|
2008-01-11 01:01:58 -05:00
|
|
|
if(strcmp(line, "%DELTAS%") == 0) {
|
2009-10-17 17:12:19 -04:00
|
|
|
while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) {
|
2008-11-30 18:17:00 -05:00
|
|
|
pmdelta_t *delta = _alpm_delta_parse(line);
|
|
|
|
if(delta) {
|
|
|
|
info->deltas = alpm_list_add(info->deltas, delta);
|
|
|
|
}
|
2007-10-19 13:17:51 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
/* INSTALL */
|
Fix double read issue in maint releases
This is essentially a backport/cherry-pick of commit 33240e87b99e from
master, but has to be done by hand because the DB format has diverged. Read
more in the commit message used there, which follows.
Due to the way we funk around with package data loading, we had a condition
where the filelist got doubled up because it was loaded twice.
Packages are originally loaded with INFRQ_BASE. In an upgrade/sync, the
package is checked for file conflicts next, leaving us in an "INFRQ_BASE |
INFRQ_FILES" state. Later, when committing a single package, we have an
explicit call to _alpm_local_db_read() with INFRQ_ALL as the level. Because
the package's level did not match this, we skipped over our previous "does
the incoming level match where I'm at" shortcut, and continued to load
things again, because of a lack of fine-grained checking for each of DESC,
FILES, and INSTALL.
The end result is we loaded the filelist twice, causing our remove logic to
iterate twice over the installed files, spewing a bunch of "cannot find file
X" messages.
Fix the problem by doing a bit more bitmasking logic throughout the load
method, and also fix the sanity check at the beginning of the function- this
should *only* be used for local packages as opposed to the "not a package"
check that was there before.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-12 10:17:22 -05:00
|
|
|
if(inforeq & INFRQ_SCRIPTLET && !(info->infolevel & INFRQ_SCRIPTLET)) {
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sinstall", pkgpath);
|
2008-06-15 20:15:36 -04:00
|
|
|
if(access(path, F_OK) == 0) {
|
2006-03-02 14:06:52 -05:00
|
|
|
info->scriptlet = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* internal */
|
|
|
|
info->infolevel |= inforeq;
|
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
free(pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
return(0);
|
|
|
|
|
|
|
|
error:
|
2008-05-30 02:52:27 -04:00
|
|
|
free(pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
if(fp) {
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2009-01-02 04:12:22 -05:00
|
|
|
int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info)
|
|
|
|
{
|
|
|
|
mode_t oldmask;
|
|
|
|
int retval = 0;
|
|
|
|
char *pkgpath = NULL;
|
|
|
|
|
2009-01-19 16:54:00 -05:00
|
|
|
if(checkdbdir(db) != 0) {
|
|
|
|
return(-1);
|
|
|
|
}
|
2009-01-02 04:12:22 -05:00
|
|
|
|
2009-01-19 16:54:00 -05:00
|
|
|
oldmask = umask(0000);
|
2009-01-02 04:12:22 -05:00
|
|
|
pkgpath = get_pkgpath(db, info);
|
|
|
|
|
|
|
|
if((retval = mkdir(pkgpath, 0755)) != 0) {
|
2009-01-19 16:54:00 -05:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not create directory %s: %s\n"),
|
|
|
|
pkgpath, strerror(errno));
|
2009-01-02 04:12:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
free(pkgpath);
|
|
|
|
umask(oldmask);
|
|
|
|
|
|
|
|
return(retval);
|
|
|
|
}
|
|
|
|
|
2007-02-21 03:34:36 -05:00
|
|
|
int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
2006-03-02 14:06:52 -05:00
|
|
|
{
|
|
|
|
FILE *fp = NULL;
|
|
|
|
char path[PATH_MAX];
|
|
|
|
mode_t oldmask;
|
2007-01-19 04:28:44 -05:00
|
|
|
alpm_list_t *lp = NULL;
|
2006-03-02 14:06:52 -05:00
|
|
|
int retval = 0;
|
|
|
|
int local = 0;
|
2008-05-30 02:52:27 -04:00
|
|
|
char *pkgpath = NULL;
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2007-01-30 03:14:10 -05:00
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
if(db == NULL || info == NULL) {
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
pkgpath = get_pkgpath(db, info);
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
/* make sure we have a sane umask */
|
2009-01-02 04:12:22 -05:00
|
|
|
oldmask = umask(0022);
|
2006-03-02 14:06:52 -05:00
|
|
|
|
|
|
|
if(strcmp(db->treename, "local") == 0) {
|
|
|
|
local = 1;
|
|
|
|
}
|
2007-02-12 20:46:33 -05:00
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
/* DESC */
|
|
|
|
if(inforeq & INFRQ_DESC) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n",
|
2007-07-10 14:24:58 -04:00
|
|
|
info->name, info->version);
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sdesc", pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
if((fp = fopen(path, "w")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2007-01-24 03:51:50 -05:00
|
|
|
retval = -1;
|
2006-03-02 14:06:52 -05:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
fprintf(fp, "%%NAME%%\n%s\n\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%%VERSION%%\n%s\n\n", info->name, info->version);
|
2008-01-11 01:01:58 -05:00
|
|
|
if(info->desc) {
|
2007-02-12 20:46:33 -05:00
|
|
|
fprintf(fp, "%%DESC%%\n"
|
|
|
|
"%s\n\n", info->desc);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
if(info->groups) {
|
|
|
|
fputs("%GROUPS%\n", fp);
|
|
|
|
for(lp = info->groups; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
2008-05-22 17:59:10 -04:00
|
|
|
if(info->replaces) {
|
|
|
|
fputs("%REPLACES%\n", fp);
|
|
|
|
for(lp = info->replaces; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
2006-03-02 14:06:52 -05:00
|
|
|
if(local) {
|
2008-01-11 01:01:58 -05:00
|
|
|
if(info->url) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%URL%%\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%s\n\n", info->url);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-03-03 03:13:59 -05:00
|
|
|
if(info->licenses) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fputs("%LICENSE%\n", fp);
|
2007-03-03 03:13:59 -05:00
|
|
|
for(lp = info->licenses; lp; lp = lp->next) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
if(info->arch) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%ARCH%%\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%s\n\n", info->arch);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-09-19 01:21:56 -04:00
|
|
|
if(info->builddate) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%BUILDDATE%%\n"
|
2009-11-14 14:26:37 -05:00
|
|
|
"%ld\n\n", info->builddate);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2007-09-19 01:21:56 -04:00
|
|
|
if(info->installdate) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%INSTALLDATE%%\n"
|
2009-11-14 14:26:37 -05:00
|
|
|
"%ld\n\n", info->installdate);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
if(info->packager) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%PACKAGER%%\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%s\n\n", info->packager);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-06-01 22:47:31 -04:00
|
|
|
if(info->isize) {
|
2007-03-12 11:41:33 -04:00
|
|
|
/* only write installed size, csize is irrelevant once installed */
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%SIZE%%\n"
|
2009-02-28 19:40:24 -05:00
|
|
|
"%jd\n\n", (intmax_t)info->isize);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
if(info->reason) {
|
|
|
|
fprintf(fp, "%%REASON%%\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%u\n\n", info->reason);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(info->size) {
|
|
|
|
fprintf(fp, "%%CSIZE%%\n"
|
2009-02-28 19:40:24 -05:00
|
|
|
"%jd\n\n", (intmax_t)info->size);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2006-11-22 04:03:41 -05:00
|
|
|
if(info->isize) {
|
|
|
|
fprintf(fp, "%%ISIZE%%\n"
|
2009-02-28 19:40:24 -05:00
|
|
|
"%jd\n\n", (intmax_t)info->isize);
|
2006-10-15 15:31:03 -04:00
|
|
|
}
|
2007-07-25 17:35:29 -04:00
|
|
|
if(info->md5sum) {
|
2006-03-02 14:06:52 -05:00
|
|
|
fprintf(fp, "%%MD5SUM%%\n"
|
2007-02-12 20:46:33 -05:00
|
|
|
"%s\n\n", info->md5sum);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FILES */
|
|
|
|
if(local && (inforeq & INFRQ_FILES)) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",
|
2007-07-10 14:24:58 -04:00
|
|
|
info->name, info->version);
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sfiles", pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
if((fp = fopen(path, "w")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2006-03-02 14:06:52 -05:00
|
|
|
retval = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if(info->files) {
|
|
|
|
fprintf(fp, "%%FILES%%\n");
|
|
|
|
for(lp = info->files; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
if(info->backup) {
|
|
|
|
fprintf(fp, "%%BACKUP%%\n");
|
|
|
|
for(lp = info->backup; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DEPENDS */
|
|
|
|
if(inforeq & INFRQ_DEPENDS) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "writing %s-%s DEPENDS information back to db\n",
|
2007-07-10 14:24:58 -04:00
|
|
|
info->name, info->version);
|
2008-05-30 02:52:27 -04:00
|
|
|
snprintf(path, PATH_MAX, "%sdepends", pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
if((fp = fopen(path, "w")) == NULL) {
|
2007-08-23 22:26:55 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
|
2006-03-02 14:06:52 -05:00
|
|
|
retval = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if(info->depends) {
|
|
|
|
fputs("%DEPENDS%\n", fp);
|
|
|
|
for(lp = info->depends; lp; lp = lp->next) {
|
2008-08-26 06:57:08 -04:00
|
|
|
char *depstring = alpm_dep_compute_string(lp->data);
|
2007-11-13 00:01:14 -05:00
|
|
|
fprintf(fp, "%s\n", depstring);
|
|
|
|
free(depstring);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
2007-09-26 00:02:30 -04:00
|
|
|
if(info->optdepends) {
|
|
|
|
fputs("%OPTDEPENDS%\n", fp);
|
|
|
|
for(lp = info->optdepends; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
2006-03-02 14:06:52 -05:00
|
|
|
if(info->conflicts) {
|
|
|
|
fputs("%CONFLICTS%\n", fp);
|
|
|
|
for(lp = info->conflicts; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
if(info->provides) {
|
|
|
|
fputs("%PROVIDES%\n", fp);
|
|
|
|
for(lp = info->provides; lp; lp = lp->next) {
|
|
|
|
fprintf(fp, "%s\n", (char *)lp->data);
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* INSTALL */
|
2006-10-15 15:31:03 -04:00
|
|
|
/* nothing needed here (script is automatically extracted) */
|
2006-03-02 14:06:52 -05:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
umask(oldmask);
|
2008-05-30 02:52:27 -04:00
|
|
|
free(pkgpath);
|
2006-03-02 14:06:52 -05:00
|
|
|
|
|
|
|
if(fp) {
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(retval);
|
|
|
|
}
|
|
|
|
|
|
|
|
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
|
|
|
|
{
|
2008-05-30 02:52:27 -04:00
|
|
|
int ret = 0;
|
|
|
|
char *pkgpath = NULL;
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2007-01-30 03:14:10 -05:00
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
if(db == NULL || info == NULL) {
|
2006-10-25 14:15:25 -04:00
|
|
|
RET_ERR(PM_ERR_DB_NULL, -1);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
pkgpath = get_pkgpath(db, info);
|
2006-03-02 14:06:52 -05:00
|
|
|
|
2008-05-30 02:52:27 -04:00
|
|
|
ret = _alpm_rmrf(pkgpath);
|
|
|
|
free(pkgpath);
|
|
|
|
if(ret != 0) {
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
return(ret);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* vim: set ts=2 sw=2 noet: */
|