[pacman-dev] [PATCH 03/12] Allow frontends to specify the sync database extension
This allows frontends to select between the .db and .files databases currently supplied by repo-add or any other compatible database. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/alpm.c | 4 ++++ lib/libalpm/alpm.h | 3 +++ lib/libalpm/be_sync.c | 15 ++++++++++----- lib/libalpm/db.c | 6 ++++-- lib/libalpm/handle.c | 28 ++++++++++++++++++++++++++++ lib/libalpm/handle.h | 1 + 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 2110286..6fd3932 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -64,6 +64,10 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, goto cleanup; } + /* set default database extension */ + myhandle->dbext = calloc(4, sizeof(char)); + snprintf(myhandle->dbext, 4, "%s", ".db"); + lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; myhandle->lockfile = calloc(lockfilelen, sizeof(char)); snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 06e080b..594f0b6 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -859,6 +859,9 @@ int alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio); int alpm_option_get_checkspace(alpm_handle_t *handle); int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace); +const char *alpm_option_get_dbext(alpm_handle_t *handle); +int alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext); + alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle); int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level); diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index ea979e6..5783f64 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -174,6 +174,7 @@ valid: int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) { char *syncpath; + const char *dbext; alpm_list_t *i; int ret = -1; mode_t oldmask; @@ -208,6 +209,8 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1); } + dbext = db->handle->dbext; + for(i = db->servers; i; i = i->next) { const char *server = i->data, *final_db_url = NULL; struct dload_payload payload; @@ -220,10 +223,10 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) payload.max_size = 25 * 1024 * 1024; /* print server + filename into a buffer */ - len = strlen(server) + strlen(db->treename) + 5; + len = strlen(server) + strlen(db->treename) + strlen(dbext) + 2; /* TODO fix leak syncpath and umask unset */ MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); - snprintf(payload.fileurl, len, "%s/%s.db", server, db->treename); + snprintf(payload.fileurl, len, "%s/%s%s", server, db->treename, dbext); payload.handle = handle; payload.force = force; payload.unlink_on_fail = 1; @@ -244,7 +247,9 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) /* check if the final URL from internal downloader looks reasonable */ if(final_db_url != NULL) { - if(strlen(final_db_url) < 3 || strcmp(final_db_url + strlen(final_db_url) - 3, ".db") != 0) { + if(strlen(final_db_url) < 3 + || strcmp(final_db_url + strlen(final_db_url) - strlen(dbext), + dbext) != 0) { final_db_url = NULL; } } @@ -255,7 +260,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) len = strlen(final_db_url) + 5; } else { /* print server + filename into a buffer (leave space for separator and .db.sig) */ - len = strlen(server) + strlen(db->treename) + 9; + len = strlen(server) + strlen(db->treename) + strlen(dbext) + 5; } /* TODO fix leak syncpath and umask unset */ @@ -264,7 +269,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) if(final_db_url != NULL) { snprintf(payload.fileurl, len, "%s.sig", final_db_url); } else { - snprintf(payload.fileurl, len, "%s/%s.db.sig", server, db->treename); + snprintf(payload.fileurl, len, "%s/%s%s.sig", server, db->treename, dbext); } payload.handle = handle; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index fe208be..b94d334 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -375,10 +375,12 @@ const char *_alpm_db_path(alpm_db_t *db) CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL)); sprintf(db->_path, "%s%s/", dbpath, db->treename); } else { - pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4; + const char *dbext = db->handle->dbext; + + pathsize = strlen(dbpath) + 5 + strlen(db->treename) + strlen(dbext) + 1; CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL)); /* all sync DBs now reside in the sync/ subdir of the dbpath */ - sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename); + sprintf(db->_path, "%ssync/%s%s", dbpath, db->treename, dbext); } _alpm_log(db->handle, ALPM_LOG_DEBUG, "database path for tree %s set to %s\n", db->treename, db->_path); diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 4915d0b..2b43e25 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -81,6 +81,7 @@ void _alpm_handle_free(alpm_handle_t *handle) _alpm_trans_free(handle->trans); FREE(handle->root); FREE(handle->dbpath); + FREE(handle->dbext); FREELIST(handle->cachedirs); FREE(handle->logfile); FREE(handle->lockfile); @@ -284,6 +285,12 @@ int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle) return handle->checkspace; } +const char SYMEXPORT *alpm_option_get_dbext(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->dbext; +} + int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb) { CHECK_HANDLE(handle, return -1); @@ -664,6 +671,27 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace) return 0; } +int SYMEXPORT alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext) +{ + char *olddbext = handle->dbext; + + CHECK_HANDLE(handle, return -1); + if(!dbext) { + handle->pm_errno = ALPM_ERR_WRONG_ARGS; + return -1; + } + + STRDUP(handle->dbext, dbext, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + + /* free the old dbext path string */ + if(olddbext) { + FREE(olddbext); + } + + _alpm_log(handle, ALPM_LOG_DEBUG, "option 'dbext' = %s\n", handle->dbext); + return 0; +} + int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level) { diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 5893139..315d987 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -95,6 +95,7 @@ struct __alpm_handle_t { double deltaratio; /* Download deltas if possible; a ratio value */ int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ int checkspace; /* Check disk space before installing */ + char *dbext; /* Sync DB extension */ alpm_siglevel_t siglevel; /* Default signature verification level */ alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file upgrade operations */ -- 2.4.5
If a sync database contains a "files" file, the file list will be read. Currently, there is no known demand for the file list to be lazy loaded by any libalpm frontend, so these files are read whenever present. Lazy loading can be implemented when a demand exists. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/be_sync.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 5783f64..1c3527e 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -40,6 +40,7 @@ #include "delta.h" #include "deps.h" #include "dload.h" +#include "filelist.h" static char *get_sync_dir(alpm_handle_t *handle) { @@ -438,6 +439,7 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive) /* assume it is at least somewhat compressed */ per_package = 500; } + return (size_t)((st->st_size / per_package) + 1); } @@ -470,6 +472,12 @@ static int sync_db_populate(alpm_db_t *db) } est_count = estimate_package_count(&buf, archive); + /* currently only .files dbs contain file lists - make flexible when required*/ + if(strcmp(db->handle->dbext, ".files") == 0) { + /* files databases are about four times larger on average */ + est_count /= 4; + } + db->pkgcache = _alpm_pkghash_create(est_count); if(db->pkgcache == NULL) { db->handle->pm_errno = ALPM_ERR_MEMORY; @@ -600,6 +608,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive, } if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 + || strcmp(filename, "files") == 0 || (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) { int ret; while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) { @@ -685,6 +694,33 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive, pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(db->handle, line)); } + } else if(strcmp(line, "%FILES%") == 0) { + /* TODO: this could lazy load if there is future demand */ + size_t files_count = 0, files_size = 0; + alpm_file_t *files = NULL; + + while(1) { + if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) { + goto error; + } + line = buf.line; + if(_alpm_strip_newline(line, buf.real_line_size) == 0) { + break; + } + + if(!_alpm_greedy_grow((void **)&files, &files_size, + (files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) { + goto error; + } + STRDUP(files[files_count].name, line, goto error); + files_count++; + } + /* attempt to hand back any memory we don't need */ + files = realloc(files, sizeof(alpm_file_t) * files_count); + /* make sure the list is sorted */ + qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp); + pkg->files.count = files_count; + pkg->files.files = files; } } if(ret != ARCHIVE_EOF) { @@ -693,8 +729,6 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive, *likely_pkg = pkg; } else if(strcmp(filename, "deltas") == 0) { /* skip reading delta files if UseDelta is unset */ - } else if(strcmp(filename, "files") == 0) { - /* currently do nothing with this file */ } else { /* unknown database file */ _alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename); -- 2.4.5
On 07/14/15 at 10:31pm, Allan McRae wrote:
This allows frontends to select between the .db and .files databases currently supplied by repo-add or any other compatible database.
Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/alpm.c | 4 ++++ lib/libalpm/alpm.h | 3 +++ lib/libalpm/be_sync.c | 15 ++++++++++----- lib/libalpm/db.c | 6 ++++-- lib/libalpm/handle.c | 28 ++++++++++++++++++++++++++++ lib/libalpm/handle.h | 1 + 6 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 2110286..6fd3932 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -64,6 +64,10 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, goto cleanup; }
+ /* set default database extension */ + myhandle->dbext = calloc(4, sizeof(char)); + snprintf(myhandle->dbext, 4, "%s", ".db");
STRDUP(myhandle->dbext, ".db", goto cleanup);
lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; myhandle->lockfile = calloc(lockfilelen, sizeof(char)); snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 06e080b..594f0b6 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -859,6 +859,9 @@ int alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio); int alpm_option_get_checkspace(alpm_handle_t *handle); int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
+const char *alpm_option_get_dbext(alpm_handle_t *handle); +int alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext); + alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle); int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index ea979e6..5783f64 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -174,6 +174,7 @@ valid: int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) { char *syncpath; + const char *dbext; alpm_list_t *i; int ret = -1; mode_t oldmask; @@ -208,6 +209,8 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1); }
+ dbext = db->handle->dbext; + for(i = db->servers; i; i = i->next) { const char *server = i->data, *final_db_url = NULL; struct dload_payload payload; @@ -220,10 +223,10 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) payload.max_size = 25 * 1024 * 1024;
/* print server + filename into a buffer */ - len = strlen(server) + strlen(db->treename) + 5; + len = strlen(server) + strlen(db->treename) + strlen(dbext) + 2; /* TODO fix leak syncpath and umask unset */ MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); - snprintf(payload.fileurl, len, "%s/%s.db", server, db->treename); + snprintf(payload.fileurl, len, "%s/%s%s", server, db->treename, dbext); payload.handle = handle; payload.force = force; payload.unlink_on_fail = 1; @@ -244,7 +247,9 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
/* check if the final URL from internal downloader looks reasonable */ if(final_db_url != NULL) { - if(strlen(final_db_url) < 3 || strcmp(final_db_url + strlen(final_db_url) - 3, ".db") != 0) { + if(strlen(final_db_url) < 3 + || strcmp(final_db_url + strlen(final_db_url) - strlen(dbext), + dbext) != 0) { final_db_url = NULL; } } @@ -255,7 +260,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) len = strlen(final_db_url) + 5; } else { /* print server + filename into a buffer (leave space for separator and .db.sig) */ - len = strlen(server) + strlen(db->treename) + 9; + len = strlen(server) + strlen(db->treename) + strlen(dbext) + 5;
Should be + 6.
}
/* TODO fix leak syncpath and umask unset */ @@ -264,7 +269,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) if(final_db_url != NULL) { snprintf(payload.fileurl, len, "%s.sig", final_db_url); } else { - snprintf(payload.fileurl, len, "%s/%s.db.sig", server, db->treename); + snprintf(payload.fileurl, len, "%s/%s%s.sig", server, db->treename, dbext); }
payload.handle = handle; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index fe208be..b94d334 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -375,10 +375,12 @@ const char *_alpm_db_path(alpm_db_t *db) CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL)); sprintf(db->_path, "%s%s/", dbpath, db->treename); } else { - pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4; + const char *dbext = db->handle->dbext; + + pathsize = strlen(dbpath) + 5 + strlen(db->treename) + strlen(dbext) + 1; CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL)); /* all sync DBs now reside in the sync/ subdir of the dbpath */ - sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename); + sprintf(db->_path, "%ssync/%s%s", dbpath, db->treename, dbext); } _alpm_log(db->handle, ALPM_LOG_DEBUG, "database path for tree %s set to %s\n", db->treename, db->_path); diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 4915d0b..2b43e25 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -81,6 +81,7 @@ void _alpm_handle_free(alpm_handle_t *handle) _alpm_trans_free(handle->trans); FREE(handle->root); FREE(handle->dbpath); + FREE(handle->dbext); FREELIST(handle->cachedirs); FREE(handle->logfile); FREE(handle->lockfile); @@ -284,6 +285,12 @@ int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle) return handle->checkspace; }
+const char SYMEXPORT *alpm_option_get_dbext(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->dbext; +} + int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb) { CHECK_HANDLE(handle, return -1); @@ -664,6 +671,27 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace) return 0; }
+int SYMEXPORT alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext) +{ + char *olddbext = handle->dbext;
CHECK_HANDLE needs to be called before dereferencing it.
+ + CHECK_HANDLE(handle, return -1); + if(!dbext) { + handle->pm_errno = ALPM_ERR_WRONG_ARGS; + return -1; + }
Just a style nitpick, but this can be shortened to: ASSERT(dbext, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
+ + STRDUP(handle->dbext, dbext, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
STRDUP modifies the destination even on failure, so saving the old extension won't do any good if this fails. Instead STRDUP should be used to assign to a temporary variable. STRDUP(newdbext, dbext, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); free(handle->dbext); handle->dbext = newdbext;
+ + /* free the old dbext path string */ + if(olddbext) { + FREE(olddbext); + } + + _alpm_log(handle, ALPM_LOG_DEBUG, "option 'dbext' = %s\n", handle->dbext); + return 0; +} + int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level) { diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 5893139..315d987 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -95,6 +95,7 @@ struct __alpm_handle_t { double deltaratio; /* Download deltas if possible; a ratio value */ int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ int checkspace; /* Check disk space before installing */ + char *dbext; /* Sync DB extension */ alpm_siglevel_t siglevel; /* Default signature verification level */ alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file upgrade operations */ -- 2.4.5
participants (2)
-
Allan McRae
-
Andrew Gregory