2006-03-02 14:06:52 -05:00
|
|
|
/*
|
2010-10-13 04:04:07 -04:00
|
|
|
* be_sync.c
|
2007-11-16 21:18:45 -05:00
|
|
|
*
|
Complete rework of package accessor logic
Hopefully we've finally arrived at package handling nirvana, or at least
this commit will get us a heck of a lot closer. The former method of getting
the depends list for a package was the following:
1. call alpm_pkg_get_depends()
2. this method would check if the package came from the cache
3. if so, ensure our cache level is correct, otherwise call db_load
4. finally return the depends list
Why did this suck? Because getting the depends list from the package
shouldn't care about whether the package was loaded from a file, from the
'package cache', or some other system which we can't even use because the
damn thing is so complicated. It should just return the depends list.
So what does this commit change? It adds a pointer to a struct of function
pointers to every package for all of these 'package operations' as I've
decided to call them (I know, sounds completely straightforward, right?). So
now when we call an alpm_pkg_get-* function, we don't do any of the cache
logic or anything else there- we let the actual backend handle it by
delegating all work to the method at pkg->ops->get_depends.
Now that be_package has achieved equal status with be_files, we can treat
packages from these completely different load points differently. We know a
package loaded from a zip file will have all of its fields populated, so
we can set up all its accessor functions to be direct accessors. On the
other hand, the packages loaded from the local and sync DBs are not always
fully-loaded, so their accessor functions are routed through the same logic
as before.
Net result? More code. However, this code now make it roughly 52 times
easier to open the door to something like a read-only tar.gz database
backend.
Are you still reading? I'm impressed. Looking at the patch will probably be
clearer than this long-winded explanation.
Signed-off-by: Dan McGee <dan@archlinux.org>
[Allan: rebase and adjust]
Signed-off-by: Allan McRae <allan@archlinux.org>
2008-05-11 17:00:33 -04:00
|
|
|
* Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>
|
|
|
|
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.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 <errno.h>
|
2007-09-19 01:21:56 -04:00
|
|
|
#include <ctype.h>
|
2010-10-09 09:31:29 -04:00
|
|
|
#include <locale.h>
|
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 */
|
2006-03-02 14:06:52 -05:00
|
|
|
#include "util.h"
|
2010-10-13 04:04:07 -04:00
|
|
|
#include "log.h"
|
2006-03-02 14:06:52 -05:00
|
|
|
#include "alpm.h"
|
2010-10-13 04:04:07 -04:00
|
|
|
#include "alpm_list.h"
|
2006-11-20 04:10:23 -05:00
|
|
|
#include "package.h"
|
2010-10-13 04:04:07 -04:00
|
|
|
#include "handle.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
|
|
|
|
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
|
|
|
{
|
2010-10-10 01:25:45 -04:00
|
|
|
char *dbfile, *syncpath;
|
|
|
|
const char *dbpath;
|
2010-12-12 23:41:02 -05:00
|
|
|
struct stat buf;
|
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));
|
|
|
|
|
|
|
|
if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
|
|
|
|
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
|
|
|
}
|
|
|
|
|
2010-06-03 10:10:50 -04:00
|
|
|
len = strlen(db->treename) + 4;
|
2008-05-30 02:52:27 -04:00
|
|
|
MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
|
2010-06-03 10:10:50 -04:00
|
|
|
sprintf(dbfile, "%s.db", db->treename);
|
2008-05-30 02:52:27 -04:00
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
dbpath = alpm_option_get_dbpath();
|
2010-07-07 02:10:10 -04:00
|
|
|
len = strlen(dbpath) + 6;
|
|
|
|
MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
sprintf(syncpath, "%s%s", dbpath, "sync/");
|
2008-05-11 20:29:23 -04:00
|
|
|
|
2010-12-12 23:41:02 -05:00
|
|
|
if(stat(syncpath, &buf) != 0) {
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
|
|
|
|
syncpath);
|
|
|
|
if(_alpm_makepath(syncpath) != 0) {
|
|
|
|
free(dbfile);
|
|
|
|
free(syncpath);
|
|
|
|
RET_ERR(PM_ERR_SYSTEM, -1);
|
|
|
|
}
|
|
|
|
} else if(!S_ISDIR(buf.st_mode)) {
|
|
|
|
_alpm_log(PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath);
|
|
|
|
if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) {
|
|
|
|
free(dbfile);
|
|
|
|
free(syncpath);
|
|
|
|
RET_ERR(PM_ERR_SYSTEM, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-07 02:10:10 -04:00
|
|
|
ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force);
|
2008-05-30 02:52:27 -04:00
|
|
|
free(dbfile);
|
2010-07-07 02:10:10 -04:00
|
|
|
free(syncpath);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/* Cache needs to be rebuilt */
|
|
|
|
_alpm_db_free_pkgcache(db);
|
|
|
|
|
2008-05-11 20:29:23 -04:00
|
|
|
return(0);
|
2006-10-25 14:15:25 -04:00
|
|
|
}
|
|
|
|
|
2010-12-13 21:16:36 -05:00
|
|
|
/* Forward decl so I don't reorganize the whole file right now */
|
|
|
|
static int sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry *entry);
|
|
|
|
|
2010-12-13 21:19:32 -05:00
|
|
|
static int sync_db_populate(pmdb_t *db)
|
2006-03-02 14:06:52 -05:00
|
|
|
{
|
2008-05-12 19:56:14 -04:00
|
|
|
int count = 0;
|
2010-10-09 09:31:29 -04:00
|
|
|
struct archive *archive;
|
|
|
|
struct archive_entry *entry;
|
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
|
|
|
|
2010-10-09 09:31:29 -04:00
|
|
|
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, _alpm_db_path(db),
|
|
|
|
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
|
|
|
_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), _alpm_db_path(db),
|
|
|
|
archive_error_string(archive));
|
|
|
|
RET_ERR(PM_ERR_PKG_OPEN, 1);
|
2009-01-19 14:45:12 -05:00
|
|
|
}
|
2010-10-09 09:31:29 -04:00
|
|
|
|
|
|
|
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
|
|
|
const struct stat *st;
|
|
|
|
const char *name;
|
2008-05-12 19:56:14 -04:00
|
|
|
pmpkg_t *pkg;
|
2008-01-11 01:01:58 -05:00
|
|
|
|
2010-10-09 09:31:29 -04:00
|
|
|
st = archive_entry_stat(entry);
|
|
|
|
|
2010-10-10 00:49:10 -04:00
|
|
|
if(S_ISDIR(st->st_mode)) {
|
|
|
|
pkg = _alpm_pkg_new();
|
|
|
|
if(pkg == NULL) {
|
|
|
|
archive_read_finish(archive);
|
|
|
|
return(-1);
|
|
|
|
}
|
2010-10-09 09:31:29 -04:00
|
|
|
|
2010-10-10 00:49:10 -04:00
|
|
|
name = archive_entry_pathname(entry);
|
2010-10-09 09:31:29 -04:00
|
|
|
|
2010-10-11 00:05:07 -04:00
|
|
|
if(_alpm_splitname(name, pkg) != 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
|
|
|
|
name);
|
|
|
|
_alpm_pkg_free(pkg);
|
|
|
|
continue;
|
|
|
|
}
|
2007-03-03 03:13:59 -05:00
|
|
|
|
2010-10-10 00:49:10 -04: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;
|
|
|
|
}
|
2009-11-13 10:42:42 -05:00
|
|
|
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->origin = PKG_FROM_SYNCDB;
|
|
|
|
pkg->ops = &default_pkg_ops;
|
|
|
|
pkg->origin_data.db = db;
|
2010-10-09 09:31:29 -04:00
|
|
|
|
2010-10-10 00:49:10 -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++;
|
|
|
|
} else {
|
|
|
|
/* we have desc, depends or deltas - parse it */
|
2010-12-13 21:16:36 -05:00
|
|
|
sync_db_read(db, archive, entry);
|
2010-10-10 00:49:10 -04:00
|
|
|
}
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
|
2010-10-09 09:31:29 -04:00
|
|
|
archive_read_finish(archive);
|
|
|
|
|
2008-05-12 19:56:14 -04:00
|
|
|
return(count);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2010-12-13 21:16:36 -05:00
|
|
|
static int sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry *entry)
|
2006-03-02 14:06:52 -05:00
|
|
|
{
|
2010-07-07 18:12:42 -04:00
|
|
|
char line[1024];
|
2010-10-31 16:39:31 -04:00
|
|
|
const char *entryname = NULL;
|
2010-10-10 00:49:10 -04:00
|
|
|
char *filename, *pkgname, *p, *q;
|
|
|
|
pmpkg_t *pkg;
|
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);
|
|
|
|
}
|
|
|
|
|
2010-10-31 16:39:31 -04:00
|
|
|
if(entry != NULL) {
|
|
|
|
entryname = archive_entry_pathname(entry);
|
|
|
|
}
|
|
|
|
if(entryname == NULL) {
|
2010-10-10 00:49:10 -04:00
|
|
|
_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n");
|
2006-03-02 14:06:52 -05:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2010-10-10 00:49:10 -04:00
|
|
|
_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n",
|
|
|
|
entryname);
|
|
|
|
|
|
|
|
/* get package and db file names */
|
|
|
|
STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
p = pkgname + strlen(pkgname);
|
|
|
|
for(q = --p; *q && *q != '/'; q--);
|
|
|
|
STRDUP(filename, q+1, RET_ERR(PM_ERR_MEMORY, -1));
|
|
|
|
for(p = --q; *p && *p != '-'; p--);
|
|
|
|
for(q = --p; *q && *q != '-'; q--);
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
/* package is already in db due to parsing of directory name */
|
|
|
|
pkg = _alpm_pkg_find(db->pkgcache, pkgname);
|
|
|
|
if(pkg == NULL) {
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database",
|
|
|
|
pkgname, db->treename);
|
2006-11-01 01:30:47 -05:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
2010-12-12 21:38:20 -05:00
|
|
|
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|
|
|
|
|| strcmp(filename, "deltas") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) != NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
_alpm_strtrim(line);
|
2008-05-03 13:59:11 -04:00
|
|
|
if(strcmp(line, "%NAME%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2008-05-03 13:59:11 -04:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
if(strcmp(_alpm_strtrim(line), pkg->name) != 0) {
|
2008-05-03 13:59:11 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name "
|
2010-10-10 00:49:10 -04:00
|
|
|
"mismatch on package %s\n"), db->treename, pkg->name);
|
2008-05-03 13:59:11 -04:00
|
|
|
}
|
|
|
|
} else if(strcmp(line, "%VERSION%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2008-05-03 13:59:11 -04:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
if(strcmp(_alpm_strtrim(line), pkg->version) != 0) {
|
2008-05-03 13:59:11 -04:00
|
|
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
|
2010-10-10 00:49:10 -04:00
|
|
|
"mismatch on package %s\n"), db->treename, pkg->name);
|
2008-05-03 13:59:11 -04:00
|
|
|
}
|
|
|
|
} else if(strcmp(line, "%FILENAME%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-11-22 04:03:41 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->filename, _alpm_strtrim(line), goto error);
|
2008-05-03 13:59:11 -04:00
|
|
|
} else if(strcmp(line, "%DESC%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2007-02-12 20:46:33 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->desc, _alpm_strtrim(line), goto error);
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%GROUPS%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) && strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->groups = alpm_list_add(pkg->groups, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%URL%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->url, _alpm_strtrim(line), goto error);
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%LICENSE%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->licenses = alpm_list_add(pkg->licenses, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%ARCH%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->arch, _alpm_strtrim(line), goto error);
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%BUILDDATE%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == 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);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->builddate = mktime(&tmp_tm);
|
2007-11-09 00:18:07 -05:00
|
|
|
setlocale(LC_TIME, "");
|
2007-09-19 01:21:56 -04:00
|
|
|
} else {
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->builddate = atol(line);
|
2007-09-19 01:21:56 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%PACKAGER%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->packager, _alpm_strtrim(line), goto error);
|
2010-10-11 01:10:26 -04:00
|
|
|
} else if(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.
|
|
|
|
*/
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->size = atol(_alpm_strtrim(line));
|
2007-11-11 16:02:33 -05:00
|
|
|
/* also store this value to isize if isize is unset */
|
2010-10-10 00:49:10 -04:00
|
|
|
if(pkg->isize == 0) {
|
|
|
|
pkg->isize = pkg->size;
|
2007-11-11 16:02:33 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%ISIZE%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-10-15 15:31:03 -04:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->isize = atol(_alpm_strtrim(line));
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%MD5SUM%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
2006-03-02 14:06:52 -05:00
|
|
|
goto error;
|
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
STRDUP(pkg->md5sum, _alpm_strtrim(line), goto error);
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%REPLACES%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->replaces = alpm_list_add(pkg->replaces, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2010-10-08 09:39:23 -04:00
|
|
|
} else if(strcmp(line, "%EPOCH%") == 0) {
|
|
|
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
pkg->epoch = atoi(_alpm_strtrim(line));
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%FORCE%") == 0) {
|
2010-10-08 09:39:23 -04:00
|
|
|
/* For backward compatibility, treat force as a non-zero epoch
|
|
|
|
* but only if we didn't already have a known epoch value. */
|
|
|
|
if(!pkg->epoch) {
|
|
|
|
pkg->epoch = 1;
|
|
|
|
}
|
2010-10-30 00:50:04 -04:00
|
|
|
} else if(strcmp(line, "%DEPENDS%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-21 19:28:05 -05:00
|
|
|
pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line));
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->depends = alpm_list_add(pkg->depends, dep);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->optdepends = alpm_list_add(pkg->optdepends, linedup);
|
2007-09-26 00:02:30 -04:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%CONFLICTS%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->conflicts = alpm_list_add(pkg->conflicts, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2008-01-11 01:01:58 -05:00
|
|
|
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
2010-10-10 00:49:10 -04:00
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
|
|
|
strlen(_alpm_strtrim(line))) {
|
2008-01-11 01:01:58 -05:00
|
|
|
char *linedup;
|
|
|
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
2010-10-10 00:49:10 -04:00
|
|
|
pkg->provides = alpm_list_add(pkg->provides, linedup);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2010-12-12 21:38:20 -05:00
|
|
|
} else if(strcmp(line, "%DELTAS%") == 0) {
|
|
|
|
while(_alpm_archive_fgets(line, sizeof(line), archive) && strlen(_alpm_strtrim(line))) {
|
|
|
|
pmdelta_t *delta = _alpm_delta_parse(line);
|
|
|
|
if(delta) {
|
|
|
|
pkg->deltas = alpm_list_add(pkg->deltas, delta);
|
2007-10-19 13:17:51 -04:00
|
|
|
}
|
|
|
|
}
|
2010-12-12 21:38:20 -05:00
|
|
|
}
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
2010-10-10 00:49:10 -04:00
|
|
|
} else {
|
|
|
|
/* unknown database file */
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "unknown database file: %s", filename);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
error:
|
2010-10-10 00:49:10 -04:00
|
|
|
FREE(pkgname);
|
|
|
|
FREE(filename);
|
2010-12-13 21:16:36 -05:00
|
|
|
/* TODO: return 0 always? */
|
2010-10-10 00:49:10 -04:00
|
|
|
return(0);
|
2006-03-02 14:06:52 -05:00
|
|
|
}
|
|
|
|
|
2010-10-09 06:16:15 -04:00
|
|
|
struct db_operations sync_db_ops = {
|
2010-12-13 21:19:32 -05:00
|
|
|
.populate = sync_db_populate,
|
2010-10-09 06:16:15 -04:00
|
|
|
.unregister = _alpm_db_unregister,
|
|
|
|
};
|
|
|
|
|
|
|
|
pmdb_t *_alpm_db_register_sync(const char *treename)
|
|
|
|
{
|
|
|
|
pmdb_t *db;
|
|
|
|
alpm_list_t *i;
|
|
|
|
|
|
|
|
ALPM_LOG_FUNC;
|
|
|
|
|
|
|
|
for(i = handle->dbs_sync; i; i = i->next) {
|
|
|
|
pmdb_t *sdb = i->data;
|
|
|
|
if(strcmp(treename, sdb->treename) == 0) {
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "attempt to re-register the '%s' database, using existing\n", sdb->treename);
|
|
|
|
return sdb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
|
|
|
|
|
|
|
|
db = _alpm_db_new(treename, 0);
|
|
|
|
db->ops = &sync_db_ops;
|
|
|
|
if(db == NULL) {
|
|
|
|
RET_ERR(PM_ERR_DB_CREATE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
|
|
|
|
return(db);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-02 14:06:52 -05:00
|
|
|
/* vim: set ts=2 sw=2 noet: */
|