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/>.
28 #include <sys/types.h>
32 #include "alpm_list.h"
40 /** \addtogroup alpm_packages Package Functions
41 * @brief Functions to manipulate libalpm packages
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
) {
58 /** Check the integrity (with md5) of a package from the sync cache. */
59 int SYMEXPORT
alpm_pkg_checkmd5sum(alpm_pkg_t
*pkg
)
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
);
76 } else if(retval
== 1) {
77 pkg
->handle
->pm_errno
= ALPM_ERR_PKG_INVALID
;
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
)
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
)
122 static int _pkg_changelog_close(const alpm_pkg_t UNUSED
*pkg
,
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;
181 const char SYMEXPORT
*alpm_pkg_get_version(alpm_pkg_t
*pkg
)
183 ASSERT(pkg
!= NULL
, return NULL
);
184 pkg
->handle
->pm_errno
= 0;
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;
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
)
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
;
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
;
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
);
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
);
430 for(i
= pkg
->handle
->dbs_sync
; i
; i
= i
->next
) {
432 find_requiredby(pkg
, db
, &reqs
);
434 reqs
= alpm_list_msort(reqs
, alpm_list_count(reqs
), _alpm_str_cmp
);
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
;
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)
465 CALLOC(pkg
, 1, sizeof(alpm_pkg_t
), return NULL
);
470 alpm_pkg_t
*_alpm_pkg_dup(alpm_pkg_t
*pkg
)
475 if(pkg
->ops
->force_load(pkg
)) {
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
) {
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
)) {
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
));
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
);
538 newpkg
->origin_data
.db
= pkg
->origin_data
.db
;
540 newpkg
->ops
= pkg
->ops
;
541 newpkg
->handle
= pkg
->handle
;
546 _alpm_pkg_free(newpkg
);
550 void _alpm_pkg_free(alpm_pkg_t
*pkg
)
563 FREE(pkg
->sha256sum
);
564 FREE(pkg
->base64_sig
);
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
) {
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
);
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
)
609 if(pkg
->origin
== PKG_FROM_FILE
) {
614 alpm_list_free(pkg
->removes
);
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*
636 alpm_pkg_t
*_alpm_pkg_find(alpm_list_t
*haystack
, const char *needle
)
639 unsigned long needle_hash
;
641 if(needle
== NULL
|| haystack
== NULL
) {
645 needle_hash
= _alpm_hash_sdbm(needle
);
647 for(lp
= haystack
; lp
; lp
= lp
->next
) {
648 alpm_pkg_t
*info
= lp
->data
;
651 if(info
->name_hash
!= needle_hash
) {
655 /* finally: we had hash match, verify string match */
656 if(strcmp(info
->name
, needle
) == 0) {
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
)) {
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
)) {
694 /* vim: set ts=2 sw=2 noet: */