Remove usages of alpm_list_next() in backend
[pacman-ng.git] / lib / libalpm / package.c
blobd865ac95b97219464feee9b6a94f02b30b36606e
1 /*
2 * package.c
4 * Copyright (c) 2006-2011 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 "config.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
30 /* libalpm */
31 #include "package.h"
32 #include "alpm_list.h"
33 #include "log.h"
34 #include "util.h"
35 #include "db.h"
36 #include "delta.h"
37 #include "handle.h"
38 #include "deps.h"
40 /** \addtogroup alpm_packages Package Functions
41 * @brief Functions to manipulate libalpm packages
42 * @{
45 /** Free a package. */
46 int SYMEXPORT alpm_pkg_free(alpm_pkg_t *pkg)
48 ASSERT(pkg != NULL, return -1);
50 /* Only free packages loaded in user space */
51 if(pkg->origin == PKG_FROM_FILE) {
52 _alpm_pkg_free(pkg);
55 return 0;
58 /** Check the integrity (with md5) of a package from the sync cache. */
59 int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
61 char *fpath;
62 int retval;
64 ASSERT(pkg != NULL, return -1);
65 pkg->handle->pm_errno = 0;
66 /* We only inspect packages from sync repositories */
67 ASSERT(pkg->origin == PKG_FROM_SYNCDB,
68 RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
70 fpath = _alpm_filecache_find(pkg->handle, alpm_pkg_get_filename(pkg));
72 retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_CSUM_MD5);
74 if(retval == 0) {
75 return 0;
76 } else if(retval == 1) {
77 pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID;
78 retval = -1;
81 return retval;
84 /* Default package accessor functions. These will get overridden by any
85 * backend logic that needs lazy access, such as the local database through
86 * a lazy-load cache. However, the defaults will work just fine for fully-
87 * populated package structures. */
88 static const char *_pkg_get_filename(alpm_pkg_t *pkg) { return pkg->filename; }
89 static const char *_pkg_get_desc(alpm_pkg_t *pkg) { return pkg->desc; }
90 static const char *_pkg_get_url(alpm_pkg_t *pkg) { return pkg->url; }
91 static time_t _pkg_get_builddate(alpm_pkg_t *pkg) { return pkg->builddate; }
92 static time_t _pkg_get_installdate(alpm_pkg_t *pkg) { return pkg->installdate; }
93 static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; }
94 static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; }
95 static off_t _pkg_get_size(alpm_pkg_t *pkg) { return pkg->size; }
96 static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; }
97 static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; }
98 static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; }
100 static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; }
101 static alpm_list_t *_pkg_get_groups(alpm_pkg_t *pkg) { return pkg->groups; }
102 static alpm_list_t *_pkg_get_depends(alpm_pkg_t *pkg) { return pkg->depends; }
103 static alpm_list_t *_pkg_get_optdepends(alpm_pkg_t *pkg) { return pkg->optdepends; }
104 static alpm_list_t *_pkg_get_conflicts(alpm_pkg_t *pkg) { return pkg->conflicts; }
105 static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides; }
106 static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; }
107 static alpm_list_t *_pkg_get_deltas(alpm_pkg_t *pkg) { return pkg->deltas; }
108 static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
109 static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
111 static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
113 return NULL;
116 static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size,
117 const alpm_pkg_t UNUSED *pkg, const UNUSED void *fp)
119 return 0;
122 static int _pkg_changelog_close(const alpm_pkg_t UNUSED *pkg,
123 void UNUSED *fp)
125 return EOF;
128 static int _pkg_force_load(alpm_pkg_t UNUSED *pkg) { return 0; }
130 /** The standard package operations struct. Get fields directly from the
131 * struct itself with no abstraction layer or any type of lazy loading.
133 struct pkg_operations default_pkg_ops = {
134 .get_filename = _pkg_get_filename,
135 .get_desc = _pkg_get_desc,
136 .get_url = _pkg_get_url,
137 .get_builddate = _pkg_get_builddate,
138 .get_installdate = _pkg_get_installdate,
139 .get_packager = _pkg_get_packager,
140 .get_arch = _pkg_get_arch,
141 .get_size = _pkg_get_size,
142 .get_isize = _pkg_get_isize,
143 .get_reason = _pkg_get_reason,
144 .has_scriptlet = _pkg_has_scriptlet,
146 .get_licenses = _pkg_get_licenses,
147 .get_groups = _pkg_get_groups,
148 .get_depends = _pkg_get_depends,
149 .get_optdepends = _pkg_get_optdepends,
150 .get_conflicts = _pkg_get_conflicts,
151 .get_provides = _pkg_get_provides,
152 .get_replaces = _pkg_get_replaces,
153 .get_deltas = _pkg_get_deltas,
154 .get_files = _pkg_get_files,
155 .get_backup = _pkg_get_backup,
157 .changelog_open = _pkg_changelog_open,
158 .changelog_read = _pkg_changelog_read,
159 .changelog_close = _pkg_changelog_close,
161 .force_load = _pkg_force_load,
164 /* Public functions for getting package information. These functions
165 * delegate the hard work to the function callbacks attached to each
166 * package, which depend on where the package was loaded from. */
167 const char SYMEXPORT *alpm_pkg_get_filename(alpm_pkg_t *pkg)
169 ASSERT(pkg != NULL, return NULL);
170 pkg->handle->pm_errno = 0;
171 return pkg->ops->get_filename(pkg);
174 const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg)
176 ASSERT(pkg != NULL, return NULL);
177 pkg->handle->pm_errno = 0;
178 return pkg->name;
181 const char SYMEXPORT *alpm_pkg_get_version(alpm_pkg_t *pkg)
183 ASSERT(pkg != NULL, return NULL);
184 pkg->handle->pm_errno = 0;
185 return pkg->version;
188 const char SYMEXPORT *alpm_pkg_get_desc(alpm_pkg_t *pkg)
190 ASSERT(pkg != NULL, return NULL);
191 pkg->handle->pm_errno = 0;
192 return pkg->ops->get_desc(pkg);
195 const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg)
197 ASSERT(pkg != NULL, return NULL);
198 pkg->handle->pm_errno = 0;
199 return pkg->ops->get_url(pkg);
202 time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg)
204 ASSERT(pkg != NULL, return -1);
205 pkg->handle->pm_errno = 0;
206 return pkg->ops->get_builddate(pkg);
209 time_t SYMEXPORT alpm_pkg_get_installdate(alpm_pkg_t *pkg)
211 ASSERT(pkg != NULL, return -1);
212 pkg->handle->pm_errno = 0;
213 return pkg->ops->get_installdate(pkg);
216 const char SYMEXPORT *alpm_pkg_get_packager(alpm_pkg_t *pkg)
218 ASSERT(pkg != NULL, return NULL);
219 pkg->handle->pm_errno = 0;
220 return pkg->ops->get_packager(pkg);
223 const char SYMEXPORT *alpm_pkg_get_md5sum(alpm_pkg_t *pkg)
225 ASSERT(pkg != NULL, return NULL);
226 pkg->handle->pm_errno = 0;
227 return pkg->md5sum;
230 const char SYMEXPORT *alpm_pkg_get_sha256sum(alpm_pkg_t *pkg)
232 ASSERT(pkg != NULL, return NULL);
233 pkg->handle->pm_errno = 0;
234 return pkg->sha256sum;
237 const char SYMEXPORT *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg)
239 ASSERT(pkg != NULL, return NULL);
240 pkg->handle->pm_errno = 0;
241 return pkg->base64_sig;
244 const char SYMEXPORT *alpm_pkg_get_arch(alpm_pkg_t *pkg)
246 ASSERT(pkg != NULL, return NULL);
247 pkg->handle->pm_errno = 0;
248 return pkg->ops->get_arch(pkg);
251 off_t SYMEXPORT alpm_pkg_get_size(alpm_pkg_t *pkg)
253 ASSERT(pkg != NULL, return -1);
254 pkg->handle->pm_errno = 0;
255 return pkg->ops->get_size(pkg);
258 off_t SYMEXPORT alpm_pkg_get_isize(alpm_pkg_t *pkg)
260 ASSERT(pkg != NULL, return -1);
261 pkg->handle->pm_errno = 0;
262 return pkg->ops->get_isize(pkg);
265 alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg)
267 ASSERT(pkg != NULL, return -1);
268 pkg->handle->pm_errno = 0;
269 return pkg->ops->get_reason(pkg);
272 alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg)
274 ASSERT(pkg != NULL, return NULL);
275 pkg->handle->pm_errno = 0;
276 return pkg->ops->get_licenses(pkg);
279 alpm_list_t SYMEXPORT *alpm_pkg_get_groups(alpm_pkg_t *pkg)
281 ASSERT(pkg != NULL, return NULL);
282 pkg->handle->pm_errno = 0;
283 return pkg->ops->get_groups(pkg);
286 alpm_list_t SYMEXPORT *alpm_pkg_get_depends(alpm_pkg_t *pkg)
288 ASSERT(pkg != NULL, return NULL);
289 pkg->handle->pm_errno = 0;
290 return pkg->ops->get_depends(pkg);
293 alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(alpm_pkg_t *pkg)
295 ASSERT(pkg != NULL, return NULL);
296 pkg->handle->pm_errno = 0;
297 return pkg->ops->get_optdepends(pkg);
300 alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(alpm_pkg_t *pkg)
302 ASSERT(pkg != NULL, return NULL);
303 pkg->handle->pm_errno = 0;
304 return pkg->ops->get_conflicts(pkg);
307 alpm_list_t SYMEXPORT *alpm_pkg_get_provides(alpm_pkg_t *pkg)
309 ASSERT(pkg != NULL, return NULL);
310 pkg->handle->pm_errno = 0;
311 return pkg->ops->get_provides(pkg);
314 alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg)
316 ASSERT(pkg != NULL, return NULL);
317 pkg->handle->pm_errno = 0;
318 return pkg->ops->get_replaces(pkg);
321 alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg)
323 ASSERT(pkg != NULL, return NULL);
324 pkg->handle->pm_errno = 0;
325 return pkg->ops->get_deltas(pkg);
328 alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg)
330 ASSERT(pkg != NULL, return NULL);
331 pkg->handle->pm_errno = 0;
332 return pkg->ops->get_files(pkg);
335 alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg)
337 ASSERT(pkg != NULL, return NULL);
338 pkg->handle->pm_errno = 0;
339 return pkg->ops->get_backup(pkg);
342 alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg)
344 /* Sanity checks */
345 ASSERT(pkg != NULL, return NULL);
346 ASSERT(pkg->origin != PKG_FROM_FILE, return NULL);
347 pkg->handle->pm_errno = 0;
349 return pkg->origin_data.db;
352 /** Open a package changelog for reading. */
353 void SYMEXPORT *alpm_pkg_changelog_open(alpm_pkg_t *pkg)
355 ASSERT(pkg != NULL, return NULL);
356 pkg->handle->pm_errno = 0;
357 return pkg->ops->changelog_open(pkg);
360 /** Read data from an open changelog 'file stream'. */
361 size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,
362 const alpm_pkg_t *pkg, const void *fp)
364 ASSERT(pkg != NULL, return 0);
365 pkg->handle->pm_errno = 0;
366 return pkg->ops->changelog_read(ptr, size, pkg, fp);
370 int SYMEXPORT alpm_pkg_changelog_feof(const alpm_pkg_t *pkg, void *fp)
372 return pkg->ops->changelog_feof(pkg, fp);
376 /** Close a package changelog for reading. */
377 int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp)
379 ASSERT(pkg != NULL, return -1);
380 pkg->handle->pm_errno = 0;
381 return pkg->ops->changelog_close(pkg, fp);
384 int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg)
386 ASSERT(pkg != NULL, return -1);
387 pkg->handle->pm_errno = 0;
388 return pkg->ops->has_scriptlet(pkg);
391 static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
393 const alpm_list_t *i;
394 pkg->handle->pm_errno = 0;
396 for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
397 alpm_pkg_t *cachepkg = i->data;
398 alpm_list_t *j;
399 for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
400 if(_alpm_depcmp(pkg, j->data)) {
401 const char *cachepkgname = cachepkg->name;
402 if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
403 *reqs = alpm_list_add(*reqs, strdup(cachepkgname));
410 /** Compute the packages requiring a given package. */
411 alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
413 const alpm_list_t *i;
414 alpm_list_t *reqs = NULL;
415 alpm_db_t *db;
417 ASSERT(pkg != NULL, return NULL);
418 pkg->handle->pm_errno = 0;
420 if(pkg->origin == PKG_FROM_FILE) {
421 /* The sane option; search locally for things that require this. */
422 find_requiredby(pkg, pkg->handle->db_local, &reqs);
423 } else {
424 /* We have a DB package. if it is a local package, then we should
425 * only search the local DB; else search all known sync databases. */
426 db = pkg->origin_data.db;
427 if(db->status & DB_STATUS_LOCAL) {
428 find_requiredby(pkg, db, &reqs);
429 } else {
430 for(i = pkg->handle->dbs_sync; i; i = i->next) {
431 db = i->data;
432 find_requiredby(pkg, db, &reqs);
434 reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);
437 return reqs;
440 /** @} */
442 alpm_file_t *_alpm_file_copy(alpm_file_t *dest,
443 const alpm_file_t *src)
445 STRDUP(dest->name, src->name, return NULL);
446 dest->size = src->size;
447 dest->mode = src->mode;
449 return dest;
452 /* Helper function for comparing files list entries
454 int _alpm_files_cmp(const void *f1, const void *f2)
456 const alpm_file_t *file1 = f1;
457 const alpm_file_t *file2 = f2;
458 return strcmp(file1->name, file2->name);
461 alpm_pkg_t *_alpm_pkg_new(void)
463 alpm_pkg_t* pkg;
465 CALLOC(pkg, 1, sizeof(alpm_pkg_t), return NULL);
467 return pkg;
470 alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg)
472 alpm_pkg_t *newpkg;
473 alpm_list_t *i;
475 if(pkg->ops->force_load(pkg)) {
476 return NULL;
479 CALLOC(newpkg, 1, sizeof(alpm_pkg_t), goto cleanup);
481 newpkg->name_hash = pkg->name_hash;
482 STRDUP(newpkg->filename, pkg->filename, goto cleanup);
483 STRDUP(newpkg->name, pkg->name, goto cleanup);
484 STRDUP(newpkg->version, pkg->version, goto cleanup);
485 STRDUP(newpkg->desc, pkg->desc, goto cleanup);
486 STRDUP(newpkg->url, pkg->url, goto cleanup);
487 newpkg->builddate = pkg->builddate;
488 newpkg->installdate = pkg->installdate;
489 STRDUP(newpkg->packager, pkg->packager, goto cleanup);
490 STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup);
491 STRDUP(newpkg->sha256sum, pkg->md5sum, goto cleanup);
492 STRDUP(newpkg->arch, pkg->arch, goto cleanup);
493 newpkg->size = pkg->size;
494 newpkg->isize = pkg->isize;
495 newpkg->scriptlet = pkg->scriptlet;
496 newpkg->reason = pkg->reason;
498 newpkg->licenses = alpm_list_strdup(pkg->licenses);
499 for(i = pkg->replaces; i; i = i->next) {
500 newpkg->replaces = alpm_list_add(newpkg->replaces, _alpm_dep_dup(i->data));
502 newpkg->groups = alpm_list_strdup(pkg->groups);
503 if(pkg->files.count) {
504 size_t filenum;
505 size_t len = sizeof(alpm_file_t) * pkg->files.count;
506 MALLOC(newpkg->files.files, len, goto cleanup);
507 for(filenum = 0; filenum < pkg->files.count; filenum++) {
508 if(!_alpm_file_copy(newpkg->files.files + filenum,
509 pkg->files.files + filenum)) {
510 goto cleanup;
513 newpkg->files.count = pkg->files.count;
515 for(i = pkg->backup; i; i = i->next) {
516 newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data));
518 for(i = pkg->depends; i; i = i->next) {
519 newpkg->depends = alpm_list_add(newpkg->depends, _alpm_dep_dup(i->data));
521 newpkg->optdepends = alpm_list_strdup(pkg->optdepends);
522 for(i = pkg->conflicts; i; i = i->next) {
523 newpkg->conflicts = alpm_list_add(newpkg->conflicts, _alpm_dep_dup(i->data));
525 for(i = pkg->provides; i; i = i->next) {
526 newpkg->provides = alpm_list_add(newpkg->provides, _alpm_dep_dup(i->data));
528 for(i = pkg->deltas; i; i = i->next) {
529 newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data));
532 /* internal */
533 newpkg->infolevel = pkg->infolevel;
534 newpkg->origin = pkg->origin;
535 if(newpkg->origin == PKG_FROM_FILE) {
536 newpkg->origin_data.file = strdup(pkg->origin_data.file);
537 } else {
538 newpkg->origin_data.db = pkg->origin_data.db;
540 newpkg->ops = pkg->ops;
541 newpkg->handle = pkg->handle;
543 return newpkg;
545 cleanup:
546 _alpm_pkg_free(newpkg);
547 return NULL;
550 void _alpm_pkg_free(alpm_pkg_t *pkg)
552 if(pkg == NULL) {
553 return;
556 FREE(pkg->filename);
557 FREE(pkg->name);
558 FREE(pkg->version);
559 FREE(pkg->desc);
560 FREE(pkg->url);
561 FREE(pkg->packager);
562 FREE(pkg->md5sum);
563 FREE(pkg->sha256sum);
564 FREE(pkg->base64_sig);
565 FREE(pkg->arch);
567 FREELIST(pkg->licenses);
568 alpm_list_free_inner(pkg->replaces, (alpm_list_fn_free)_alpm_dep_free);
569 alpm_list_free(pkg->replaces);
570 FREELIST(pkg->groups);
571 if(pkg->files.count) {
572 size_t i;
573 for(i = 0; i < pkg->files.count; i++) {
574 free(pkg->files.files[i].name);
576 free(pkg->files.files);
578 alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free);
579 alpm_list_free(pkg->backup);
580 alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
581 alpm_list_free(pkg->depends);
582 FREELIST(pkg->optdepends);
583 alpm_list_free_inner(pkg->conflicts, (alpm_list_fn_free)_alpm_dep_free);
584 alpm_list_free(pkg->conflicts);
585 alpm_list_free_inner(pkg->provides, (alpm_list_fn_free)_alpm_dep_free);
586 alpm_list_free(pkg->provides);
587 alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
588 alpm_list_free(pkg->deltas);
589 alpm_list_free(pkg->delta_path);
590 alpm_list_free(pkg->removes);
592 if(pkg->origin == PKG_FROM_FILE) {
593 FREE(pkg->origin_data.file);
595 FREE(pkg);
598 /* This function should be used when removing a target from upgrade/sync target list
599 * Case 1: If pkg is a loaded package file (PKG_FROM_FILE), it will be freed.
600 * Case 2: If pkg is a pkgcache entry (PKG_FROM_CACHE), it won't be freed,
601 * only the transaction specific fields of pkg will be freed.
603 void _alpm_pkg_free_trans(alpm_pkg_t *pkg)
605 if(pkg == NULL) {
606 return;
609 if(pkg->origin == PKG_FROM_FILE) {
610 _alpm_pkg_free(pkg);
611 return;
614 alpm_list_free(pkg->removes);
615 pkg->removes = NULL;
618 /* Is spkg an upgrade for localpkg? */
619 int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg)
621 return alpm_pkg_vercmp(spkg->version, localpkg->version);
624 /* Helper function for comparing packages
626 int _alpm_pkg_cmp(const void *p1, const void *p2)
628 const alpm_pkg_t *pkg1 = p1;
629 const alpm_pkg_t *pkg2 = p2;
630 return strcoll(pkg1->name, pkg2->name);
633 /* Test for existence of a package in a alpm_list_t*
634 * of alpm_pkg_t*
636 alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)
638 alpm_list_t *lp;
639 unsigned long needle_hash;
641 if(needle == NULL || haystack == NULL) {
642 return NULL;
645 needle_hash = _alpm_hash_sdbm(needle);
647 for(lp = haystack; lp; lp = lp->next) {
648 alpm_pkg_t *info = lp->data;
650 if(info) {
651 if(info->name_hash != needle_hash) {
652 continue;
655 /* finally: we had hash match, verify string match */
656 if(strcmp(info->name, needle) == 0) {
657 return info;
661 return NULL;
664 /** Test if a package should be ignored.
666 * Checks if the package is ignored via IgnorePkg, or if the package is
667 * in a group ignored via IgnoreGroup.
669 * @param handle the context handle
670 * @param pkg the package to test
672 * @return 1 if the package should be ignored, 0 otherwise
674 int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg)
676 alpm_list_t *groups = NULL;
678 /* first see if the package is ignored */
679 if(alpm_list_find_str(handle->ignorepkg, pkg->name)) {
680 return 1;
683 /* next see if the package is in a group that is ignored */
684 for(groups = handle->ignoregroup; groups; groups = groups->next) {
685 char *grp = (char *)alpm_list_getdata(groups);
686 if(alpm_list_find_str(alpm_pkg_get_groups(pkg), grp)) {
687 return 1;
691 return 0;
694 /* vim: set ts=2 sw=2 noet: */