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/>.
26 #include <sys/types.h>
30 #include "alpm_list.h"
38 /** \addtogroup alpm_packages Package Functions
39 * @brief Functions to manipulate libalpm packages
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
) {
56 /** Check the integrity (with md5) of a package from the sync cache. */
57 int SYMEXPORT
alpm_pkg_checkmd5sum(alpm_pkg_t
*pkg
)
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
);
74 } else if(retval
== 1) {
75 pkg
->handle
->pm_errno
= ALPM_ERR_PKG_INVALID
;
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
)
112 static size_t _pkg_changelog_read(void UNUSED
*ptr
, size_t UNUSED size
,
113 const alpm_pkg_t UNUSED
*pkg
, UNUSED
void *fp
)
118 static int _pkg_changelog_close(const alpm_pkg_t UNUSED
*pkg
,
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;
175 const char SYMEXPORT
*alpm_pkg_get_version(alpm_pkg_t
*pkg
)
177 ASSERT(pkg
!= NULL
, return NULL
);
178 pkg
->handle
->pm_errno
= 0;
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;
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;
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;
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;
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
)
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
;
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
;
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
);
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
);
431 for(i
= pkg
->handle
->dbs_sync
; i
; i
= i
->next
) {
433 find_requiredby(pkg
, db
, &reqs
);
435 reqs
= alpm_list_msort(reqs
, alpm_list_count(reqs
), _alpm_str_cmp
);
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
;
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)
466 CALLOC(pkg
, 1, sizeof(alpm_pkg_t
), return NULL
);
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
));
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
)
492 if(!pkg
|| !pkg
->handle
) {
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
);
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
) {
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
)) {
551 newpkg
->files
.count
= pkg
->files
.count
;
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
);
560 newpkg
->origin_data
.db
= pkg
->origin_data
.db
;
562 newpkg
->ops
= pkg
->ops
;
563 newpkg
->handle
= pkg
->handle
;
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
)
592 FREE(pkg
->sha256sum
);
593 FREE(pkg
->base64_sig
);
596 FREELIST(pkg
->licenses
);
597 free_deplist(pkg
->replaces
);
598 FREELIST(pkg
->groups
);
599 if(pkg
->files
.count
) {
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
);
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
)
634 if(pkg
->origin
== PKG_FROM_FILE
) {
639 alpm_list_free(pkg
->removes
);
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*
661 alpm_pkg_t
*_alpm_pkg_find(alpm_list_t
*haystack
, const char *needle
)
664 unsigned long needle_hash
;
666 if(needle
== NULL
|| haystack
== NULL
) {
670 needle_hash
= _alpm_hash_sdbm(needle
);
672 for(lp
= haystack
; lp
; lp
= lp
->next
) {
673 alpm_pkg_t
*info
= lp
->data
;
676 if(info
->name_hash
!= needle_hash
) {
680 /* finally: we had hash match, verify string match */
681 if(strcmp(info
->name
, needle
) == 0) {
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
)) {
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
)) {
719 /* vim: set ts=2 sw=2 noet: */