makepkg: prevent issues with files starting with a hyphen
[pacman-ng.git] / lib / libalpm / package.c
blob6b6486757eee5aab94009b4446f39b0e9146ac0c
1 /*
2 * package.c
4 * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
5 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
6 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
7 * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu>
8 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
28 /* libalpm */
29 #include "package.h"
30 #include "alpm_list.h"
31 #include "log.h"
32 #include "util.h"
33 #include "db.h"
34 #include "delta.h"
35 #include "handle.h"
36 #include "deps.h"
38 /** \addtogroup alpm_packages Package Functions
39 * @brief Functions to manipulate libalpm packages
40 * @{
43 /** Free a package. */
44 int SYMEXPORT alpm_pkg_free(alpm_pkg_t *pkg)
46 ASSERT(pkg != NULL, return -1);
48 /* Only free packages loaded in user space */
49 if(pkg->origin == PKG_FROM_FILE) {
50 _alpm_pkg_free(pkg);
53 return 0;
56 /** Check the integrity (with md5) of a package from the sync cache. */
57 int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
59 char *fpath;
60 int retval;
62 ASSERT(pkg != NULL, return -1);
63 pkg->handle->pm_errno = 0;
64 /* We only inspect packages from sync repositories */
65 ASSERT(pkg->origin == PKG_FROM_SYNCDB,
66 RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
68 fpath = _alpm_filecache_find(pkg->handle, pkg->filename);
70 retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM);
72 if(retval == 0) {
73 return 0;
74 } else if(retval == 1) {
75 pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID;
76 retval = -1;
79 return retval;
82 /* Default package accessor functions. These will get overridden by any
83 * backend logic that needs lazy access, such as the local database through
84 * a lazy-load cache. However, the defaults will work just fine for fully-
85 * populated package structures. */
86 static const char *_pkg_get_desc(alpm_pkg_t *pkg) { return pkg->desc; }
87 static const char *_pkg_get_url(alpm_pkg_t *pkg) { return pkg->url; }
88 static alpm_time_t _pkg_get_builddate(alpm_pkg_t *pkg) { return pkg->builddate; }
89 static alpm_time_t _pkg_get_installdate(alpm_pkg_t *pkg) { return pkg->installdate; }
90 static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; }
91 static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; }
92 static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; }
93 static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; }
94 static alpm_pkgvalidation_t _pkg_get_validation(alpm_pkg_t *pkg) { return pkg->validation; }
95 static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; }
97 static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; }
98 static alpm_list_t *_pkg_get_groups(alpm_pkg_t *pkg) { return pkg->groups; }
99 static alpm_list_t *_pkg_get_depends(alpm_pkg_t *pkg) { return pkg->depends; }
100 static alpm_list_t *_pkg_get_optdepends(alpm_pkg_t *pkg) { return pkg->optdepends; }
101 static alpm_list_t *_pkg_get_conflicts(alpm_pkg_t *pkg) { return pkg->conflicts; }
102 static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides; }
103 static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; }
104 static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
105 static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
107 static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
109 return NULL;
112 static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size,
113 const alpm_pkg_t UNUSED *pkg, UNUSED void *fp)
115 return 0;
118 static int _pkg_changelog_close(const alpm_pkg_t UNUSED *pkg,
119 void UNUSED *fp)
121 return EOF;
124 static int _pkg_force_load(alpm_pkg_t UNUSED *pkg) { return 0; }
126 /** The standard package operations struct. Get fields directly from the
127 * struct itself with no abstraction layer or any type of lazy loading.
129 struct pkg_operations default_pkg_ops = {
130 .get_desc = _pkg_get_desc,
131 .get_url = _pkg_get_url,
132 .get_builddate = _pkg_get_builddate,
133 .get_installdate = _pkg_get_installdate,
134 .get_packager = _pkg_get_packager,
135 .get_arch = _pkg_get_arch,
136 .get_isize = _pkg_get_isize,
137 .get_reason = _pkg_get_reason,
138 .get_validation = _pkg_get_validation,
139 .has_scriptlet = _pkg_has_scriptlet,
141 .get_licenses = _pkg_get_licenses,
142 .get_groups = _pkg_get_groups,
143 .get_depends = _pkg_get_depends,
144 .get_optdepends = _pkg_get_optdepends,
145 .get_conflicts = _pkg_get_conflicts,
146 .get_provides = _pkg_get_provides,
147 .get_replaces = _pkg_get_replaces,
148 .get_files = _pkg_get_files,
149 .get_backup = _pkg_get_backup,
151 .changelog_open = _pkg_changelog_open,
152 .changelog_read = _pkg_changelog_read,
153 .changelog_close = _pkg_changelog_close,
155 .force_load = _pkg_force_load,
158 /* Public functions for getting package information. These functions
159 * delegate the hard work to the function callbacks attached to each
160 * package, which depend on where the package was loaded from. */
161 const char SYMEXPORT *alpm_pkg_get_filename(alpm_pkg_t *pkg)
163 ASSERT(pkg != NULL, return NULL);
164 pkg->handle->pm_errno = 0;
165 return pkg->filename;
168 const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg)
170 ASSERT(pkg != NULL, return NULL);
171 pkg->handle->pm_errno = 0;
172 return pkg->name;
175 const char SYMEXPORT *alpm_pkg_get_version(alpm_pkg_t *pkg)
177 ASSERT(pkg != NULL, return NULL);
178 pkg->handle->pm_errno = 0;
179 return pkg->version;
182 alpm_pkgfrom_t SYMEXPORT alpm_pkg_get_origin(alpm_pkg_t *pkg)
184 ASSERT(pkg != NULL, return -1);
185 pkg->handle->pm_errno = 0;
186 return pkg->origin;
189 const char SYMEXPORT *alpm_pkg_get_desc(alpm_pkg_t *pkg)
191 ASSERT(pkg != NULL, return NULL);
192 pkg->handle->pm_errno = 0;
193 return pkg->ops->get_desc(pkg);
196 const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg)
198 ASSERT(pkg != NULL, return NULL);
199 pkg->handle->pm_errno = 0;
200 return pkg->ops->get_url(pkg);
203 alpm_time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg)
205 ASSERT(pkg != NULL, return -1);
206 pkg->handle->pm_errno = 0;
207 return pkg->ops->get_builddate(pkg);
210 alpm_time_t SYMEXPORT alpm_pkg_get_installdate(alpm_pkg_t *pkg)
212 ASSERT(pkg != NULL, return -1);
213 pkg->handle->pm_errno = 0;
214 return pkg->ops->get_installdate(pkg);
217 const char SYMEXPORT *alpm_pkg_get_packager(alpm_pkg_t *pkg)
219 ASSERT(pkg != NULL, return NULL);
220 pkg->handle->pm_errno = 0;
221 return pkg->ops->get_packager(pkg);
224 const char SYMEXPORT *alpm_pkg_get_md5sum(alpm_pkg_t *pkg)
226 ASSERT(pkg != NULL, return NULL);
227 pkg->handle->pm_errno = 0;
228 return pkg->md5sum;
231 const char SYMEXPORT *alpm_pkg_get_sha256sum(alpm_pkg_t *pkg)
233 ASSERT(pkg != NULL, return NULL);
234 pkg->handle->pm_errno = 0;
235 return pkg->sha256sum;
238 const char SYMEXPORT *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg)
240 ASSERT(pkg != NULL, return NULL);
241 pkg->handle->pm_errno = 0;
242 return pkg->base64_sig;
245 const char SYMEXPORT *alpm_pkg_get_arch(alpm_pkg_t *pkg)
247 ASSERT(pkg != NULL, return NULL);
248 pkg->handle->pm_errno = 0;
249 return pkg->ops->get_arch(pkg);
252 off_t SYMEXPORT alpm_pkg_get_size(alpm_pkg_t *pkg)
254 ASSERT(pkg != NULL, return -1);
255 pkg->handle->pm_errno = 0;
256 return pkg->size;
259 off_t SYMEXPORT alpm_pkg_get_isize(alpm_pkg_t *pkg)
261 ASSERT(pkg != NULL, return -1);
262 pkg->handle->pm_errno = 0;
263 return pkg->ops->get_isize(pkg);
266 alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg)
268 ASSERT(pkg != NULL, return -1);
269 pkg->handle->pm_errno = 0;
270 return pkg->ops->get_reason(pkg);
273 alpm_pkgvalidation_t SYMEXPORT alpm_pkg_get_validation(alpm_pkg_t *pkg)
275 ASSERT(pkg != NULL, return -1);
276 pkg->handle->pm_errno = 0;
277 return pkg->ops->get_validation(pkg);
280 alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg)
282 ASSERT(pkg != NULL, return NULL);
283 pkg->handle->pm_errno = 0;
284 return pkg->ops->get_licenses(pkg);
287 alpm_list_t SYMEXPORT *alpm_pkg_get_groups(alpm_pkg_t *pkg)
289 ASSERT(pkg != NULL, return NULL);
290 pkg->handle->pm_errno = 0;
291 return pkg->ops->get_groups(pkg);
294 alpm_list_t SYMEXPORT *alpm_pkg_get_depends(alpm_pkg_t *pkg)
296 ASSERT(pkg != NULL, return NULL);
297 pkg->handle->pm_errno = 0;
298 return pkg->ops->get_depends(pkg);
301 alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(alpm_pkg_t *pkg)
303 ASSERT(pkg != NULL, return NULL);
304 pkg->handle->pm_errno = 0;
305 return pkg->ops->get_optdepends(pkg);
308 alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(alpm_pkg_t *pkg)
310 ASSERT(pkg != NULL, return NULL);
311 pkg->handle->pm_errno = 0;
312 return pkg->ops->get_conflicts(pkg);
315 alpm_list_t SYMEXPORT *alpm_pkg_get_provides(alpm_pkg_t *pkg)
317 ASSERT(pkg != NULL, return NULL);
318 pkg->handle->pm_errno = 0;
319 return pkg->ops->get_provides(pkg);
322 alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg)
324 ASSERT(pkg != NULL, return NULL);
325 pkg->handle->pm_errno = 0;
326 return pkg->ops->get_replaces(pkg);
329 alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg)
331 ASSERT(pkg != NULL, return NULL);
332 pkg->handle->pm_errno = 0;
333 return pkg->deltas;
336 alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg)
338 ASSERT(pkg != NULL, return NULL);
339 pkg->handle->pm_errno = 0;
340 return pkg->ops->get_files(pkg);
343 alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg)
345 ASSERT(pkg != NULL, return NULL);
346 pkg->handle->pm_errno = 0;
347 return pkg->ops->get_backup(pkg);
350 alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg)
352 /* Sanity checks */
353 ASSERT(pkg != NULL, return NULL);
354 ASSERT(pkg->origin != PKG_FROM_FILE, return NULL);
355 pkg->handle->pm_errno = 0;
357 return pkg->origin_data.db;
360 /** Open a package changelog for reading. */
361 void SYMEXPORT *alpm_pkg_changelog_open(alpm_pkg_t *pkg)
363 ASSERT(pkg != NULL, return NULL);
364 pkg->handle->pm_errno = 0;
365 return pkg->ops->changelog_open(pkg);
368 /** Read data from an open changelog 'file stream'. */
369 size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,
370 const alpm_pkg_t *pkg, void *fp)
372 ASSERT(pkg != NULL, return 0);
373 pkg->handle->pm_errno = 0;
374 return pkg->ops->changelog_read(ptr, size, pkg, fp);
377 /** Close a package changelog for reading. */
378 int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp)
380 ASSERT(pkg != NULL, return -1);
381 pkg->handle->pm_errno = 0;
382 return pkg->ops->changelog_close(pkg, fp);
385 int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg)
387 ASSERT(pkg != NULL, return -1);
388 pkg->handle->pm_errno = 0;
389 return pkg->ops->has_scriptlet(pkg);
392 static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
394 const alpm_list_t *i;
395 pkg->handle->pm_errno = 0;
397 for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
398 alpm_pkg_t *cachepkg = i->data;
399 alpm_list_t *j;
400 for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
401 if(_alpm_depcmp(pkg, j->data)) {
402 const char *cachepkgname = cachepkg->name;
403 if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
404 *reqs = alpm_list_add(*reqs, strdup(cachepkgname));
411 /** Compute the packages requiring a given package. */
412 alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
414 const alpm_list_t *i;
415 alpm_list_t *reqs = NULL;
416 alpm_db_t *db;
418 ASSERT(pkg != NULL, return NULL);
419 pkg->handle->pm_errno = 0;
421 if(pkg->origin == PKG_FROM_FILE) {
422 /* The sane option; search locally for things that require this. */
423 find_requiredby(pkg, pkg->handle->db_local, &reqs);
424 } else {
425 /* We have a DB package. if it is a local package, then we should
426 * only search the local DB; else search all known sync databases. */
427 db = pkg->origin_data.db;
428 if(db->status & DB_STATUS_LOCAL) {
429 find_requiredby(pkg, db, &reqs);
430 } else {
431 for(i = pkg->handle->dbs_sync; i; i = i->next) {
432 db = i->data;
433 find_requiredby(pkg, db, &reqs);
435 reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);
438 return reqs;
441 /** @} */
443 alpm_file_t *_alpm_file_copy(alpm_file_t *dest,
444 const alpm_file_t *src)
446 STRDUP(dest->name, src->name, return NULL);
447 dest->size = src->size;
448 dest->mode = src->mode;
450 return dest;
453 /* Helper function for comparing files list entries
455 int _alpm_files_cmp(const void *f1, const void *f2)
457 const alpm_file_t *file1 = f1;
458 const alpm_file_t *file2 = f2;
459 return strcmp(file1->name, file2->name);
462 alpm_pkg_t *_alpm_pkg_new(void)
464 alpm_pkg_t* pkg;
466 CALLOC(pkg, 1, sizeof(alpm_pkg_t), return NULL);
468 return pkg;
471 static alpm_list_t *list_depdup(alpm_list_t *old)
473 alpm_list_t *i, *new = NULL;
474 for(i = old; i; i = i->next) {
475 new = alpm_list_add(new, _alpm_dep_dup(i->data));
477 return new;
481 * Duplicate a package data struct.
482 * @param pkg the package to duplicate
483 * @param new_ptr location to store duplicated package pointer
484 * @return 0 on success, -1 on fatal error, 1 on non-fatal error
486 int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
488 alpm_pkg_t *newpkg;
489 alpm_list_t *i;
490 int ret = 0;
492 if(!pkg || !pkg->handle) {
493 return -1;
496 if(!new_ptr) {
497 RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1);
500 if(pkg->ops->force_load(pkg)) {
501 _alpm_log(pkg->handle, ALPM_LOG_WARNING,
502 _("could not fully load metadata for package %s-%s\n"),
503 pkg->name, pkg->version);
504 ret = 1;
505 pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID;
508 CALLOC(newpkg, 1, sizeof(alpm_pkg_t), goto cleanup);
510 newpkg->name_hash = pkg->name_hash;
511 STRDUP(newpkg->filename, pkg->filename, goto cleanup);
512 STRDUP(newpkg->name, pkg->name, goto cleanup);
513 STRDUP(newpkg->version, pkg->version, goto cleanup);
514 STRDUP(newpkg->desc, pkg->desc, goto cleanup);
515 STRDUP(newpkg->url, pkg->url, goto cleanup);
516 newpkg->builddate = pkg->builddate;
517 newpkg->installdate = pkg->installdate;
518 STRDUP(newpkg->packager, pkg->packager, goto cleanup);
519 STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup);
520 STRDUP(newpkg->sha256sum, pkg->md5sum, goto cleanup);
521 STRDUP(newpkg->arch, pkg->arch, goto cleanup);
522 newpkg->size = pkg->size;
523 newpkg->isize = pkg->isize;
524 newpkg->scriptlet = pkg->scriptlet;
525 newpkg->reason = pkg->reason;
527 newpkg->licenses = alpm_list_strdup(pkg->licenses);
528 newpkg->replaces = list_depdup(pkg->replaces);
529 newpkg->groups = alpm_list_strdup(pkg->groups);
530 for(i = pkg->backup; i; i = i->next) {
531 newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data));
533 newpkg->depends = list_depdup(pkg->depends);
534 newpkg->optdepends = list_depdup(pkg->optdepends);
535 newpkg->conflicts = list_depdup(pkg->conflicts);
536 newpkg->provides = list_depdup(pkg->provides);
537 for(i = pkg->deltas; i; i = i->next) {
538 newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data));
541 if(pkg->files.count) {
542 size_t filenum;
543 size_t len = sizeof(alpm_file_t) * pkg->files.count;
544 MALLOC(newpkg->files.files, len, goto cleanup);
545 for(filenum = 0; filenum < pkg->files.count; filenum++) {
546 if(!_alpm_file_copy(newpkg->files.files + filenum,
547 pkg->files.files + filenum)) {
548 goto cleanup;
551 newpkg->files.count = pkg->files.count;
554 /* internal */
555 newpkg->infolevel = pkg->infolevel;
556 newpkg->origin = pkg->origin;
557 if(newpkg->origin == PKG_FROM_FILE) {
558 newpkg->origin_data.file = strdup(pkg->origin_data.file);
559 } else {
560 newpkg->origin_data.db = pkg->origin_data.db;
562 newpkg->ops = pkg->ops;
563 newpkg->handle = pkg->handle;
565 *new_ptr = newpkg;
566 return ret;
568 cleanup:
569 _alpm_pkg_free(newpkg);
570 RET_ERR(pkg->handle, ALPM_ERR_MEMORY, -1);
573 static void free_deplist(alpm_list_t *deps)
575 alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_dep_free);
576 alpm_list_free(deps);
579 void _alpm_pkg_free(alpm_pkg_t *pkg)
581 if(pkg == NULL) {
582 return;
585 FREE(pkg->filename);
586 FREE(pkg->name);
587 FREE(pkg->version);
588 FREE(pkg->desc);
589 FREE(pkg->url);
590 FREE(pkg->packager);
591 FREE(pkg->md5sum);
592 FREE(pkg->sha256sum);
593 FREE(pkg->base64_sig);
594 FREE(pkg->arch);
596 FREELIST(pkg->licenses);
597 free_deplist(pkg->replaces);
598 FREELIST(pkg->groups);
599 if(pkg->files.count) {
600 size_t i;
601 for(i = 0; i < pkg->files.count; i++) {
602 free(pkg->files.files[i].name);
604 free(pkg->files.files);
606 alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free);
607 alpm_list_free(pkg->backup);
608 free_deplist(pkg->depends);
609 free_deplist(pkg->optdepends);
610 free_deplist(pkg->conflicts);
611 free_deplist(pkg->provides);
612 alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
613 alpm_list_free(pkg->deltas);
614 alpm_list_free(pkg->delta_path);
615 alpm_list_free(pkg->removes);
617 if(pkg->origin == PKG_FROM_FILE) {
618 FREE(pkg->origin_data.file);
620 FREE(pkg);
623 /* This function should be used when removing a target from upgrade/sync target list
624 * Case 1: If pkg is a loaded package file (PKG_FROM_FILE), it will be freed.
625 * Case 2: If pkg is a pkgcache entry (PKG_FROM_CACHE), it won't be freed,
626 * only the transaction specific fields of pkg will be freed.
628 void _alpm_pkg_free_trans(alpm_pkg_t *pkg)
630 if(pkg == NULL) {
631 return;
634 if(pkg->origin == PKG_FROM_FILE) {
635 _alpm_pkg_free(pkg);
636 return;
639 alpm_list_free(pkg->removes);
640 pkg->removes = NULL;
643 /* Is spkg an upgrade for localpkg? */
644 int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg)
646 return alpm_pkg_vercmp(spkg->version, localpkg->version);
649 /* Helper function for comparing packages
651 int _alpm_pkg_cmp(const void *p1, const void *p2)
653 const alpm_pkg_t *pkg1 = p1;
654 const alpm_pkg_t *pkg2 = p2;
655 return strcmp(pkg1->name, pkg2->name);
658 /* Test for existence of a package in a alpm_list_t*
659 * of alpm_pkg_t*
661 alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)
663 alpm_list_t *lp;
664 unsigned long needle_hash;
666 if(needle == NULL || haystack == NULL) {
667 return NULL;
670 needle_hash = _alpm_hash_sdbm(needle);
672 for(lp = haystack; lp; lp = lp->next) {
673 alpm_pkg_t *info = lp->data;
675 if(info) {
676 if(info->name_hash != needle_hash) {
677 continue;
680 /* finally: we had hash match, verify string match */
681 if(strcmp(info->name, needle) == 0) {
682 return info;
686 return NULL;
689 /** Test if a package should be ignored.
691 * Checks if the package is ignored via IgnorePkg, or if the package is
692 * in a group ignored via IgnoreGroup.
694 * @param handle the context handle
695 * @param pkg the package to test
697 * @return 1 if the package should be ignored, 0 otherwise
699 int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg)
701 alpm_list_t *groups = NULL;
703 /* first see if the package is ignored */
704 if(alpm_list_find(handle->ignorepkg, pkg->name, _alpm_fnmatch)) {
705 return 1;
708 /* next see if the package is in a group that is ignored */
709 for(groups = alpm_pkg_get_groups(pkg); groups; groups = groups->next) {
710 char *grp = groups->data;
711 if(alpm_list_find(handle->ignoregroup, grp, _alpm_fnmatch)) {
712 return 1;
716 return 0;
719 /* vim: set ts=2 sw=2 noet: */