diff options
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/alpm.h | 1 | ||||
-rw-r--r-- | lib/libalpm/backup.c | 6 | ||||
-rw-r--r-- | lib/libalpm/backup.h | 2 | ||||
-rw-r--r-- | lib/libalpm/be_local.c | 3 | ||||
-rw-r--r-- | lib/libalpm/be_sync.c | 128 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 35 | ||||
-rw-r--r-- | lib/libalpm/db.c | 17 | ||||
-rw-r--r-- | lib/libalpm/diskspace.c | 8 | ||||
-rw-r--r-- | lib/libalpm/dload.c | 6 | ||||
-rw-r--r-- | lib/libalpm/package.c | 6 | ||||
-rw-r--r-- | lib/libalpm/remove.c | 8 | ||||
-rw-r--r-- | lib/libalpm/util.c | 82 | ||||
-rw-r--r-- | lib/libalpm/util.h | 3 |
13 files changed, 158 insertions, 147 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 579b45f2..ac352131 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -695,7 +695,6 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg); int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); int alpm_db_check_pgp_signature(pmdb_t *db); -int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); /* * Groups diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index 20fb8a80..dc0c5674 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -58,16 +58,16 @@ int _alpm_split_backup(const char *string, pmbackup_t **backup) /* Look for a filename in a pmpkg_t.backup list. If we find it, * then we return the full backup entry. */ -pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup) +pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup_list) { const alpm_list_t *lp; - if(file == NULL || backup == NULL) { + if(file == NULL || backup_list == NULL) { return NULL; } /* run through the backup list and parse out the hash for our file */ - for(lp = backup; lp; lp = lp->next) { + for(lp = backup_list; lp; lp = lp->next) { pmbackup_t *backup = lp->data; if(strcmp(file, backup->name) == 0) { diff --git a/lib/libalpm/backup.h b/lib/libalpm/backup.h index 2f632d4a..be8de97a 100644 --- a/lib/libalpm/backup.h +++ b/lib/libalpm/backup.h @@ -24,7 +24,7 @@ #include "alpm.h" int _alpm_split_backup(const char *string, pmbackup_t **backup); -pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup); +pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup_list); void _alpm_backup_free(pmbackup_t *backup); pmbackup_t *_alpm_backup_dup(const pmbackup_t *backup); diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 96f04c51..50066883 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -439,7 +439,8 @@ static int local_db_populate(pmdb_t *db) RET_ERR(db->handle, PM_ERR_MEMORY, -1); } /* split the db entry name */ - if(_alpm_splitname(name, pkg) != 0) { + if(_alpm_splitname(name, &(pkg->name), &(pkg->version), + &(pkg->name_hash)) != 0) { _alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), name); _alpm_pkg_free(pkg); diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index f51ab97a..2bf37dab 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -245,7 +245,61 @@ cleanup: /* 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, pmpkg_t *likely_pkg); + struct archive_entry *entry, pmpkg_t **likely_pkg); + +static pmpkg_t *load_pkg_for_entry(pmdb_t *db, const char *entryname, + const char **entry_filename, pmpkg_t *likely_pkg) +{ + char *pkgname = NULL, *pkgver = NULL; + unsigned long pkgname_hash; + pmpkg_t *pkg; + + /* get package and db file names */ + if(entry_filename) { + char *fname = strrchr(entryname, '/'); + if(fname) { + *entry_filename = fname + 1; + } else { + *entry_filename = NULL; + } + } + if(_alpm_splitname(entryname, &pkgname, &pkgver, &pkgname_hash) != 0) { + _alpm_log(db->handle, PM_LOG_ERROR, + _("invalid name for database entry '%s'\n"), entryname); + return NULL; + } + + if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) { + pkg = likely_pkg; + } else { + pkg = _alpm_pkghash_find(db->pkgcache, pkgname); + } + if(pkg == NULL) { + pkg = _alpm_pkg_new(); + if(pkg == NULL) { + RET_ERR(db->handle, PM_ERR_MEMORY, NULL); + } + + pkg->name = pkgname; + pkg->version = pkgver; + pkg->name_hash = pkgname_hash; + + pkg->origin = PKG_FROM_SYNCDB; + pkg->origin_data.db = db; + pkg->ops = &default_pkg_ops; + pkg->handle = db->handle; + + /* add to the collection */ + _alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", + pkg->name, db->treename); + db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); + } else { + free(pkgname); + free(pkgver); + } + + return pkg; +} /* * This is the data table used to generate the estimating function below. @@ -355,45 +409,10 @@ static int sync_db_populate(pmdb_t *db) st = archive_entry_stat(entry); if(S_ISDIR(st->st_mode)) { - const char *name; - - pkg = _alpm_pkg_new(); - if(pkg == NULL) { - archive_read_finish(archive); - RET_ERR(db->handle, PM_ERR_MEMORY, -1); - } - - name = archive_entry_pathname(entry); - - if(_alpm_splitname(name, pkg) != 0) { - _alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), - name); - _alpm_pkg_free(pkg); - pkg = NULL; - continue; - } - - /* duplicated database entries are not allowed */ - if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { - _alpm_log(db->handle, PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); - _alpm_pkg_free(pkg); - pkg = NULL; - continue; - } - - pkg->origin = PKG_FROM_SYNCDB; - pkg->origin_data.db = db; - pkg->ops = &default_pkg_ops; - pkg->handle = db->handle; - - /* add to the collection */ - _alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", - pkg->name, db->treename); - db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); - count++; + continue; } else { /* we have desc, depends or deltas - parse it */ - if(sync_db_read(db, archive, entry, pkg) != 0) { + if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, PM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); @@ -402,6 +421,8 @@ static int sync_db_populate(pmdb_t *db) } } + count = alpm_list_count(db->pkgcache->list); + if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } @@ -431,10 +452,9 @@ static int sync_db_populate(pmdb_t *db) } while(1) /* note the while(1) and not (0) */ static int sync_db_read(pmdb_t *db, struct archive *archive, - struct archive_entry *entry, pmpkg_t *likely_pkg) + struct archive_entry *entry, pmpkg_t **likely_pkg) { const char *entryname, *filename; - char *pkgname, *p, *q; pmpkg_t *pkg; struct archive_read_buffer buf; @@ -452,27 +472,12 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, /* 512K for a line length seems reasonable */ buf.max_line_size = 512 * 1024; - /* get package and db file names */ - STRDUP(pkgname, entryname, RET_ERR(db->handle, PM_ERR_MEMORY, -1)); - p = pkgname + strlen(pkgname); - for(q = --p; *q && *q != '/'; q--); - filename = q + 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 */ - if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) { - pkg = likely_pkg; - } else { - if(db->pkgcache == NULL) { - RET_ERR(db->handle, PM_ERR_MEMORY, -1); - } - pkg = _alpm_pkghash_find(db->pkgcache, pkgname); - } + pkg = load_pkg_for_entry(db, entryname, &filename, *likely_pkg); + if(pkg == NULL) { - _alpm_log(db->handle, PM_LOG_DEBUG, "package %s not found in %s sync database", - pkgname, db->treename); + _alpm_log(db->handle, PM_LOG_DEBUG, + "entry %s could not be loaded into %s sync database", + entryname, db->treename); return -1; } @@ -559,6 +564,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, if(ret != ARCHIVE_EOF) { goto error; } + *likely_pkg = pkg; } else if(strcmp(filename, "files") == 0) { /* currently do nothing with this file */ } else { @@ -566,12 +572,10 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, _alpm_log(db->handle, PM_LOG_DEBUG, "unknown database file: %s\n", filename); } - FREE(pkgname); return 0; error: _alpm_log(db->handle, PM_LOG_DEBUG, "error parsing database file: %s\n", filename); - FREE(pkgname); return -1; } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 39f42bfe..94d82dd9 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -275,10 +275,10 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, return ret; } -/* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either - * PM_FILECONFLICT_TARGET or PM_FILECONFLICT_FILESYSTEM), a file string, and either - * two package names or one package name and NULL. This is a wrapper for former - * functionality that was done inline. +/* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type + * (either PM_FILECONFLICT_TARGET or PM_FILECONFLICT_FILESYSTEM), a file + * string, and either two package names or one package name and NULL. This is + * a wrapper for former functionality that was done inline. */ static alpm_list_t *add_fileconflict(pmhandle_t *handle, alpm_list_t *conflicts, pmfileconflicttype_t type, const char *filestr, @@ -440,7 +440,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, for(j = tmpfiles; j; j = j->next) { struct stat lsbuf; - const char *filestr = j->data; + const char *filestr = j->data, *relative_path; + /* have we acted on this conflict? */ + int resolved_conflict = 0; snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); @@ -449,7 +451,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, continue; } - if(path[strlen(path)-1] == '/') { + if(path[strlen(path) - 1] == '/') { struct stat sbuf; if(S_ISDIR(lsbuf.st_mode)) { _alpm_log(handle, PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); @@ -461,17 +463,22 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, "%s is a symlink to a dir, hopefully not a conflict\n", path); continue; } + /* if we made it to here, we want all subsequent path comparisons to + * not include the trailing slash. This allows things like file -> + * directory replacements. */ + path[strlen(path) - 1] = '\0'; } - _alpm_log(handle, PM_LOG_DEBUG, "checking possible conflict: %s\n", path); - int resolved_conflict = 0; /* have we acted on this conflict? */ + _alpm_log(handle, PM_LOG_DEBUG, "checking possible conflict: %s\n", path); + relative_path = path + strlen(handle->root); /* Check remove list (will we remove the conflicting local file?) */ for(k = remove; k && !resolved_conflict; k = k->next) { pmpkg_t *rempkg = k->data; - if(rempkg && alpm_list_find_str(alpm_pkg_get_files(rempkg), filestr)) { + if(alpm_list_find_str(alpm_pkg_get_files(rempkg), relative_path)) { _alpm_log(handle, PM_LOG_DEBUG, - "local file will be removed, not a conflict: %s\n", filestr); + "local file will be removed, not a conflict: %s\n", + relative_path); resolved_conflict = 1; } } @@ -492,7 +499,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, handle->trans->skip_remove = alpm_list_add(handle->trans->skip_remove, strdup(filestr)); _alpm_log(handle, PM_LOG_DEBUG, - "file changed packages, adding to remove skiplist: %s\n", filestr); + "file changed packages, adding to remove skiplist: %s\n", + filestr); resolved_conflict = 1; } } @@ -512,12 +520,13 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, if(!resolved_conflict && dbpkg) { char *rpath = calloc(PATH_MAX, sizeof(char)); + const char *relative_rpath; if(!realpath(path, rpath)) { free(rpath); continue; } - char *filestr = rpath + strlen(handle->root); - if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), filestr)) { + relative_rpath = rpath + strlen(handle->root); + if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), relative_rpath)) { resolved_conflict = 1; } free(rpath); diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index b20421a3..9f37f80b 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -211,23 +211,6 @@ int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url) return 1; } -/** Set the verify gpg signature option for a database. - * @param db database pointer - * @param verify enum pgp_verify_t - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ -int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify) -{ - /* Sanity checks */ - ASSERT(db != NULL, return -1); - db->handle->pm_errno = 0; - - db->pgp_verify = verify; - _alpm_log(db->handle, PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n", - db->treename, verify); - - return 0; -} /** Get the name of a package database. */ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 079e683e..51aa47f2 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -262,7 +262,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) alpm_list_t *mount_points, *i; alpm_mountpoint_t *root_mp; size_t replaces = 0, current = 0, numtargs; - int abort = 0; + int error = 0; alpm_list_t *targ; pmtrans_t *trans = handle->trans; @@ -323,7 +323,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) if(data->used && data->read_only) { _alpm_log(handle, PM_LOG_ERROR, _("Partition %s is mounted read only\n"), data->mount_dir); - abort = 1; + error = 1; } else if(data->used & USED_INSTALL) { /* cushion is roughly min(5% capacity, 20MiB) */ long fivepc = ((long)data->fsp.f_blocks / 20) + 1; @@ -338,7 +338,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) _alpm_log(handle, PM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"), data->mount_dir, data->max_blocks_needed + cushion, (unsigned long)data->fsp.f_bfree); - abort = 1; + error = 1; } } } @@ -349,7 +349,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) } FREELIST(mount_points); - if(abort) { + if(error) { RET_ERR(handle, PM_ERR_DISK_SPACE, -1); } diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 33fb1cb8..c7903ff0 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -137,12 +137,12 @@ static int curl_gethost(const char *url, char *buffer) return 0; } -static int utimes_long(const char *path, long time) +static int utimes_long(const char *path, long seconds) { - if(time != -1) { + if(seconds != -1) { struct timeval tv[2]; memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = tv[1].tv_sec = time; + tv[0].tv_sec = tv[1].tv_sec = seconds; return utimes(path, tv); } return 0; diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index e99d5bd4..75ac94c7 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -379,9 +379,9 @@ static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs) for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { pmpkg_t *cachepkg = i->data; - alpm_list_t *i; - for(i = alpm_pkg_get_depends(cachepkg); i; i = i->next) { - if(_alpm_depcmp(pkg, i->data)) { + alpm_list_t *j; + for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) { + if(_alpm_depcmp(pkg, j->data)) { const char *cachepkgname = cachepkg->name; if(alpm_list_find_str(*reqs, cachepkgname) == NULL) { *reqs = alpm_list_add(*reqs, strdup(cachepkgname)); diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index b6a4c715..134c6662 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -287,7 +287,7 @@ int _alpm_upgraderemove_package(pmhandle_t *handle, { alpm_list_t *skip_remove, *b; alpm_list_t *newfiles, *lp; - size_t filenum; + size_t filenum = 0; alpm_list_t *files = alpm_pkg_get_files(oldpkg); const char *pkgname = alpm_pkg_get_name(oldpkg); @@ -323,9 +323,9 @@ int _alpm_upgraderemove_package(pmhandle_t *handle, "not removing package '%s', can't remove all files\n", pkgname); RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1); } + filenum++; } - filenum = alpm_list_count(files); _alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); /* iterate through the list backwards, unlinking files */ @@ -391,7 +391,7 @@ int _alpm_remove_packages(pmhandle_t *handle) if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { alpm_list_t *files = alpm_pkg_get_files(info); alpm_list_t *newfiles; - size_t filenum; + size_t filenum = 0; for(lp = files; lp; lp = lp->next) { if(!can_remove_file(handle, lp->data, NULL)) { @@ -399,9 +399,9 @@ int _alpm_remove_packages(pmhandle_t *handle) pkgname); RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1); } + filenum++; } - filenum = alpm_list_count(files); _alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); /* init progress bar */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 4976703a..6fbe08ae 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -299,13 +299,13 @@ int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix, /* If specific files were requested, skip entries that don't match. */ if(list) { - char *prefix = strdup(entryname); + char *entry_prefix = strdup(entryname); char *p = strstr(prefix,"/"); if(p) { *(p+1) = '\0'; } - char *found = alpm_list_find_str(list, prefix); - free(prefix); + char *found = alpm_list_find_str(list, entry_prefix); + free(entry_prefix); if(!found) { if(archive_read_data_skip(_archive) != ARCHIVE_OK) { ret = 1; @@ -487,22 +487,22 @@ int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]) } else { /* this code runs for the parent only (wait on the child) */ int status; - FILE *pipe; + FILE *pipe_file; close(pipefd[1]); - pipe = fdopen(pipefd[0], "r"); - if(pipe == NULL) { + pipe_file = fdopen(pipefd[0], "r"); + if(pipe_file == NULL) { close(pipefd[0]); retval = 1; } else { - while(!feof(pipe)) { + while(!feof(pipe_file)) { char line[PATH_MAX]; - if(fgets(line, PATH_MAX, pipe) == NULL) + if(fgets(line, PATH_MAX, pipe_file) == NULL) break; alpm_logaction(handle, "%s", line); EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); } - fclose(pipe); + fclose(pipe_file); } while(waitpid(pid, &status, 0) == -1) { @@ -760,9 +760,8 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) &b->block_size, &offset); b->block_offset = b->block; - /* error or end of archive with no data read, cleanup */ - if(b->ret < ARCHIVE_OK || - (b->block_size == 0 && b->ret == ARCHIVE_EOF)) { + /* error, cleanup */ + if(b->ret < ARCHIVE_OK) { goto cleanup; } } @@ -779,19 +778,20 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) /* allocate our buffer, or ensure our existing one is big enough */ if(!b->line) { /* set the initial buffer to the read block_size */ - CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM); + CALLOC(b->line, b->block_size + 1, sizeof(char), b->ret = -ENOMEM; goto cleanup); b->line_size = b->block_size + 1; b->line_offset = b->line; } else { size_t needed = (size_t)((b->line_offset - b->line) + (i - b->block_offset) + 1); if(needed > b->max_line_size) { - return ERANGE; + b->ret = -ERANGE; + goto cleanup; } if(needed > b->line_size) { /* need to realloc + copy data to fit total length */ char *new; - CALLOC(new, needed, sizeof(char), return ENOMEM); + CALLOC(new, needed, sizeof(char), b->ret = -ENOMEM; goto cleanup); memcpy(new, b->line, b->line_size); b->line_size = needed; b->line_offset = new + (b->line_offset - b->line); @@ -813,6 +813,12 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) memcpy(b->line_offset, b->block_offset, len); b->line_offset += len; b->block_offset = i; + /* there was no new data, return what is left; saved ARCHIVE_EOF will be + * returned on next call */ + if(len == 0) { + b->line_offset[0] = '\0'; + return ARCHIVE_OK; + } } } @@ -825,46 +831,54 @@ cleanup: } } -int _alpm_splitname(const char *target, pmpkg_t *pkg) +int _alpm_splitname(const char *target, char **name, char **version, + unsigned long *name_hash) { /* the format of a db entry is as follows: * package-version-rel/ + * package-version-rel/desc (we ignore the filename portion) * package name can contain hyphens, so parse from the back- go back * two hyphens and we have split the version from the name. */ - const char *version, *end; + const char *pkgver, *end; - if(target == NULL || pkg == NULL) { + if(target == NULL) { return -1; } - end = target + strlen(target); - /* remove any trailing '/' */ - while(*(end - 1) == '/') { - --end; + /* remove anything trailing a '/' */ + end = strchr(target, '/'); + if(!end) { + end = target + strlen(target); } /* do the magic parsing- find the beginning of the version string * by doing two iterations of same loop to lop off two hyphens */ - for(version = end - 1; *version && *version != '-'; version--); - for(version = version - 1; *version && *version != '-'; version--); - if(*version != '-' || version == target) { + for(pkgver = end - 1; *pkgver && *pkgver != '-'; pkgver--); + for(pkgver = pkgver - 1; *pkgver && *pkgver != '-'; pkgver--); + if(*pkgver != '-' || pkgver == target) { return -1; } /* copy into fields and return */ - if(pkg->version) { - FREE(pkg->version); + if(version) { + if(*version) { + FREE(*version); + } + /* version actually points to the dash, so need to increment 1 and account + * for potential end character */ + STRNDUP(*version, pkgver + 1, end - pkgver - 1, return -1); } - /* version actually points to the dash, so need to increment 1 and account - * for potential end character */ - STRNDUP(pkg->version, version + 1, end - version - 1, return -1); - if(pkg->name) { - FREE(pkg->name); + if(name) { + if(*name) { + FREE(*name); + } + STRNDUP(*name, target, pkgver - target, return -1); + if(name_hash) { + *name_hash = _alpm_hash_sdbm(*name); + } } - STRNDUP(pkg->name, target, version - target, return -1); - pkg->name_hash = _alpm_hash_sdbm(pkg->name); return 0; } diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 778e20fe..c68b07ba 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -109,7 +109,8 @@ const char *_alpm_filecache_setup(pmhandle_t *handle); int _alpm_lstat(const char *path, struct stat *buf); int _alpm_test_md5sum(const char *filepath, const char *md5sum); int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b); -int _alpm_splitname(const char *target, pmpkg_t *pkg); +int _alpm_splitname(const char *target, char **name, char **version, + unsigned long *name_hash); unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); |