libalpm
Arch Linux Package Manager Library
|
00001 /* 00002 * package.c 00003 * 00004 * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> 00005 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> 00006 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> 00007 * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu> 00008 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org> 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 #include <stdlib.h> 00025 #include <string.h> 00026 #include <sys/types.h> 00027 00028 /* libalpm */ 00029 #include "package.h" 00030 #include "alpm_list.h" 00031 #include "log.h" 00032 #include "util.h" 00033 #include "db.h" 00034 #include "delta.h" 00035 #include "handle.h" 00036 #include "deps.h" 00037 00038 /** \addtogroup alpm_packages Package Functions 00039 * @brief Functions to manipulate libalpm packages 00040 * @{ 00041 */ 00042 00043 /** Free a package. */ 00044 int SYMEXPORT alpm_pkg_free(alpm_pkg_t *pkg) 00045 { 00046 ASSERT(pkg != NULL, return -1); 00047 00048 /* Only free packages loaded in user space */ 00049 if(pkg->origin == PKG_FROM_FILE) { 00050 _alpm_pkg_free(pkg); 00051 } 00052 00053 return 0; 00054 } 00055 00056 /** Check the integrity (with md5) of a package from the sync cache. */ 00057 int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg) 00058 { 00059 char *fpath; 00060 int retval; 00061 00062 ASSERT(pkg != NULL, return -1); 00063 pkg->handle->pm_errno = 0; 00064 /* We only inspect packages from sync repositories */ 00065 ASSERT(pkg->origin == PKG_FROM_SYNCDB, 00066 RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1)); 00067 00068 fpath = _alpm_filecache_find(pkg->handle, pkg->filename); 00069 00070 retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_CSUM_MD5); 00071 00072 if(retval == 0) { 00073 return 0; 00074 } else if(retval == 1) { 00075 pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID; 00076 retval = -1; 00077 } 00078 00079 return retval; 00080 } 00081 00082 /* Default package accessor functions. These will get overridden by any 00083 * backend logic that needs lazy access, such as the local database through 00084 * a lazy-load cache. However, the defaults will work just fine for fully- 00085 * populated package structures. */ 00086 static const char *_pkg_get_desc(alpm_pkg_t *pkg) { return pkg->desc; } 00087 static const char *_pkg_get_url(alpm_pkg_t *pkg) { return pkg->url; } 00088 static alpm_time_t _pkg_get_builddate(alpm_pkg_t *pkg) { return pkg->builddate; } 00089 static alpm_time_t _pkg_get_installdate(alpm_pkg_t *pkg) { return pkg->installdate; } 00090 static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; } 00091 static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; } 00092 static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; } 00093 static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; } 00094 static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; } 00095 00096 static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; } 00097 static alpm_list_t *_pkg_get_groups(alpm_pkg_t *pkg) { return pkg->groups; } 00098 static alpm_list_t *_pkg_get_depends(alpm_pkg_t *pkg) { return pkg->depends; } 00099 static alpm_list_t *_pkg_get_optdepends(alpm_pkg_t *pkg) { return pkg->optdepends; } 00100 static alpm_list_t *_pkg_get_conflicts(alpm_pkg_t *pkg) { return pkg->conflicts; } 00101 static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides; } 00102 static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; } 00103 static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); } 00104 static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; } 00105 00106 static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg) 00107 { 00108 return NULL; 00109 } 00110 00111 static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size, 00112 const alpm_pkg_t UNUSED *pkg, UNUSED void *fp) 00113 { 00114 return 0; 00115 } 00116 00117 static int _pkg_changelog_close(const alpm_pkg_t UNUSED *pkg, 00118 void UNUSED *fp) 00119 { 00120 return EOF; 00121 } 00122 00123 static int _pkg_force_load(alpm_pkg_t UNUSED *pkg) { return 0; } 00124 00125 /** The standard package operations struct. Get fields directly from the 00126 * struct itself with no abstraction layer or any type of lazy loading. 00127 */ 00128 struct pkg_operations default_pkg_ops = { 00129 .get_desc = _pkg_get_desc, 00130 .get_url = _pkg_get_url, 00131 .get_builddate = _pkg_get_builddate, 00132 .get_installdate = _pkg_get_installdate, 00133 .get_packager = _pkg_get_packager, 00134 .get_arch = _pkg_get_arch, 00135 .get_isize = _pkg_get_isize, 00136 .get_reason = _pkg_get_reason, 00137 .has_scriptlet = _pkg_has_scriptlet, 00138 00139 .get_licenses = _pkg_get_licenses, 00140 .get_groups = _pkg_get_groups, 00141 .get_depends = _pkg_get_depends, 00142 .get_optdepends = _pkg_get_optdepends, 00143 .get_conflicts = _pkg_get_conflicts, 00144 .get_provides = _pkg_get_provides, 00145 .get_replaces = _pkg_get_replaces, 00146 .get_files = _pkg_get_files, 00147 .get_backup = _pkg_get_backup, 00148 00149 .changelog_open = _pkg_changelog_open, 00150 .changelog_read = _pkg_changelog_read, 00151 .changelog_close = _pkg_changelog_close, 00152 00153 .force_load = _pkg_force_load, 00154 }; 00155 00156 /* Public functions for getting package information. These functions 00157 * delegate the hard work to the function callbacks attached to each 00158 * package, which depend on where the package was loaded from. */ 00159 const char SYMEXPORT *alpm_pkg_get_filename(alpm_pkg_t *pkg) 00160 { 00161 ASSERT(pkg != NULL, return NULL); 00162 pkg->handle->pm_errno = 0; 00163 return pkg->filename; 00164 } 00165 00166 const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg) 00167 { 00168 ASSERT(pkg != NULL, return NULL); 00169 pkg->handle->pm_errno = 0; 00170 return pkg->name; 00171 } 00172 00173 const char SYMEXPORT *alpm_pkg_get_version(alpm_pkg_t *pkg) 00174 { 00175 ASSERT(pkg != NULL, return NULL); 00176 pkg->handle->pm_errno = 0; 00177 return pkg->version; 00178 } 00179 00180 alpm_pkgfrom_t SYMEXPORT alpm_pkg_get_origin(alpm_pkg_t *pkg) 00181 { 00182 ASSERT(pkg != NULL, return -1); 00183 pkg->handle->pm_errno = 0; 00184 return pkg->origin; 00185 } 00186 00187 const char SYMEXPORT *alpm_pkg_get_desc(alpm_pkg_t *pkg) 00188 { 00189 ASSERT(pkg != NULL, return NULL); 00190 pkg->handle->pm_errno = 0; 00191 return pkg->ops->get_desc(pkg); 00192 } 00193 00194 const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg) 00195 { 00196 ASSERT(pkg != NULL, return NULL); 00197 pkg->handle->pm_errno = 0; 00198 return pkg->ops->get_url(pkg); 00199 } 00200 00201 alpm_time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg) 00202 { 00203 ASSERT(pkg != NULL, return -1); 00204 pkg->handle->pm_errno = 0; 00205 return pkg->ops->get_builddate(pkg); 00206 } 00207 00208 alpm_time_t SYMEXPORT alpm_pkg_get_installdate(alpm_pkg_t *pkg) 00209 { 00210 ASSERT(pkg != NULL, return -1); 00211 pkg->handle->pm_errno = 0; 00212 return pkg->ops->get_installdate(pkg); 00213 } 00214 00215 const char SYMEXPORT *alpm_pkg_get_packager(alpm_pkg_t *pkg) 00216 { 00217 ASSERT(pkg != NULL, return NULL); 00218 pkg->handle->pm_errno = 0; 00219 return pkg->ops->get_packager(pkg); 00220 } 00221 00222 const char SYMEXPORT *alpm_pkg_get_md5sum(alpm_pkg_t *pkg) 00223 { 00224 ASSERT(pkg != NULL, return NULL); 00225 pkg->handle->pm_errno = 0; 00226 return pkg->md5sum; 00227 } 00228 00229 const char SYMEXPORT *alpm_pkg_get_sha256sum(alpm_pkg_t *pkg) 00230 { 00231 ASSERT(pkg != NULL, return NULL); 00232 pkg->handle->pm_errno = 0; 00233 return pkg->sha256sum; 00234 } 00235 00236 const char SYMEXPORT *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg) 00237 { 00238 ASSERT(pkg != NULL, return NULL); 00239 pkg->handle->pm_errno = 0; 00240 return pkg->base64_sig; 00241 } 00242 00243 const char SYMEXPORT *alpm_pkg_get_arch(alpm_pkg_t *pkg) 00244 { 00245 ASSERT(pkg != NULL, return NULL); 00246 pkg->handle->pm_errno = 0; 00247 return pkg->ops->get_arch(pkg); 00248 } 00249 00250 off_t SYMEXPORT alpm_pkg_get_size(alpm_pkg_t *pkg) 00251 { 00252 ASSERT(pkg != NULL, return -1); 00253 pkg->handle->pm_errno = 0; 00254 return pkg->size; 00255 } 00256 00257 off_t SYMEXPORT alpm_pkg_get_isize(alpm_pkg_t *pkg) 00258 { 00259 ASSERT(pkg != NULL, return -1); 00260 pkg->handle->pm_errno = 0; 00261 return pkg->ops->get_isize(pkg); 00262 } 00263 00264 alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg) 00265 { 00266 ASSERT(pkg != NULL, return -1); 00267 pkg->handle->pm_errno = 0; 00268 return pkg->ops->get_reason(pkg); 00269 } 00270 00271 alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg) 00272 { 00273 ASSERT(pkg != NULL, return NULL); 00274 pkg->handle->pm_errno = 0; 00275 return pkg->ops->get_licenses(pkg); 00276 } 00277 00278 alpm_list_t SYMEXPORT *alpm_pkg_get_groups(alpm_pkg_t *pkg) 00279 { 00280 ASSERT(pkg != NULL, return NULL); 00281 pkg->handle->pm_errno = 0; 00282 return pkg->ops->get_groups(pkg); 00283 } 00284 00285 alpm_list_t SYMEXPORT *alpm_pkg_get_depends(alpm_pkg_t *pkg) 00286 { 00287 ASSERT(pkg != NULL, return NULL); 00288 pkg->handle->pm_errno = 0; 00289 return pkg->ops->get_depends(pkg); 00290 } 00291 00292 alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(alpm_pkg_t *pkg) 00293 { 00294 ASSERT(pkg != NULL, return NULL); 00295 pkg->handle->pm_errno = 0; 00296 return pkg->ops->get_optdepends(pkg); 00297 } 00298 00299 alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(alpm_pkg_t *pkg) 00300 { 00301 ASSERT(pkg != NULL, return NULL); 00302 pkg->handle->pm_errno = 0; 00303 return pkg->ops->get_conflicts(pkg); 00304 } 00305 00306 alpm_list_t SYMEXPORT *alpm_pkg_get_provides(alpm_pkg_t *pkg) 00307 { 00308 ASSERT(pkg != NULL, return NULL); 00309 pkg->handle->pm_errno = 0; 00310 return pkg->ops->get_provides(pkg); 00311 } 00312 00313 alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg) 00314 { 00315 ASSERT(pkg != NULL, return NULL); 00316 pkg->handle->pm_errno = 0; 00317 return pkg->ops->get_replaces(pkg); 00318 } 00319 00320 alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg) 00321 { 00322 ASSERT(pkg != NULL, return NULL); 00323 pkg->handle->pm_errno = 0; 00324 return pkg->deltas; 00325 } 00326 00327 alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg) 00328 { 00329 ASSERT(pkg != NULL, return NULL); 00330 pkg->handle->pm_errno = 0; 00331 return pkg->ops->get_files(pkg); 00332 } 00333 00334 alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg) 00335 { 00336 ASSERT(pkg != NULL, return NULL); 00337 pkg->handle->pm_errno = 0; 00338 return pkg->ops->get_backup(pkg); 00339 } 00340 00341 alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg) 00342 { 00343 /* Sanity checks */ 00344 ASSERT(pkg != NULL, return NULL); 00345 ASSERT(pkg->origin != PKG_FROM_FILE, return NULL); 00346 pkg->handle->pm_errno = 0; 00347 00348 return pkg->origin_data.db; 00349 } 00350 00351 /** Open a package changelog for reading. */ 00352 void SYMEXPORT *alpm_pkg_changelog_open(alpm_pkg_t *pkg) 00353 { 00354 ASSERT(pkg != NULL, return NULL); 00355 pkg->handle->pm_errno = 0; 00356 return pkg->ops->changelog_open(pkg); 00357 } 00358 00359 /** Read data from an open changelog 'file stream'. */ 00360 size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size, 00361 const alpm_pkg_t *pkg, void *fp) 00362 { 00363 ASSERT(pkg != NULL, return 0); 00364 pkg->handle->pm_errno = 0; 00365 return pkg->ops->changelog_read(ptr, size, pkg, fp); 00366 } 00367 00368 /** Close a package changelog for reading. */ 00369 int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp) 00370 { 00371 ASSERT(pkg != NULL, return -1); 00372 pkg->handle->pm_errno = 0; 00373 return pkg->ops->changelog_close(pkg, fp); 00374 } 00375 00376 int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg) 00377 { 00378 ASSERT(pkg != NULL, return -1); 00379 pkg->handle->pm_errno = 0; 00380 return pkg->ops->has_scriptlet(pkg); 00381 } 00382 00383 static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs) 00384 { 00385 const alpm_list_t *i; 00386 pkg->handle->pm_errno = 0; 00387 00388 for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { 00389 alpm_pkg_t *cachepkg = i->data; 00390 alpm_list_t *j; 00391 for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) { 00392 if(_alpm_depcmp(pkg, j->data)) { 00393 const char *cachepkgname = cachepkg->name; 00394 if(alpm_list_find_str(*reqs, cachepkgname) == NULL) { 00395 *reqs = alpm_list_add(*reqs, strdup(cachepkgname)); 00396 } 00397 } 00398 } 00399 } 00400 } 00401 00402 /** Compute the packages requiring a given package. */ 00403 alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg) 00404 { 00405 const alpm_list_t *i; 00406 alpm_list_t *reqs = NULL; 00407 alpm_db_t *db; 00408 00409 ASSERT(pkg != NULL, return NULL); 00410 pkg->handle->pm_errno = 0; 00411 00412 if(pkg->origin == PKG_FROM_FILE) { 00413 /* The sane option; search locally for things that require this. */ 00414 find_requiredby(pkg, pkg->handle->db_local, &reqs); 00415 } else { 00416 /* We have a DB package. if it is a local package, then we should 00417 * only search the local DB; else search all known sync databases. */ 00418 db = pkg->origin_data.db; 00419 if(db->status & DB_STATUS_LOCAL) { 00420 find_requiredby(pkg, db, &reqs); 00421 } else { 00422 for(i = pkg->handle->dbs_sync; i; i = i->next) { 00423 db = i->data; 00424 find_requiredby(pkg, db, &reqs); 00425 } 00426 reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp); 00427 } 00428 } 00429 return reqs; 00430 } 00431 00432 /** @} */ 00433 00434 alpm_file_t *_alpm_file_copy(alpm_file_t *dest, 00435 const alpm_file_t *src) 00436 { 00437 STRDUP(dest->name, src->name, return NULL); 00438 dest->size = src->size; 00439 dest->mode = src->mode; 00440 00441 return dest; 00442 } 00443 00444 /* Helper function for comparing files list entries 00445 */ 00446 int _alpm_files_cmp(const void *f1, const void *f2) 00447 { 00448 const alpm_file_t *file1 = f1; 00449 const alpm_file_t *file2 = f2; 00450 return strcmp(file1->name, file2->name); 00451 } 00452 00453 alpm_pkg_t *_alpm_pkg_new(void) 00454 { 00455 alpm_pkg_t* pkg; 00456 00457 CALLOC(pkg, 1, sizeof(alpm_pkg_t), return NULL); 00458 00459 return pkg; 00460 } 00461 00462 static alpm_list_t *list_depdup(alpm_list_t *old) 00463 { 00464 alpm_list_t *i, *new = NULL; 00465 for(i = old; i; i = i->next) { 00466 new = alpm_list_add(new, _alpm_dep_dup(i->data)); 00467 } 00468 return new; 00469 } 00470 00471 /** 00472 * Duplicate a package data struct. 00473 * @param pkg the package to duplicate 00474 * @param new_ptr location to store duplicated package pointer 00475 * @return 0 on success, -1 on fatal error, 1 on non-fatal error 00476 */ 00477 int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr) 00478 { 00479 alpm_pkg_t *newpkg; 00480 alpm_list_t *i; 00481 int ret = 0; 00482 00483 if(!pkg || !pkg->handle) { 00484 return -1; 00485 } 00486 00487 if(!new_ptr) { 00488 RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1); 00489 } 00490 00491 if(pkg->ops->force_load(pkg)) { 00492 _alpm_log(pkg->handle, ALPM_LOG_WARNING, 00493 _("could not fully load metadata for package %s-%s\n"), 00494 pkg->name, pkg->version); 00495 ret = 1; 00496 pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID; 00497 } 00498 00499 CALLOC(newpkg, 1, sizeof(alpm_pkg_t), goto cleanup); 00500 00501 newpkg->name_hash = pkg->name_hash; 00502 STRDUP(newpkg->filename, pkg->filename, goto cleanup); 00503 STRDUP(newpkg->name, pkg->name, goto cleanup); 00504 STRDUP(newpkg->version, pkg->version, goto cleanup); 00505 STRDUP(newpkg->desc, pkg->desc, goto cleanup); 00506 STRDUP(newpkg->url, pkg->url, goto cleanup); 00507 newpkg->builddate = pkg->builddate; 00508 newpkg->installdate = pkg->installdate; 00509 STRDUP(newpkg->packager, pkg->packager, goto cleanup); 00510 STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup); 00511 STRDUP(newpkg->sha256sum, pkg->md5sum, goto cleanup); 00512 STRDUP(newpkg->arch, pkg->arch, goto cleanup); 00513 newpkg->size = pkg->size; 00514 newpkg->isize = pkg->isize; 00515 newpkg->scriptlet = pkg->scriptlet; 00516 newpkg->reason = pkg->reason; 00517 00518 newpkg->licenses = alpm_list_strdup(pkg->licenses); 00519 newpkg->replaces = list_depdup(pkg->replaces); 00520 newpkg->groups = alpm_list_strdup(pkg->groups); 00521 for(i = pkg->backup; i; i = i->next) { 00522 newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data)); 00523 } 00524 newpkg->depends = list_depdup(pkg->depends); 00525 newpkg->optdepends = alpm_list_strdup(pkg->optdepends); 00526 newpkg->conflicts = list_depdup(pkg->conflicts); 00527 newpkg->provides = list_depdup(pkg->provides); 00528 for(i = pkg->deltas; i; i = i->next) { 00529 newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data)); 00530 } 00531 00532 if(pkg->files.count) { 00533 size_t filenum; 00534 size_t len = sizeof(alpm_file_t) * pkg->files.count; 00535 MALLOC(newpkg->files.files, len, goto cleanup); 00536 for(filenum = 0; filenum < pkg->files.count; filenum++) { 00537 if(!_alpm_file_copy(newpkg->files.files + filenum, 00538 pkg->files.files + filenum)) { 00539 goto cleanup; 00540 } 00541 } 00542 newpkg->files.count = pkg->files.count; 00543 } 00544 00545 /* internal */ 00546 newpkg->infolevel = pkg->infolevel; 00547 newpkg->origin = pkg->origin; 00548 if(newpkg->origin == PKG_FROM_FILE) { 00549 newpkg->origin_data.file = strdup(pkg->origin_data.file); 00550 } else { 00551 newpkg->origin_data.db = pkg->origin_data.db; 00552 } 00553 newpkg->ops = pkg->ops; 00554 newpkg->handle = pkg->handle; 00555 00556 *new_ptr = newpkg; 00557 return ret; 00558 00559 cleanup: 00560 _alpm_pkg_free(newpkg); 00561 RET_ERR(pkg->handle, ALPM_ERR_MEMORY, -1); 00562 } 00563 00564 static void free_deplist(alpm_list_t *deps) 00565 { 00566 alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_dep_free); 00567 alpm_list_free(deps); 00568 } 00569 00570 void _alpm_pkg_free(alpm_pkg_t *pkg) 00571 { 00572 if(pkg == NULL) { 00573 return; 00574 } 00575 00576 FREE(pkg->filename); 00577 FREE(pkg->name); 00578 FREE(pkg->version); 00579 FREE(pkg->desc); 00580 FREE(pkg->url); 00581 FREE(pkg->packager); 00582 FREE(pkg->md5sum); 00583 FREE(pkg->sha256sum); 00584 FREE(pkg->base64_sig); 00585 FREE(pkg->arch); 00586 00587 FREELIST(pkg->licenses); 00588 free_deplist(pkg->replaces); 00589 FREELIST(pkg->groups); 00590 if(pkg->files.count) { 00591 size_t i; 00592 for(i = 0; i < pkg->files.count; i++) { 00593 free(pkg->files.files[i].name); 00594 } 00595 free(pkg->files.files); 00596 } 00597 alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free); 00598 alpm_list_free(pkg->backup); 00599 free_deplist(pkg->depends); 00600 FREELIST(pkg->optdepends); 00601 free_deplist(pkg->conflicts); 00602 free_deplist(pkg->provides); 00603 alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free); 00604 alpm_list_free(pkg->deltas); 00605 alpm_list_free(pkg->delta_path); 00606 alpm_list_free(pkg->removes); 00607 00608 if(pkg->origin == PKG_FROM_FILE) { 00609 FREE(pkg->origin_data.file); 00610 } 00611 FREE(pkg); 00612 } 00613 00614 /* This function should be used when removing a target from upgrade/sync target list 00615 * Case 1: If pkg is a loaded package file (PKG_FROM_FILE), it will be freed. 00616 * Case 2: If pkg is a pkgcache entry (PKG_FROM_CACHE), it won't be freed, 00617 * only the transaction specific fields of pkg will be freed. 00618 */ 00619 void _alpm_pkg_free_trans(alpm_pkg_t *pkg) 00620 { 00621 if(pkg == NULL) { 00622 return; 00623 } 00624 00625 if(pkg->origin == PKG_FROM_FILE) { 00626 _alpm_pkg_free(pkg); 00627 return; 00628 } 00629 00630 alpm_list_free(pkg->removes); 00631 pkg->removes = NULL; 00632 } 00633 00634 /* Is spkg an upgrade for localpkg? */ 00635 int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg) 00636 { 00637 return alpm_pkg_vercmp(spkg->version, localpkg->version); 00638 } 00639 00640 /* Helper function for comparing packages 00641 */ 00642 int _alpm_pkg_cmp(const void *p1, const void *p2) 00643 { 00644 const alpm_pkg_t *pkg1 = p1; 00645 const alpm_pkg_t *pkg2 = p2; 00646 return strcmp(pkg1->name, pkg2->name); 00647 } 00648 00649 /* Test for existence of a package in a alpm_list_t* 00650 * of alpm_pkg_t* 00651 */ 00652 alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) 00653 { 00654 alpm_list_t *lp; 00655 unsigned long needle_hash; 00656 00657 if(needle == NULL || haystack == NULL) { 00658 return NULL; 00659 } 00660 00661 needle_hash = _alpm_hash_sdbm(needle); 00662 00663 for(lp = haystack; lp; lp = lp->next) { 00664 alpm_pkg_t *info = lp->data; 00665 00666 if(info) { 00667 if(info->name_hash != needle_hash) { 00668 continue; 00669 } 00670 00671 /* finally: we had hash match, verify string match */ 00672 if(strcmp(info->name, needle) == 0) { 00673 return info; 00674 } 00675 } 00676 } 00677 return NULL; 00678 } 00679 00680 /** Test if a package should be ignored. 00681 * 00682 * Checks if the package is ignored via IgnorePkg, or if the package is 00683 * in a group ignored via IgnoreGroup. 00684 * 00685 * @param handle the context handle 00686 * @param pkg the package to test 00687 * 00688 * @return 1 if the package should be ignored, 0 otherwise 00689 */ 00690 int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg) 00691 { 00692 alpm_list_t *groups = NULL; 00693 00694 /* first see if the package is ignored */ 00695 if(alpm_list_find(handle->ignorepkg, pkg->name, _alpm_fnmatch)) { 00696 return 1; 00697 } 00698 00699 /* next see if the package is in a group that is ignored */ 00700 for(groups = alpm_pkg_get_groups(pkg); groups; groups = groups->next) { 00701 char *grp = groups->data; 00702 if(alpm_list_find(handle->ignoregroup, grp, _alpm_fnmatch)) { 00703 return 1; 00704 } 00705 } 00706 00707 return 0; 00708 } 00709 00710 /* vim: set ts=2 sw=2 noet: */