A few final changes for the 3.0.6 release
[pacman.git] / lib / libalpm / package.c
blob74adf5cd4b3579ca88d46e5f96c264d3ab728111
1 /*
2 * package.c
4 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
5 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
6 * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu>
7 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 * USA.
25 #include "config.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <string.h>
31 #include <libintl.h>
32 #include <locale.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
38 /* libalpm */
39 #include "package.h"
40 #include "alpm_list.h"
41 #include "log.h"
42 #include "util.h"
43 #include "error.h"
44 #include "db.h"
45 #include "cache.h"
46 #include "provide.h"
47 #include "handle.h"
48 #include "versioncmp.h"
49 #include "alpm.h"
51 pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
53 pmpkg_t* pkg;
55 ALPM_LOG_FUNC;
57 if((pkg = calloc(1,sizeof(pmpkg_t))) == NULL) {
58 RET_ERR(PM_ERR_MEMORY, NULL);
61 if(name && name[0] != 0) {
62 STRNCPY(pkg->name, name, PKG_NAME_LEN);
63 } else {
64 pkg->name[0] = '\0';
66 if(version && version[0] != 0) {
67 STRNCPY(pkg->version, version, PKG_VERSION_LEN);
68 } else {
69 pkg->version[0] = '\0';
72 return(pkg);
75 pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
77 pmpkg_t* newpkg;
79 ALPM_LOG_FUNC;
81 if((newpkg = calloc(1, sizeof(pmpkg_t))) == NULL) {
82 _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmpkg_t));
83 RET_ERR(PM_ERR_MEMORY, NULL);
86 memcpy(newpkg, pkg, sizeof(pmpkg_t));
87 newpkg->licenses = alpm_list_strdup(alpm_pkg_get_licenses(pkg));
88 /*newpkg->desc_localized = alpm_list_strdup(pkg->desc_localized);*/
89 newpkg->requiredby = alpm_list_strdup(alpm_pkg_get_requiredby(pkg));
90 newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
91 newpkg->files = alpm_list_strdup(alpm_pkg_get_files(pkg));
92 newpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(pkg));
93 newpkg->depends = alpm_list_strdup(alpm_pkg_get_depends(pkg));
94 newpkg->removes = alpm_list_strdup(alpm_pkg_get_removes(pkg));
95 newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
96 newpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(pkg));
97 newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
98 /* internal */
99 newpkg->data = (newpkg->origin == PKG_FROM_FILE) ? strdup(pkg->data) : pkg->data;
101 return(newpkg);
104 void _alpm_pkg_free(void *data)
106 pmpkg_t *pkg = data;
108 ALPM_LOG_FUNC;
110 if(pkg == NULL) {
111 return;
114 FREELIST(pkg->licenses);
115 /*FREELIST(pkg->desc_localized);*/
116 FREELIST(pkg->files);
117 FREELIST(pkg->backup);
118 FREELIST(pkg->depends);
119 FREELIST(pkg->removes);
120 FREELIST(pkg->conflicts);
121 FREELIST(pkg->requiredby);
122 FREELIST(pkg->groups);
123 FREELIST(pkg->provides);
124 FREELIST(pkg->replaces);
125 if(pkg->origin == PKG_FROM_FILE) {
126 FREE(pkg->data);
128 FREE(pkg);
130 return;
133 /* Is pkgB an upgrade for pkgA ? */
134 int alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg)
136 int cmp = 0;
138 ALPM_LOG_FUNC;
140 if(pkg->origin == PKG_FROM_CACHE) {
141 /* ensure we have the /desc file, which contains the 'force' option */
142 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
145 if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(pkg))) {
146 /* package should be ignored (IgnorePkg) */
147 _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (%s)"),
148 alpm_pkg_get_name(local_pkg), alpm_pkg_get_version(local_pkg),
149 alpm_pkg_get_version(pkg));
150 return(0);
153 /* compare versions and see if we need to upgrade */
154 cmp = _alpm_versioncmp(alpm_pkg_get_version(pkg), alpm_pkg_get_version(local_pkg));
156 if(cmp != 0 && pkg->force) {
157 cmp = 1;
158 _alpm_log(PM_LOG_WARNING, _("%s: forcing upgrade to version %s"),
159 alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
160 } else if(cmp < 0) {
161 /* local version is newer */
162 pmdb_t *db = pkg->data;
163 _alpm_log(PM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)"),
164 alpm_pkg_get_name(local_pkg), alpm_pkg_get_version(local_pkg),
165 alpm_db_get_name(db), alpm_pkg_get_version(pkg));
166 cmp = 0;
167 } else if(cmp > 0) {
168 /* we have an upgrade, make sure we should actually do it */
169 if(_alpm_pkg_istoonew(pkg)) {
170 /* package too new (UpgradeDelay) */
171 _alpm_log(PM_LOG_WARNING, _("%s-%s: delaying upgrade of package (%s)"),
172 alpm_pkg_get_name(local_pkg), alpm_pkg_get_version(local_pkg),
173 alpm_pkg_get_version(pkg));
174 cmp = 0;
178 return(cmp);
181 /* Helper function for comparing packages
183 int _alpm_pkg_cmp(const void *p1, const void *p2)
185 pmpkg_t *pk1 = (pmpkg_t *)p1;
186 pmpkg_t *pk2 = (pmpkg_t *)p2;
188 return(strcmp(alpm_pkg_get_name(pk1), alpm_pkg_get_name(pk2)));
191 /* Parses the package description file for the current package
192 * TODO: this should ALL be in a backend interface (be_files), we should
193 * be dealing with the abstracted concepts only in this file
194 * Returns: 0 on success, 1 on error
197 static int parse_descfile(const char *descfile, pmpkg_t *info)
199 FILE* fp = NULL;
200 char line[PATH_MAX];
201 char *ptr = NULL;
202 char *key = NULL;
203 int linenum = 0;
205 ALPM_LOG_FUNC;
207 if((fp = fopen(descfile, "r")) == NULL) {
208 _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), descfile, strerror(errno));
209 return(-1);
212 while(!feof(fp)) {
213 fgets(line, PATH_MAX, fp);
214 linenum++;
215 _alpm_strtrim(line);
216 if(strlen(line) == 0 || line[0] == '#') {
217 continue;
219 ptr = line;
220 key = strsep(&ptr, "=");
221 if(key == NULL || ptr == NULL) {
222 _alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
223 info->name[0] != '\0' ? info->name : "error", linenum);
224 } else {
225 _alpm_strtrim(key);
226 key = _alpm_strtoupper(key);
227 _alpm_strtrim(ptr);
228 if(!strcmp(key, "PKGNAME")) {
229 STRNCPY(info->name, ptr, sizeof(info->name));
230 } else if(!strcmp(key, "PKGVER")) {
231 STRNCPY(info->version, ptr, sizeof(info->version));
232 } else if(!strcmp(key, "PKGDESC")) {
234 char *lang_tmp;
235 info->desc_localized = alpm_list_add(info->desc_localized, strdup(ptr));
236 if((lang_tmp = (char *)malloc(strlen(setlocale(LC_ALL, "")))) == NULL) {
237 RET_ERR(PM_ERR_MEMORY, -1);
239 STRNCPY(lang_tmp, setlocale(LC_ALL, ""), strlen(setlocale(LC_ALL, "")));
240 if(info->desc_localized && !info->desc_localized->next) {
242 STRNCPY(info->desc, ptr, sizeof(info->desc));
244 } else if (ptr && !strncmp(ptr, lang_tmp, strlen(lang_tmp))) {
245 STRNCPY(info->desc, ptr+strlen(lang_tmp)+1, sizeof(info->desc));
247 FREE(lang_tmp);
249 } else if(!strcmp(key, "GROUP")) {
250 info->groups = alpm_list_add(info->groups, strdup(ptr));
251 } else if(!strcmp(key, "URL")) {
252 STRNCPY(info->url, ptr, sizeof(info->url));
253 } else if(!strcmp(key, "LICENSE")) {
254 info->licenses = alpm_list_add(info->licenses, strdup(ptr));
255 } else if(!strcmp(key, "BUILDDATE")) {
256 STRNCPY(info->builddate, ptr, sizeof(info->builddate));
257 } else if(!strcmp(key, "BUILDTYPE")) {
258 STRNCPY(info->buildtype, ptr, sizeof(info->buildtype));
259 } else if(!strcmp(key, "INSTALLDATE")) {
260 STRNCPY(info->installdate, ptr, sizeof(info->installdate));
261 } else if(!strcmp(key, "PACKAGER")) {
262 STRNCPY(info->packager, ptr, sizeof(info->packager));
263 } else if(!strcmp(key, "ARCH")) {
264 STRNCPY(info->arch, ptr, sizeof(info->arch));
265 } else if(!strcmp(key, "SIZE")) {
266 /* size in the raw package is uncompressed (installed) size */
267 info->isize = atol(ptr);
268 } else if(!strcmp(key, "DEPEND")) {
269 info->depends = alpm_list_add(info->depends, strdup(ptr));
270 } else if(!strcmp(key, "REMOVE")) {
271 info->removes = alpm_list_add(info->removes, strdup(ptr));
272 } else if(!strcmp(key, "CONFLICT")) {
273 info->conflicts = alpm_list_add(info->conflicts, strdup(ptr));
274 } else if(!strcmp(key, "REPLACES")) {
275 info->replaces = alpm_list_add(info->replaces, strdup(ptr));
276 } else if(!strcmp(key, "PROVIDES")) {
277 info->provides = alpm_list_add(info->provides, strdup(ptr));
278 } else if(!strcmp(key, "BACKUP")) {
279 info->backup = alpm_list_add(info->backup, strdup(ptr));
280 } else {
281 _alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
282 info->name[0] != '\0' ? info->name : "error", linenum);
285 line[0] = '\0';
287 fclose(fp);
288 unlink(descfile);
290 return(0);
293 pmpkg_t *_alpm_pkg_load(const char *pkgfile)
295 char *expath;
296 int ret = ARCHIVE_OK;
297 int config = 0;
298 int filelist = 0;
299 int scriptcheck = 0;
300 struct archive *archive;
301 struct archive_entry *entry;
302 pmpkg_t *info = NULL;
303 char *descfile = NULL;
304 int fd = -1;
305 alpm_list_t *all_files = NULL;
306 struct stat st;
308 ALPM_LOG_FUNC;
310 if(pkgfile == NULL || strlen(pkgfile) == 0) {
311 RET_ERR(PM_ERR_WRONG_ARGS, NULL);
314 if((archive = archive_read_new()) == NULL) {
315 RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
318 archive_read_support_compression_all(archive);
319 archive_read_support_format_all(archive);
321 if (archive_read_open_file(archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
322 RET_ERR(PM_ERR_PKG_OPEN, NULL);
325 info = _alpm_pkg_new(NULL, NULL);
326 if(info == NULL) {
327 archive_read_finish(archive);
328 RET_ERR(PM_ERR_MEMORY, NULL);
331 if(stat(pkgfile, &st) == 0) {
332 info->size = st.st_size;
335 /* TODO there is no reason to make temp files to read
336 * from a libarchive archive, it can be done by reading
337 * directly from the archive
338 * See: archive_read_data_into_buffer
339 * requires changes 'parse_descfile' as well
340 * */
342 /* Read through the entire archive for metadata. We will continue reading
343 * even if all metadata is found, to verify the integrity of the archive in
344 * full */
345 while((ret = archive_read_next_header (archive, &entry)) == ARCHIVE_OK) {
346 const char *entry_name = archive_entry_pathname(entry);
348 if(strcmp(entry_name, ".PKGINFO") == 0) {
349 /* extract this file into /tmp. it has info for us */
350 descfile = strdup("/tmp/alpm_XXXXXX");
351 fd = mkstemp(descfile);
352 archive_read_data_into_fd (archive, fd);
353 /* parse the info file */
354 if(parse_descfile(descfile, info) == -1) {
355 _alpm_log(PM_LOG_ERROR, _("could not parse the package description file"));
356 goto pkg_invalid;
358 if(!strlen(info->name)) {
359 _alpm_log(PM_LOG_ERROR, _("missing package name in %s"), pkgfile);
360 goto pkg_invalid;
362 if(!strlen(info->version)) {
363 _alpm_log(PM_LOG_ERROR, _("missing package version in %s"), pkgfile);
364 goto pkg_invalid;
366 config = 1;
367 unlink(descfile);
368 FREE(descfile);
369 close(fd);
370 continue;
371 } else if(strcmp(entry_name, ".INSTALL") == 0) {
372 info->scriptlet = 1;
373 scriptcheck = 1;
374 } else if(strcmp(entry_name, ".FILELIST") == 0) {
375 /* Build info->files from the filelist */
376 FILE *fp;
377 char *fn;
378 char *str;
379 int fd;
381 if((str = (char *)malloc(PATH_MAX)) == NULL) {
382 RET_ERR(PM_ERR_MEMORY, (pmpkg_t *)-1);
384 fn = strdup("/tmp/alpm_XXXXXX");
385 fd = mkstemp(fn);
386 archive_read_data_into_fd(archive,fd);
387 fp = fopen(fn, "r");
388 while(!feof(fp)) {
389 if(fgets(str, PATH_MAX, fp) == NULL) {
390 continue;
392 _alpm_strtrim(str);
393 info->files = alpm_list_add(info->files, strdup(str));
395 FREE(str);
396 fclose(fp);
397 if(unlink(fn)) {
398 _alpm_log(PM_LOG_WARNING, _("could not remove tempfile %s"), fn);
400 FREE(fn);
401 close(fd);
402 filelist = 1;
403 continue;
404 } else {
405 scriptcheck = 1;
406 /* Keep track of all files so we can generate a filelist later if missing */
407 all_files = alpm_list_add(all_files, strdup(entry_name));
410 if(archive_read_data_skip(archive)) {
411 _alpm_log(PM_LOG_ERROR, _("error while reading package: %s"), archive_error_string(archive));
412 pm_errno = PM_ERR_LIBARCHIVE_ERROR;
413 goto error;
415 expath = NULL;
417 if(ret != ARCHIVE_EOF) { /* An error occured */
418 _alpm_log(PM_LOG_ERROR, _("error while reading package: %s"), archive_error_string(archive));
419 pm_errno = PM_ERR_LIBARCHIVE_ERROR;
420 goto error;
423 if(!config) {
424 _alpm_log(PM_LOG_ERROR, _("missing package metadata"), pkgfile);
425 goto error;
428 archive_read_finish(archive);
430 if(!filelist) {
431 _alpm_log(PM_LOG_ERROR, _("missing package filelist in %s, generating one"), pkgfile);
432 info->files = all_files;
433 } else {
434 alpm_list_free_inner(all_files, free);
435 alpm_list_free(all_files);
438 /* this is IMPORTANT - "checking for conflicts" requires a sorted list, so we
439 * ensure that here */
440 info->files = alpm_list_msort(info->files, alpm_list_count(info->files), _alpm_str_cmp);
442 /* internal */
443 info->origin = PKG_FROM_FILE;
444 info->data = strdup(pkgfile);
445 info->infolevel = 0xFF;
447 return(info);
449 pkg_invalid:
450 pm_errno = PM_ERR_PKG_INVALID;
451 if(descfile) {
452 unlink(descfile);
453 FREE(descfile);
455 if(fd != -1) {
456 close(fd);
458 error:
459 FREEPKG(info);
460 archive_read_finish(archive);
462 return(NULL);
465 /* Test for existence of a package in a alpm_list_t*
466 * of pmpkg_t*
468 pmpkg_t *_alpm_pkg_find(const char *needle, alpm_list_t *haystack)
470 alpm_list_t *lp;
472 ALPM_LOG_FUNC;
474 if(needle == NULL || haystack == NULL) {
475 return(NULL);
478 for(lp = haystack; lp; lp = lp->next) {
479 pmpkg_t *info = lp->data;
481 if(info && strcmp(alpm_pkg_get_name(info), needle) == 0) {
482 return(info);
485 return(NULL);
488 int _alpm_pkg_splitname(const char *target, char *name, char *version, int witharch)
490 char tmp[PKG_FULLNAME_LEN+7];
491 const char *t;
492 char *p, *q;
494 ALPM_LOG_FUNC;
496 if(target == NULL) {
497 return(-1);
500 /* trim path name (if any) */
501 if((t = strrchr(target, '/')) == NULL) {
502 t = target;
503 } else {
504 t++;
506 STRNCPY(tmp, t, PKG_FULLNAME_LEN+7);
507 /* trim file extension (if any) */
508 if((p = strstr(tmp, PM_EXT_PKG))) {
509 *p = '\0';
512 if(witharch) {
513 /* trim architecture */
514 if((p = alpm_pkg_name_hasarch(tmp))) {
515 *p = 0;
519 p = tmp + strlen(tmp);
521 for(q = --p; *q && *q != '-'; q--);
522 if(*q != '-' || q == tmp) {
523 return(-1);
525 for(p = --q; *p && *p != '-'; p--);
526 if(*p != '-' || p == tmp) {
527 return(-1);
529 if(version) {
530 STRNCPY(version, p+1, PKG_VERSION_LEN);
532 *p = '\0';
534 if(name) {
535 STRNCPY(name, tmp, PKG_NAME_LEN);
538 return(0);
542 void _alpm_pkg_update_requiredby(pmpkg_t *pkg)
544 alpm_list_t *i, *j, *k;
545 const char *pkgname = alpm_pkg_get_name(pkg);
547 pmdb_t *localdb = alpm_option_get_localdb();
548 for(i = _alpm_db_get_pkgcache(localdb); i; i = i->next) {
549 if(!i->data) {
550 continue;
552 pmpkg_t *cachepkg = i->data;
553 const char *cachepkgname = alpm_pkg_get_name(cachepkg);
555 for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
556 pmdepend_t *dep;
557 if(!j->data) {
558 continue;
560 dep = alpm_splitdep(j->data);
561 if(dep == NULL) {
562 continue;
565 /* check the actual package itself */
566 if(strcmp(dep->name, pkgname) == 0) {
567 alpm_list_t *reqs = alpm_pkg_get_requiredby(pkg);
569 if(!alpm_list_find_str(reqs, cachepkgname)) {
570 _alpm_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s'"),
571 cachepkgname, pkg->name);
572 reqs = alpm_list_add(reqs, strdup(cachepkgname));
573 pkg->requiredby = reqs;
577 /* check for provisions as well */
578 for(k = alpm_pkg_get_provides(pkg); k; k = k->next) {
579 const char *provname = k->data;
580 if(strcmp(dep->name, provname) == 0) {
581 alpm_list_t *reqs = alpm_pkg_get_requiredby(pkg);
583 if(!alpm_list_find_str(reqs, cachepkgname)) {
584 _alpm_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s' (provides: %s)"),
585 cachepkgname, pkgname, provname);
586 reqs = alpm_list_add(reqs, strdup(cachepkgname));
587 pkg->requiredby = reqs;
591 free(dep);
596 const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
598 ALPM_LOG_FUNC;
600 /* Sanity checks */
601 ASSERT(handle != NULL, return(NULL));
602 ASSERT(pkg != NULL, return(NULL));
604 if(!strlen(pkg->filename)) {
605 /* construct the file name, it's not in the desc file */
606 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
607 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
609 if(pkg->arch && strlen(pkg->arch) > 0) {
610 snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s-%s" PM_EXT_PKG,
611 pkg->name, pkg->version, pkg->arch);
612 } else {
613 snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s" PM_EXT_PKG,
614 pkg->name, pkg->version);
618 return pkg->filename;
621 const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg)
623 ALPM_LOG_FUNC;
625 /* Sanity checks */
626 ASSERT(handle != NULL, return(NULL));
627 ASSERT(pkg != NULL, return(NULL));
629 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_BASE)) {
630 _alpm_db_read(pkg->data, pkg, INFRQ_BASE);
632 return pkg->name;
635 const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg)
637 ALPM_LOG_FUNC;
639 /* Sanity checks */
640 ASSERT(handle != NULL, return(NULL));
641 ASSERT(pkg != NULL, return(NULL));
643 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_BASE)) {
644 _alpm_db_read(pkg->data, pkg, INFRQ_BASE);
646 return pkg->version;
649 const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg)
651 ALPM_LOG_FUNC;
653 /* Sanity checks */
654 ASSERT(handle != NULL, return(NULL));
655 ASSERT(pkg != NULL, return(NULL));
657 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
658 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
660 return pkg->desc;
663 const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg)
665 ALPM_LOG_FUNC;
667 /* Sanity checks */
668 ASSERT(handle != NULL, return(NULL));
669 ASSERT(pkg != NULL, return(NULL));
671 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
672 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
674 return pkg->url;
677 const char SYMEXPORT *alpm_pkg_get_builddate(pmpkg_t *pkg)
679 ALPM_LOG_FUNC;
681 /* Sanity checks */
682 ASSERT(handle != NULL, return(NULL));
683 ASSERT(pkg != NULL, return(NULL));
685 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
686 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
688 return pkg->builddate;
691 const char SYMEXPORT *alpm_pkg_get_buildtype(pmpkg_t *pkg)
693 ALPM_LOG_FUNC;
695 /* Sanity checks */
696 ASSERT(handle != NULL, return(NULL));
697 ASSERT(pkg != NULL, return(NULL));
699 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
700 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
702 return pkg->buildtype;
705 const char SYMEXPORT *alpm_pkg_get_installdate(pmpkg_t *pkg)
707 ALPM_LOG_FUNC;
709 /* Sanity checks */
710 ASSERT(handle != NULL, return(NULL));
711 ASSERT(pkg != NULL, return(NULL));
713 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
714 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
716 return pkg->installdate;
719 const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)
721 ALPM_LOG_FUNC;
723 /* Sanity checks */
724 ASSERT(handle != NULL, return(NULL));
725 ASSERT(pkg != NULL, return(NULL));
727 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
728 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
730 return pkg->packager;
733 const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)
735 ALPM_LOG_FUNC;
737 /* Sanity checks */
738 ASSERT(handle != NULL, return(NULL));
739 ASSERT(pkg != NULL, return(NULL));
741 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
742 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
744 return pkg->md5sum;
747 const char SYMEXPORT *alpm_pkg_get_sha1sum(pmpkg_t *pkg)
749 ALPM_LOG_FUNC;
751 /* Sanity checks */
752 ASSERT(handle != NULL, return(NULL));
753 ASSERT(pkg != NULL, return(NULL));
755 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
756 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
758 return pkg->sha1sum;
761 const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg)
763 ALPM_LOG_FUNC;
765 /* Sanity checks */
766 ASSERT(handle != NULL, return(NULL));
767 ASSERT(pkg != NULL, return(NULL));
769 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
770 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
772 return pkg->arch;
775 unsigned long SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg)
777 ALPM_LOG_FUNC;
779 /* Sanity checks */
780 ASSERT(handle != NULL, return(-1));
781 ASSERT(pkg != NULL, return(-1));
783 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
784 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
786 return pkg->size;
789 unsigned long SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg)
791 ALPM_LOG_FUNC;
793 /* Sanity checks */
794 ASSERT(handle != NULL, return(-1));
795 ASSERT(pkg != NULL, return(-1));
797 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
798 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
800 return pkg->isize;
803 pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)
805 ALPM_LOG_FUNC;
807 /* Sanity checks */
808 ASSERT(handle != NULL, return(-1));
809 ASSERT(pkg != NULL, return(-1));
811 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
812 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
814 return pkg->reason;
817 alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)
819 ALPM_LOG_FUNC;
821 /* Sanity checks */
822 ASSERT(handle != NULL, return(NULL));
823 ASSERT(pkg != NULL, return(NULL));
825 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
826 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
828 return pkg->licenses;
831 alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg)
833 ALPM_LOG_FUNC;
835 /* Sanity checks */
836 ASSERT(handle != NULL, return(NULL));
837 ASSERT(pkg != NULL, return(NULL));
839 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
840 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
842 return pkg->groups;
845 /* depends */
846 alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg)
848 ALPM_LOG_FUNC;
850 /* Sanity checks */
851 ASSERT(handle != NULL, return(NULL));
852 ASSERT(pkg != NULL, return(NULL));
854 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
855 _alpm_db_read(pkg->data, pkg, INFRQ_DEPENDS);
857 return pkg->depends;
860 alpm_list_t SYMEXPORT *alpm_pkg_get_removes(pmpkg_t *pkg)
862 ALPM_LOG_FUNC;
864 /* Sanity checks */
865 ASSERT(handle != NULL, return(NULL));
866 ASSERT(pkg != NULL, return(NULL));
868 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
869 _alpm_db_read(pkg->data, pkg, INFRQ_DEPENDS);
871 return pkg->removes;
874 alpm_list_t SYMEXPORT *alpm_pkg_get_requiredby(pmpkg_t *pkg)
876 ALPM_LOG_FUNC;
878 /* Sanity checks */
879 ASSERT(handle != NULL, return(NULL));
880 ASSERT(pkg != NULL, return(NULL));
882 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
883 _alpm_db_read(pkg->data, pkg, INFRQ_DEPENDS);
885 return pkg->requiredby;
888 alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg)
890 ALPM_LOG_FUNC;
892 /* Sanity checks */
893 ASSERT(handle != NULL, return(NULL));
894 ASSERT(pkg != NULL, return(NULL));
896 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
897 _alpm_db_read(pkg->data, pkg, INFRQ_DEPENDS);
899 return pkg->conflicts;
902 alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg)
904 ALPM_LOG_FUNC;
906 /* Sanity checks */
907 ASSERT(handle != NULL, return(NULL));
908 ASSERT(pkg != NULL, return(NULL));
910 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
911 _alpm_db_read(pkg->data, pkg, INFRQ_DEPENDS);
913 return pkg->provides;
916 alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg)
918 ALPM_LOG_FUNC;
920 /* Sanity checks */
921 ASSERT(handle != NULL, return(NULL));
922 ASSERT(pkg != NULL, return(NULL));
924 if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
925 _alpm_db_read(pkg->data, pkg, INFRQ_DESC);
927 return pkg->replaces;
930 alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg)
932 ALPM_LOG_FUNC;
934 /* Sanity checks */
935 ASSERT(handle != NULL, return(NULL));
936 ASSERT(pkg != NULL, return(NULL));
938 if(pkg->origin == PKG_FROM_CACHE && pkg->data == handle->db_local
939 && !(pkg->infolevel & INFRQ_FILES)) {
940 _alpm_db_read(pkg->data, pkg, INFRQ_FILES);
942 return pkg->files;
945 alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
947 ALPM_LOG_FUNC;
949 /* Sanity checks */
950 ASSERT(handle != NULL, return(NULL));
951 ASSERT(pkg != NULL, return(NULL));
953 if(pkg->origin == PKG_FROM_CACHE && pkg->data == handle->db_local
954 && !(pkg->infolevel & INFRQ_FILES)) {
955 _alpm_db_read(pkg->data, pkg, INFRQ_FILES);
957 return pkg->backup;
960 unsigned short SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
962 ALPM_LOG_FUNC;
964 /* Sanity checks */
965 ASSERT(handle != NULL, return(-1));
966 ASSERT(pkg != NULL, return(-1));
968 if(pkg->origin == PKG_FROM_CACHE && pkg->data == handle->db_local
969 && !(pkg->infolevel & INFRQ_SCRIPTLET)) {
970 _alpm_db_read(pkg->data, pkg, INFRQ_SCRIPTLET);
972 return pkg->scriptlet;
975 /* TODO this should either be public, or done somewhere else */
976 int _alpm_pkg_istoonew(pmpkg_t *pkg)
978 time_t t;
980 ALPM_LOG_FUNC;
982 if (!handle->upgradedelay)
983 return 0;
984 time(&t);
985 return((pkg->date + handle->upgradedelay) > t);
987 /* vim: set ts=2 sw=2 noet: */