1 /* pkg.c - the opkg package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
27 #include "pkg_parse.h"
28 #include "pkg_extract.h"
29 #include "opkg_message.h"
30 #include "opkg_utils.h"
32 #include "libbb/libbb.h"
33 #include "sprintf_alloc.h"
34 #include "file_util.h"
37 #include "opkg_conf.h"
39 typedef struct enum_map enum_map_t;
46 static const enum_map_t pkg_state_want_map[] = {
47 { SW_UNKNOWN, "unknown"},
48 { SW_INSTALL, "install"},
49 { SW_DEINSTALL, "deinstall"},
53 static const enum_map_t pkg_state_flag_map[] = {
55 { SF_REINSTREQ, "reinstreq"},
57 { SF_REPLACE, "replace"},
58 { SF_NOPRUNE, "noprune"},
59 { SF_PREFER, "prefer"},
60 { SF_OBSOLETE, "obsolete"},
64 static const enum_map_t pkg_state_status_map[] = {
65 { SS_NOT_INSTALLED, "not-installed" },
66 { SS_UNPACKED, "unpacked" },
67 { SS_HALF_CONFIGURED, "half-configured" },
68 { SS_INSTALLED, "installed" },
69 { SS_HALF_INSTALLED, "half-installed" },
70 { SS_CONFIG_FILES, "config-files" },
71 { SS_POST_INST_FAILED, "post-inst-failed" },
72 { SS_REMOVAL_FAILED, "removal-failed" }
75 static int verrevcmp(const char *val, const char *ref);
82 pkg = calloc(1, sizeof(pkg_t));
84 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
93 int pkg_init(pkg_t *pkg)
101 pkg->architecture = NULL;
102 pkg->maintainer = NULL;
104 pkg->description = NULL;
105 pkg->state_want = SW_UNKNOWN;
106 pkg->state_flag = SF_OK;
107 pkg->state_status = SS_NOT_INSTALLED;
108 pkg->depends_str = NULL;
109 pkg->provides_str = NULL;
110 pkg->depends_count = 0;
112 pkg->suggests_str = NULL;
113 pkg->recommends_str = NULL;
114 pkg->suggests_count = 0;
115 pkg->recommends_count = 0;
117 active_list_init(&pkg->list);
119 /* Abhaya: added init for conflicts fields */
120 pkg->conflicts = NULL;
121 pkg->conflicts_count = 0;
123 /* added for replaces. Jamey 7/23/2002 */
124 pkg->replaces = NULL;
125 pkg->replaces_count = 0;
127 pkg->pre_depends_count = 0;
128 pkg->pre_depends_str = NULL;
129 pkg->provides_count = 0;
130 pkg->provides = NULL;
131 pkg->filename = NULL;
132 pkg->local_filename = NULL;
133 pkg->tmp_unpack_dir = NULL;
135 #if defined HAVE_SHA256
136 pkg->sha256sum = NULL;
139 pkg->installed_size = NULL;
140 pkg->priority = NULL;
142 conffile_list_init(&pkg->conffiles);
143 pkg->installed_files = NULL;
144 pkg->installed_files_ref_cnt = 0;
146 pkg->provided_by_hand = 0;
151 void compound_depend_deinit (compound_depend_t *depends)
154 for (i = 0; i < depends->possibility_count; i++)
157 d = depends->possibilities[i];
161 free (depends->possibilities);
164 void pkg_deinit(pkg_t *pkg)
173 /* revision shares storage with version, so
175 pkg->revision = NULL;
176 /* owned by opkg_conf_t */
178 /* owned by opkg_conf_t */
180 free(pkg->architecture);
181 pkg->architecture = NULL;
182 free(pkg->maintainer);
183 pkg->maintainer = NULL;
186 free(pkg->description);
187 pkg->description = NULL;
188 pkg->state_want = SW_UNKNOWN;
189 pkg->state_flag = SF_OK;
190 pkg->state_status = SS_NOT_INSTALLED;
192 active_list_clear(&pkg->list);
194 free (pkg->replaces);
195 pkg->replaces = NULL;
197 for (i = 0; i < pkg->depends_count; i++)
198 free (pkg->depends_str[i]);
199 free(pkg->depends_str);
200 pkg->depends_str = NULL;
202 for (i = 0; i < pkg->provides_count; i++)
203 free (pkg->provides_str[i]);
204 free(pkg->provides_str);
205 pkg->provides_str = NULL;
207 for (i = 0; i < pkg->conflicts_count; i++)
208 free (pkg->conflicts_str[i]);
209 free(pkg->conflicts_str);
210 pkg->conflicts_str = NULL;
212 for (i = 0; i < pkg->replaces_count; i++)
213 free (pkg->replaces_str[i]);
214 free(pkg->replaces_str);
215 pkg->replaces_str = NULL;
217 for (i = 0; i < pkg->recommends_count; i++)
218 free (pkg->recommends_str[i]);
219 free(pkg->recommends_str);
220 pkg->recommends_str = NULL;
222 for (i = 0; i < pkg->suggests_count; i++)
223 free (pkg->suggests_str[i]);
224 free(pkg->suggests_str);
225 pkg->suggests_str = NULL;
229 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
232 for (x = 0; x < count; x++)
233 compound_depend_deinit (&pkg->depends[x]);
240 for (x = 0; x < pkg->conflicts_count; x++)
241 compound_depend_deinit (&pkg->conflicts[x]);
242 free (pkg->conflicts);
245 free (pkg->provides);
247 pkg->pre_depends_count = 0;
248 free(pkg->pre_depends_str);
249 pkg->pre_depends_str = NULL;
250 pkg->provides_count = 0;
252 pkg->filename = NULL;
253 free(pkg->local_filename);
254 pkg->local_filename = NULL;
255 /* CLEANUP: It'd be nice to pullin the cleanup function from
256 opkg_install.c here. See comment in
257 opkg_install.c:cleanup_temporary_files */
258 free(pkg->tmp_unpack_dir);
259 pkg->tmp_unpack_dir = NULL;
262 #if defined HAVE_SHA256
263 free(pkg->sha256sum);
264 pkg->sha256sum = NULL;
268 free(pkg->installed_size);
269 pkg->installed_size = NULL;
271 pkg->priority = NULL;
274 conffile_list_deinit(&pkg->conffiles);
275 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
276 since if they are calling deinit, they should know. Maybe do an
277 assertion here instead? */
278 pkg->installed_files_ref_cnt = 1;
279 pkg_free_installed_files(pkg);
285 int pkg_init_from_file(pkg_t *pkg, const char *filename)
288 char **raw, **raw_start;
292 if (err) { return err; }
294 pkg->local_filename = xstrdup(filename);
296 control_file = tmpfile();
297 err = pkg_extract_control_file_to_stream(pkg, control_file);
298 if (err) { return err; }
300 rewind(control_file);
301 raw = raw_start = read_raw_pkgs_from_stream(control_file);
302 pkg_parse_raw(pkg, &raw, NULL, NULL);
304 fclose(control_file);
315 /* Merge any new information in newpkg into oldpkg */
316 /* XXX: CLEANUP: This function shouldn't actually modify anything in
317 newpkg, but should leave it usable. This rework is so that
318 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
320 * uh, i thought that i had originally written this so that it took
321 * two pkgs and returned a new one? we can do that again... -sma
323 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
325 if (oldpkg == newpkg) {
330 oldpkg->src = newpkg->src;
332 oldpkg->dest = newpkg->dest;
333 if (!oldpkg->architecture)
334 oldpkg->architecture = xstrdup(newpkg->architecture);
335 if (!oldpkg->arch_priority)
336 oldpkg->arch_priority = newpkg->arch_priority;
337 if (!oldpkg->section)
338 oldpkg->section = xstrdup(newpkg->section);
339 if(!oldpkg->maintainer)
340 oldpkg->maintainer = xstrdup(newpkg->maintainer);
341 if(!oldpkg->description)
342 oldpkg->description = xstrdup(newpkg->description);
344 /* merge the state_flags from the new package */
345 oldpkg->state_want = newpkg->state_want;
346 oldpkg->state_status = newpkg->state_status;
347 oldpkg->state_flag = newpkg->state_flag;
349 if (oldpkg->state_want == SW_UNKNOWN)
350 oldpkg->state_want = newpkg->state_want;
351 if (oldpkg->state_status == SS_NOT_INSTALLED)
352 oldpkg->state_status = newpkg->state_status;
353 oldpkg->state_flag |= newpkg->state_flag;
356 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
357 oldpkg->depends_str = newpkg->depends_str;
358 newpkg->depends_str = NULL;
359 oldpkg->depends_count = newpkg->depends_count;
360 newpkg->depends_count = 0;
362 oldpkg->depends = newpkg->depends;
363 newpkg->depends = NULL;
365 oldpkg->pre_depends_str = newpkg->pre_depends_str;
366 newpkg->pre_depends_str = NULL;
367 oldpkg->pre_depends_count = newpkg->pre_depends_count;
368 newpkg->pre_depends_count = 0;
370 oldpkg->recommends_str = newpkg->recommends_str;
371 newpkg->recommends_str = NULL;
372 oldpkg->recommends_count = newpkg->recommends_count;
373 newpkg->recommends_count = 0;
375 oldpkg->suggests_str = newpkg->suggests_str;
376 newpkg->suggests_str = NULL;
377 oldpkg->suggests_count = newpkg->suggests_count;
378 newpkg->suggests_count = 0;
381 if (!oldpkg->provides_str) {
382 oldpkg->provides_str = newpkg->provides_str;
383 newpkg->provides_str = NULL;
384 oldpkg->provides_count = newpkg->provides_count;
385 newpkg->provides_count = 0;
387 oldpkg->provides = newpkg->provides;
388 newpkg->provides = NULL;
391 if (!oldpkg->conflicts_str) {
392 oldpkg->conflicts_str = newpkg->conflicts_str;
393 newpkg->conflicts_str = NULL;
394 oldpkg->conflicts_count = newpkg->conflicts_count;
395 newpkg->conflicts_count = 0;
397 oldpkg->conflicts = newpkg->conflicts;
398 newpkg->conflicts = NULL;
401 if (!oldpkg->replaces_str) {
402 oldpkg->replaces_str = newpkg->replaces_str;
403 newpkg->replaces_str = NULL;
404 oldpkg->replaces_count = newpkg->replaces_count;
405 newpkg->replaces_count = 0;
407 oldpkg->replaces = newpkg->replaces;
408 newpkg->replaces = NULL;
411 if (!oldpkg->filename)
412 oldpkg->filename = xstrdup(newpkg->filename);
414 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
415 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
416 if (!oldpkg->local_filename)
417 oldpkg->local_filename = xstrdup(newpkg->local_filename);
418 if (!oldpkg->tmp_unpack_dir)
419 oldpkg->tmp_unpack_dir = xstrdup(newpkg->tmp_unpack_dir);
421 oldpkg->md5sum = xstrdup(newpkg->md5sum);
422 #if defined HAVE_SHA256
423 if (!oldpkg->sha256sum)
424 oldpkg->sha256sum = xstrdup(newpkg->sha256sum);
427 oldpkg->size = xstrdup(newpkg->size);
428 if (!oldpkg->installed_size)
429 oldpkg->installed_size = xstrdup(newpkg->installed_size);
430 if (!oldpkg->priority)
431 oldpkg->priority = xstrdup(newpkg->priority);
433 oldpkg->source = xstrdup(newpkg->source);
434 if (nv_pair_list_empty(&oldpkg->conffiles)){
435 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
436 conffile_list_init(&newpkg->conffiles);
438 if (!oldpkg->installed_files){
439 oldpkg->installed_files = newpkg->installed_files;
440 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
441 newpkg->installed_files = NULL;
443 if (!oldpkg->essential)
444 oldpkg->essential = newpkg->essential;
449 abstract_pkg_t *abstract_pkg_new(void)
451 abstract_pkg_t * ab_pkg;
453 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
455 if (ab_pkg == NULL) {
456 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
460 if ( abstract_pkg_init(ab_pkg) < 0 )
466 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
468 ab_pkg->provided_by = abstract_pkg_vec_alloc();
469 if (ab_pkg->provided_by==NULL){
472 ab_pkg->dependencies_checked = 0;
473 ab_pkg->state_status = SS_NOT_INSTALLED;
478 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
481 char **raw_start=NULL;
483 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
484 temp_str = (char *) alloca (str_size);
485 memset(temp_str, 0 , str_size);
487 if (temp_str == NULL ){
488 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
491 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
493 raw = raw_start = read_raw_pkgs_from_file(temp_str);
495 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
500 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
501 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
516 void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
519 int flag_provide_false = 0;
521 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
522 goto UNKNOWN_FMT_FIELD;
529 if (strcasecmp(field, "Architecture") == 0) {
530 if (pkg->architecture) {
531 fprintf(fp, "Architecture: %s\n", pkg->architecture);
533 } else if (strcasecmp(field, "Auto-Installed") == 0) {
534 if (pkg->auto_installed)
535 fprintf(fp, "Auto-Installed: yes\n");
537 goto UNKNOWN_FMT_FIELD;
542 if (strcasecmp(field, "Conffiles") == 0) {
543 conffile_list_elt_t *iter;
545 if (nv_pair_list_empty(&pkg->conffiles))
548 fprintf(fp, "Conffiles:\n");
549 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
550 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
551 fprintf(fp, "%s %s\n",
552 ((conffile_t *)iter->data)->name,
553 ((conffile_t *)iter->data)->value);
556 } else if (strcasecmp(field, "Conflicts") == 0) {
557 if (pkg->conflicts_count) {
558 fprintf(fp, "Conflicts:");
559 for(i = 0; i < pkg->conflicts_count; i++) {
560 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
565 goto UNKNOWN_FMT_FIELD;
570 if (strcasecmp(field, "Depends") == 0) {
571 if (pkg->depends_count) {
572 fprintf(fp, "Depends:");
573 for(i = 0; i < pkg->depends_count; i++) {
574 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
578 } else if (strcasecmp(field, "Description") == 0) {
579 if (pkg->description) {
580 fprintf(fp, "Description: %s\n", pkg->description);
583 goto UNKNOWN_FMT_FIELD;
588 if (pkg->essential) {
589 fprintf(fp, "Essential: yes\n");
595 fprintf(fp, "Filename: %s\n", pkg->filename);
600 if (strcasecmp(field, "Installed-Size") == 0) {
601 fprintf(fp, "Installed-Size: %s\n", pkg->installed_size);
602 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
603 fprintf(fp, "Installed-Time: %lu\n", pkg->installed_time);
608 if (strcasecmp(field, "Maintainer") == 0) {
609 if (pkg->maintainer) {
610 fprintf(fp, "maintainer: %s\n", pkg->maintainer);
612 } else if (strcasecmp(field, "MD5sum") == 0) {
614 fprintf(fp, "MD5Sum: %s\n", pkg->md5sum);
617 goto UNKNOWN_FMT_FIELD;
622 if (strcasecmp(field, "Package") == 0) {
623 fprintf(fp, "Package: %s\n", pkg->name);
624 } else if (strcasecmp(field, "Priority") == 0) {
625 fprintf(fp, "Priority: %s\n", pkg->priority);
626 } else if (strcasecmp(field, "Provides") == 0) {
627 if (pkg->provides_count) {
628 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
629 for ( i=0; i < pkg->provides_count; i++ ){
630 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
631 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
632 flag_provide_false = 1;
635 if ( !flag_provide_false || /* Pigi there is not my trick flag */
636 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
637 fprintf(fp, "Provides:");
638 for(i = 0; i < pkg->provides_count; i++) {
639 if (strlen(pkg->provides_str[i])>0) {
640 fprintf(fp, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
647 goto UNKNOWN_FMT_FIELD;
652 if (strcasecmp (field, "Replaces") == 0) {
653 if (pkg->replaces_count) {
654 fprintf(fp, "Replaces:");
655 for (i = 0; i < pkg->replaces_count; i++) {
656 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
660 } else if (strcasecmp (field, "Recommends") == 0) {
661 if (pkg->recommends_count) {
662 fprintf(fp, "Recommends:");
663 for(i = 0; i < pkg->recommends_count; i++) {
664 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
669 goto UNKNOWN_FMT_FIELD;
674 if (strcasecmp(field, "Section") == 0) {
676 fprintf(fp, "Section: %s\n", pkg->section);
678 #if defined HAVE_SHA256
679 } else if (strcasecmp(field, "SHA256sum") == 0) {
680 if (pkg->sha256sum) {
681 fprintf(fp, "SHA256sum: %s\n", pkg->sha256sum);
684 } else if (strcasecmp(field, "Size") == 0) {
686 fprintf(fp, "Size: %s\n", pkg->size);
688 } else if (strcasecmp(field, "Source") == 0) {
690 fprintf(fp, "Source: %s\n", pkg->source);
692 } else if (strcasecmp(field, "Status") == 0) {
693 char *pflag = pkg_state_flag_to_str(pkg->state_flag);
694 char *pstat = pkg_state_status_to_str(pkg->state_status);
695 char *pwant = pkg_state_want_to_str(pkg->state_want);
697 if (pflag == NULL || pstat == NULL || pwant == NULL)
700 fprintf(fp, "Status: %s %s %s\n", pwant, pflag, pstat);
705 } else if (strcasecmp(field, "Suggests") == 0) {
706 if (pkg->suggests_count) {
707 fprintf(fp, "Suggests:");
708 for(i = 0; i < pkg->suggests_count; i++) {
709 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
714 goto UNKNOWN_FMT_FIELD;
719 if (strcasecmp(field, "Tags") == 0) {
721 fprintf(fp, "Tags: %s\n", pkg->tags);
728 char *version = pkg_version_str_alloc(pkg);
731 fprintf(fp, "Version: %s\n", version);
736 goto UNKNOWN_FMT_FIELD;
742 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
745 void pkg_formatted_info(FILE *fp, pkg_t *pkg)
747 pkg_formatted_field(fp, pkg, "Package");
748 pkg_formatted_field(fp, pkg, "Version");
749 pkg_formatted_field(fp, pkg, "Depends");
750 pkg_formatted_field(fp, pkg, "Recommends");
751 pkg_formatted_field(fp, pkg, "Suggests");
752 pkg_formatted_field(fp, pkg, "Provides");
753 pkg_formatted_field(fp, pkg, "Replaces");
754 pkg_formatted_field(fp, pkg, "Conflicts");
755 pkg_formatted_field(fp, pkg, "Status");
756 pkg_formatted_field(fp, pkg, "Section");
757 pkg_formatted_field(fp, pkg, "Essential");
758 pkg_formatted_field(fp, pkg, "Architecture");
759 pkg_formatted_field(fp, pkg, "Maintainer");
760 pkg_formatted_field(fp, pkg, "MD5sum");
761 pkg_formatted_field(fp, pkg, "Size");
762 pkg_formatted_field(fp, pkg, "Filename");
763 pkg_formatted_field(fp, pkg, "Conffiles");
764 pkg_formatted_field(fp, pkg, "Source");
765 pkg_formatted_field(fp, pkg, "Description");
766 pkg_formatted_field(fp, pkg, "Installed-Time");
767 pkg_formatted_field(fp, pkg, "Tags");
771 void pkg_print_status(pkg_t * pkg, FILE * file)
777 /* XXX: QUESTION: Do we actually want more fields here? The
778 original idea was to save space by installing only what was
779 needed for actual computation, (package, version, status,
780 essential, conffiles). The assumption is that all other fields
781 can be found in th available file.
783 But, someone proposed the idea to make it possible to
784 reconstruct a .opk from an installed package, (ie. for beaming
785 from one handheld to another). So, maybe we actually want a few
786 more fields here, (depends, suggests, etc.), so that that would
787 be guaranteed to work even in the absence of more information
788 from the available file.
790 28-MAR-03: kergoth and I discussed this yesterday. We think
791 the essential info needs to be here for all installed packages
792 because they may not appear in the Packages files on various
793 feeds. Furthermore, one should be able to install from URL or
794 local storage without requiring a Packages file from any feed.
797 pkg_formatted_field(file, pkg, "Package");
798 pkg_formatted_field(file, pkg, "Version");
799 pkg_formatted_field(file, pkg, "Depends");
800 pkg_formatted_field(file, pkg, "Recommends");
801 pkg_formatted_field(file, pkg, "Suggests");
802 pkg_formatted_field(file, pkg, "Provides");
803 pkg_formatted_field(file, pkg, "Replaces");
804 pkg_formatted_field(file, pkg, "Conflicts");
805 pkg_formatted_field(file, pkg, "Status");
806 pkg_formatted_field(file, pkg, "Essential");
807 pkg_formatted_field(file, pkg, "Architecture");
808 pkg_formatted_field(file, pkg, "Conffiles");
809 pkg_formatted_field(file, pkg, "Installed-Time");
810 pkg_formatted_field(file, pkg, "Auto-Installed");
815 * libdpkg - Debian packaging suite library routines
816 * vercmp.c - comparison of version numbers
818 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
820 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
824 if (pkg->epoch > ref_pkg->epoch) {
828 if (pkg->epoch < ref_pkg->epoch) {
832 r = verrevcmp(pkg->version, ref_pkg->version);
837 r = verrevcmp(pkg->revision, ref_pkg->revision);
845 /* assume ascii; warning: evaluates x multiple times! */
846 #define order(x) ((x) == '~' ? -1 \
849 : isalpha((x)) ? (x) \
852 static int verrevcmp(const char *val, const char *ref) {
856 while (*val || *ref) {
859 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
860 int vc= order(*val), rc= order(*ref);
861 if (vc != rc) return vc - rc;
865 while ( *val == '0' ) val++;
866 while ( *ref == '0' ) ref++;
867 while (isdigit(*val) && isdigit(*ref)) {
868 if (!first_diff) first_diff= *val - *ref;
871 if (isdigit(*val)) return 1;
872 if (isdigit(*ref)) return -1;
873 if (first_diff) return first_diff;
878 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
882 r = pkg_compare_versions(it, ref);
884 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
888 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
892 if (strcmp(op, "<<") == 0) {
896 if (strcmp(op, ">>") == 0) {
900 if (strcmp(op, "=") == 0) {
904 fprintf(stderr, "unknown operator: %s", op);
908 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
910 const pkg_t *a = *(const pkg_t**) p1;
911 const pkg_t *b = *(const pkg_t**) p2;
914 if (!a->name || !b->name) {
915 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
916 a, a->name, b, b->name);
920 namecmp = strcmp(a->name, b->name);
923 vercmp = pkg_compare_versions(a, b);
926 if (!a->arch_priority || !b->arch_priority) {
927 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
928 a, a->arch_priority, b, b->arch_priority);
931 if (a->arch_priority > b->arch_priority)
933 if (a->arch_priority < b->arch_priority)
938 int abstract_pkg_name_compare(const void *p1, const void *p2)
940 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
941 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
942 if (!a->name || !b->name) {
943 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
944 a, a->name, b, b->name);
947 return strcmp(a->name, b->name);
951 char *pkg_version_str_alloc(pkg_t *pkg)
953 char *complete_version;
958 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
960 epoch_str = xstrdup("");
963 if (pkg->revision && strlen(pkg->revision)) {
964 sprintf_alloc(&revision_str, "-%s", pkg->revision);
966 revision_str = xstrdup("");
970 sprintf_alloc(&complete_version, "%s%s%s",
971 epoch_str, pkg->version, revision_str);
976 return complete_version;
979 str_list_t *pkg_get_installed_files(pkg_t *pkg)
982 char *list_file_name = NULL;
983 FILE *list_file = NULL;
985 char *installed_file_name;
988 pkg->installed_files_ref_cnt++;
990 if (pkg->installed_files) {
991 return pkg->installed_files;
994 pkg->installed_files = str_list_alloc();
995 if (pkg->installed_files == NULL) {
996 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1000 /* For uninstalled packages, get the file list directly from the package.
1001 For installed packages, look at the package.list file in the database.
1003 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1004 if (pkg->local_filename == NULL) {
1005 return pkg->installed_files;
1007 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1008 file. In other words, change deb_extract so that it can
1009 simply return the file list as a char *[] rather than
1010 insisting on writing in to a FILE * as it does now. */
1011 list_file = tmpfile();
1012 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1015 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1016 __FUNCTION__, pkg->local_filename, strerror(err));
1017 return pkg->installed_files;
1021 sprintf_alloc(&list_file_name, "%s/%s.list",
1022 pkg->dest->info_dir, pkg->name);
1023 if (! file_exists(list_file_name)) {
1024 free(list_file_name);
1025 return pkg->installed_files;
1028 list_file = fopen(list_file_name, "r");
1029 if (list_file == NULL) {
1030 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1031 list_file_name, strerror(errno));
1032 free(list_file_name);
1033 return pkg->installed_files;
1035 free(list_file_name);
1038 rootdirlen = strlen( pkg->dest->root_dir );
1042 line = file_read_line_alloc(list_file);
1049 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1050 if( strncmp( pkg->dest->root_dir,
1053 if (*file_name == '.') {
1056 if (*file_name == '/') {
1060 /* Freed in pkg_free_installed_files */
1061 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1063 // already contains root_dir as header -> ABSOLUTE
1064 sprintf_alloc(&installed_file_name, "%s", file_name);
1066 str_list_append(pkg->installed_files, installed_file_name);
1067 free(installed_file_name);
1073 return pkg->installed_files;
1076 /* XXX: CLEANUP: This function and it's counterpart,
1077 (pkg_get_installed_files), do not match our init/deinit naming
1078 convention. Nor the alloc/free convention. But, then again, neither
1079 of these conventions currrently fit the way these two functions
1081 int pkg_free_installed_files(pkg_t *pkg)
1083 pkg->installed_files_ref_cnt--;
1085 if (pkg->installed_files_ref_cnt > 0)
1088 if (pkg->installed_files) {
1089 str_list_purge(pkg->installed_files);
1092 pkg->installed_files = NULL;
1097 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1100 char *list_file_name;
1102 //I don't think pkg_free_installed_files should be called here. Jamey
1103 //pkg_free_installed_files(pkg);
1105 sprintf_alloc(&list_file_name, "%s/%s.list",
1106 pkg->dest->info_dir, pkg->name);
1107 if (!conf->noaction) {
1108 err = unlink(list_file_name);
1109 free(list_file_name);
1118 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1120 conffile_list_elt_t *iter;
1121 conffile_t *conffile;
1127 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1128 conffile = (conffile_t *)iter->data;
1130 if (strcmp(conffile->name, file_name) == 0) {
1138 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1139 const char *script, const char *args)
1145 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1146 maintainer script within a chroot environment. */
1148 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1149 have scripts in pkg->tmp_unpack_dir. */
1150 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1151 if (pkg->dest == NULL) {
1152 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1153 __FUNCTION__, pkg->name);
1156 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1158 if (pkg->tmp_unpack_dir == NULL) {
1159 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1160 __FUNCTION__, pkg->name);
1163 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1166 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1167 if (conf->noaction) return 0;
1169 /* XXX: CLEANUP: There must be a better way to handle maintainer
1170 scripts when running with offline_root mode and/or a dest other
1171 than '/'. I've been playing around with some clever chroot
1172 tricks and I might come up with something workable. */
1174 * Attempt to provide a restricted environment for offline operation
1175 * Need the following set as a minimum:
1176 * OPKG_OFFLINE_ROOT = absolute path to root dir
1177 * D = absolute path to root dir (for OE generated postinst)
1178 * PATH = something safe (a restricted set of utilities)
1181 bool AllowOfflineMode = false;
1182 if (conf->offline_root) {
1183 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1184 setenv("D", conf->offline_root, 1);
1185 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1186 setenv("PATH", "/dev/null", 1);
1188 setenv("PATH", conf->offline_root_path, 1);
1189 AllowOfflineMode = true;
1194 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1196 if (! file_exists(path)) {
1201 if (conf->offline_root && !AllowOfflineMode) {
1202 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1207 sprintf_alloc(&cmd, "%s %s", path, args);
1214 fprintf(stderr, "%s script returned status %d\n", script, err);
1221 char *pkg_state_want_to_str(pkg_state_want_t sw)
1225 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1226 if (pkg_state_want_map[i].value == sw) {
1227 return xstrdup(pkg_state_want_map[i].str);
1231 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1233 return xstrdup("<STATE_WANT_UNKNOWN>");
1236 pkg_state_want_t pkg_state_want_from_str(char *str)
1240 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1241 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1242 return pkg_state_want_map[i].value;
1246 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1251 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1254 int len = 3; /* ok\000 is minimum */
1257 /* clear the temporary flags before converting to string */
1258 sf &= SF_NONVOLATILE_FLAGS;
1261 return xstrdup("ok");
1264 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1265 if (sf & pkg_state_flag_map[i].value) {
1266 len += strlen(pkg_state_flag_map[i].str) + 1;
1270 if ( str == NULL ) {
1271 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1275 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1276 if (sf & pkg_state_flag_map[i].value) {
1277 strcat(str, pkg_state_flag_map[i].str);
1282 str[len-1] = 0; /* squash last comma */
1287 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1292 if (strcmp(str, "ok") == 0) {
1295 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1296 const char *sfname = pkg_state_flag_map[i].str;
1297 int sfname_len = strlen(sfname);
1298 if (strncmp(str, sfname, sfname_len) == 0) {
1299 sf |= pkg_state_flag_map[i].value;
1301 if (str[0] == ',') {
1312 char *pkg_state_status_to_str(pkg_state_status_t ss)
1316 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1317 if (pkg_state_status_map[i].value == ss) {
1318 return xstrdup(pkg_state_status_map[i].str);
1322 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1324 return xstrdup("<STATE_STATUS_UNKNOWN>");
1327 pkg_state_status_t pkg_state_status_from_str(const char *str)
1331 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1332 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1333 return pkg_state_status_map[i].value;
1337 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1339 return SS_NOT_INSTALLED;
1342 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1344 nv_pair_list_elt_t *l;
1346 if (!pkg->architecture)
1349 list_for_each_entry(l , &conf->arch_list.head, node) {
1350 nv_pair_t *nv = (nv_pair_t *)l->data;
1351 if (strcmp(nv->name, pkg->architecture) == 0) {
1352 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1357 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1361 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1363 nv_pair_list_elt_t *l;
1365 list_for_each_entry(l , &conf->arch_list.head, node) {
1366 nv_pair_t *nv = (nv_pair_t *)l->data;
1367 if (strcmp(nv->name, archname) == 0) {
1368 int priority = strtol(nv->value, NULL, 0);
1375 int pkg_info_preinstall_check(opkg_conf_t *conf)
1378 hash_table_t *pkg_hash = &conf->pkg_hash;
1379 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1380 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1382 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1383 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1384 /* update arch_priority for each package */
1385 for (i = 0; i < available_pkgs->len; i++) {
1386 pkg_t *pkg = available_pkgs->pkgs[i];
1387 int arch_priority = 1;
1390 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1391 if (pkg->architecture)
1392 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1394 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1395 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1396 pkg->arch_priority = arch_priority;
1399 for (i = 0; i < available_pkgs->len; i++) {
1400 pkg_t *pkg = available_pkgs->pkgs[i];
1401 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1402 /* clear flags and want for any uninstallable package */
1403 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1404 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1405 pkg->state_want = SW_UNKNOWN;
1406 pkg->state_flag = 0;
1409 pkg_vec_free(available_pkgs);
1411 /* update the file owner data structure */
1412 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1413 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1414 for (i = 0; i < installed_pkgs->len; i++) {
1415 pkg_t *pkg = installed_pkgs->pkgs[i];
1416 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1417 str_list_elt_t *iter, *niter;
1418 if (installed_files == NULL) {
1419 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1422 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1424 iter = niter, niter = str_list_next(installed_files, iter)) {
1425 char *installed_file = (char *) iter->data;
1426 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1427 file_hash_set_file_owner(conf, installed_file, pkg);
1429 pkg_free_installed_files(pkg);
1431 pkg_vec_free(installed_pkgs);
1436 struct pkg_write_filelist_data {
1442 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1444 struct pkg_write_filelist_data *data = data_;
1445 pkg_t *entry = entry_;
1446 if (entry == data->pkg) {
1447 fprintf(data->stream, "%s\n", key);
1451 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1453 struct pkg_write_filelist_data data;
1454 char *list_file_name = NULL;
1458 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1461 opkg_message(conf, OPKG_INFO,
1462 " creating %s.list file\n", pkg->name);
1463 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1464 if (!list_file_name) {
1465 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1468 opkg_message(conf, OPKG_INFO,
1469 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1470 data.stream = fopen(list_file_name, "w");
1472 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1473 list_file_name, strerror(errno));
1478 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1479 fclose(data.stream);
1480 free(list_file_name);
1482 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1487 int pkg_write_changed_filelists(opkg_conf_t *conf)
1489 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1490 hash_table_t *pkg_hash = &conf->pkg_hash;
1496 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1497 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1498 for (i = 0; i < installed_pkgs->len; i++) {
1499 pkg_t *pkg = installed_pkgs->pkgs[i];
1500 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1501 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1502 err = pkg_write_filelist(conf, pkg);
1504 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1507 pkg_vec_free (installed_pkgs);