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 "sprintf_alloc.h"
33 #include "file_util.h"
36 #include "opkg_conf.h"
38 typedef struct enum_map enum_map_t;
45 static const enum_map_t pkg_state_want_map[] = {
46 { SW_UNKNOWN, "unknown"},
47 { SW_INSTALL, "install"},
48 { SW_DEINSTALL, "deinstall"},
52 static const enum_map_t pkg_state_flag_map[] = {
54 { SF_REINSTREQ, "reinstreq"},
56 { SF_REPLACE, "replace"},
57 { SF_NOPRUNE, "noprune"},
58 { SF_PREFER, "prefer"},
59 { SF_OBSOLETE, "obsolete"},
63 static const enum_map_t pkg_state_status_map[] = {
64 { SS_NOT_INSTALLED, "not-installed" },
65 { SS_UNPACKED, "unpacked" },
66 { SS_HALF_CONFIGURED, "half-configured" },
67 { SS_INSTALLED, "installed" },
68 { SS_HALF_INSTALLED, "half-installed" },
69 { SS_CONFIG_FILES, "config-files" },
70 { SS_POST_INST_FAILED, "post-inst-failed" },
71 { SS_REMOVAL_FAILED, "removal-failed" }
74 static int verrevcmp(const char *val, const char *ref);
81 pkg = calloc(1, sizeof(pkg_t));
83 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
92 int pkg_init(pkg_t *pkg)
100 pkg->architecture = NULL;
101 pkg->maintainer = NULL;
103 pkg->description = NULL;
104 pkg->state_want = SW_UNKNOWN;
105 pkg->state_flag = SF_OK;
106 pkg->state_status = SS_NOT_INSTALLED;
107 pkg->depends_str = NULL;
108 pkg->provides_str = NULL;
109 pkg->depends_count = 0;
111 pkg->suggests_str = NULL;
112 pkg->recommends_str = NULL;
113 pkg->suggests_count = 0;
114 pkg->recommends_count = 0;
116 active_list_init(&pkg->list);
118 /* Abhaya: added init for conflicts fields */
119 pkg->conflicts = NULL;
120 pkg->conflicts_count = 0;
122 /* added for replaces. Jamey 7/23/2002 */
123 pkg->replaces = NULL;
124 pkg->replaces_count = 0;
126 pkg->pre_depends_count = 0;
127 pkg->pre_depends_str = NULL;
128 pkg->provides_count = 0;
129 pkg->provides = NULL;
130 pkg->filename = NULL;
131 pkg->local_filename = NULL;
132 pkg->tmp_unpack_dir = NULL;
134 #if defined HAVE_SHA256
135 pkg->sha256sum = NULL;
138 pkg->installed_size = NULL;
139 pkg->priority = NULL;
141 conffile_list_init(&pkg->conffiles);
142 pkg->installed_files = NULL;
143 pkg->installed_files_ref_cnt = 0;
145 pkg->provided_by_hand = 0;
150 void compound_depend_deinit (compound_depend_t *depends)
153 for (i = 0; i < depends->possibility_count; i++)
156 d = depends->possibilities[i];
160 free (depends->possibilities);
163 void pkg_deinit(pkg_t *pkg)
172 /* revision shares storage with version, so
174 pkg->revision = NULL;
175 /* owned by opkg_conf_t */
177 /* owned by opkg_conf_t */
179 free(pkg->architecture);
180 pkg->architecture = NULL;
181 free(pkg->maintainer);
182 pkg->maintainer = NULL;
185 free(pkg->description);
186 pkg->description = NULL;
187 pkg->state_want = SW_UNKNOWN;
188 pkg->state_flag = SF_OK;
189 pkg->state_status = SS_NOT_INSTALLED;
191 active_list_clear(&pkg->list);
193 free (pkg->replaces);
194 pkg->replaces = NULL;
196 for (i = 0; i < pkg->depends_count; i++)
197 free (pkg->depends_str[i]);
198 free(pkg->depends_str);
199 pkg->depends_str = NULL;
201 for (i = 0; i < pkg->provides_count; i++)
202 free (pkg->provides_str[i]);
203 free(pkg->provides_str);
204 pkg->provides_str = NULL;
206 for (i = 0; i < pkg->conflicts_count; i++)
207 free (pkg->conflicts_str[i]);
208 free(pkg->conflicts_str);
209 pkg->conflicts_str = NULL;
211 for (i = 0; i < pkg->replaces_count; i++)
212 free (pkg->replaces_str[i]);
213 free(pkg->replaces_str);
214 pkg->replaces_str = NULL;
216 for (i = 0; i < pkg->recommends_count; i++)
217 free (pkg->recommends_str[i]);
218 free(pkg->recommends_str);
219 pkg->recommends_str = NULL;
221 for (i = 0; i < pkg->suggests_count; i++)
222 free (pkg->suggests_str[i]);
223 free(pkg->suggests_str);
224 pkg->suggests_str = NULL;
228 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
231 for (x = 0; x < count; x++)
232 compound_depend_deinit (&pkg->depends[x]);
239 for (x = 0; x < pkg->conflicts_count; x++)
240 compound_depend_deinit (&pkg->conflicts[x]);
241 free (pkg->conflicts);
244 free (pkg->provides);
246 pkg->pre_depends_count = 0;
247 free(pkg->pre_depends_str);
248 pkg->pre_depends_str = NULL;
249 pkg->provides_count = 0;
251 pkg->filename = NULL;
252 free(pkg->local_filename);
253 pkg->local_filename = NULL;
254 /* CLEANUP: It'd be nice to pullin the cleanup function from
255 opkg_install.c here. See comment in
256 opkg_install.c:cleanup_temporary_files */
257 free(pkg->tmp_unpack_dir);
258 pkg->tmp_unpack_dir = NULL;
261 #if defined HAVE_SHA256
262 free(pkg->sha256sum);
263 pkg->sha256sum = NULL;
267 free(pkg->installed_size);
268 pkg->installed_size = NULL;
270 pkg->priority = NULL;
273 conffile_list_deinit(&pkg->conffiles);
274 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
275 since if they are calling deinit, they should know. Maybe do an
276 assertion here instead? */
277 pkg->installed_files_ref_cnt = 1;
278 pkg_free_installed_files(pkg);
284 int pkg_init_from_file(pkg_t *pkg, const char *filename)
287 char **raw, **raw_start;
291 if (err) { return err; }
293 pkg->local_filename = strdup(filename);
295 control_file = tmpfile();
296 err = pkg_extract_control_file_to_stream(pkg, control_file);
297 if (err) { return err; }
299 rewind(control_file);
300 raw = raw_start = read_raw_pkgs_from_stream(control_file);
301 pkg_parse_raw(pkg, &raw, NULL, NULL);
303 fclose(control_file);
314 /* Merge any new information in newpkg into oldpkg */
315 /* XXX: CLEANUP: This function shouldn't actually modify anything in
316 newpkg, but should leave it usable. This rework is so that
317 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
319 * uh, i thought that i had originally written this so that it took
320 * two pkgs and returned a new one? we can do that again... -sma
322 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
324 if (oldpkg == newpkg) {
329 oldpkg->src = newpkg->src;
331 oldpkg->dest = newpkg->dest;
332 if (!oldpkg->architecture)
333 oldpkg->architecture = str_dup_safe(newpkg->architecture);
334 if (!oldpkg->arch_priority)
335 oldpkg->arch_priority = newpkg->arch_priority;
336 if (!oldpkg->section)
337 oldpkg->section = str_dup_safe(newpkg->section);
338 if(!oldpkg->maintainer)
339 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
340 if(!oldpkg->description)
341 oldpkg->description = str_dup_safe(newpkg->description);
343 /* merge the state_flags from the new package */
344 oldpkg->state_want = newpkg->state_want;
345 oldpkg->state_status = newpkg->state_status;
346 oldpkg->state_flag = newpkg->state_flag;
348 if (oldpkg->state_want == SW_UNKNOWN)
349 oldpkg->state_want = newpkg->state_want;
350 if (oldpkg->state_status == SS_NOT_INSTALLED)
351 oldpkg->state_status = newpkg->state_status;
352 oldpkg->state_flag |= newpkg->state_flag;
355 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
356 oldpkg->depends_str = newpkg->depends_str;
357 newpkg->depends_str = NULL;
358 oldpkg->depends_count = newpkg->depends_count;
359 newpkg->depends_count = 0;
361 oldpkg->depends = newpkg->depends;
362 newpkg->depends = NULL;
364 oldpkg->pre_depends_str = newpkg->pre_depends_str;
365 newpkg->pre_depends_str = NULL;
366 oldpkg->pre_depends_count = newpkg->pre_depends_count;
367 newpkg->pre_depends_count = 0;
369 oldpkg->recommends_str = newpkg->recommends_str;
370 newpkg->recommends_str = NULL;
371 oldpkg->recommends_count = newpkg->recommends_count;
372 newpkg->recommends_count = 0;
374 oldpkg->suggests_str = newpkg->suggests_str;
375 newpkg->suggests_str = NULL;
376 oldpkg->suggests_count = newpkg->suggests_count;
377 newpkg->suggests_count = 0;
380 if (!oldpkg->provides_str) {
381 oldpkg->provides_str = newpkg->provides_str;
382 newpkg->provides_str = NULL;
383 oldpkg->provides_count = newpkg->provides_count;
384 newpkg->provides_count = 0;
386 oldpkg->provides = newpkg->provides;
387 newpkg->provides = NULL;
390 if (!oldpkg->conflicts_str) {
391 oldpkg->conflicts_str = newpkg->conflicts_str;
392 newpkg->conflicts_str = NULL;
393 oldpkg->conflicts_count = newpkg->conflicts_count;
394 newpkg->conflicts_count = 0;
396 oldpkg->conflicts = newpkg->conflicts;
397 newpkg->conflicts = NULL;
400 if (!oldpkg->replaces_str) {
401 oldpkg->replaces_str = newpkg->replaces_str;
402 newpkg->replaces_str = NULL;
403 oldpkg->replaces_count = newpkg->replaces_count;
404 newpkg->replaces_count = 0;
406 oldpkg->replaces = newpkg->replaces;
407 newpkg->replaces = NULL;
410 if (!oldpkg->filename)
411 oldpkg->filename = str_dup_safe(newpkg->filename);
413 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
414 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
415 if (!oldpkg->local_filename)
416 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
417 if (!oldpkg->tmp_unpack_dir)
418 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
420 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
421 #if defined HAVE_SHA256
422 if (!oldpkg->sha256sum)
423 oldpkg->sha256sum = str_dup_safe(newpkg->sha256sum);
426 oldpkg->size = str_dup_safe(newpkg->size);
427 if (!oldpkg->installed_size)
428 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
429 if (!oldpkg->priority)
430 oldpkg->priority = str_dup_safe(newpkg->priority);
432 oldpkg->source = str_dup_safe(newpkg->source);
433 if (nv_pair_list_empty(&oldpkg->conffiles)){
434 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
435 conffile_list_init(&newpkg->conffiles);
437 if (!oldpkg->installed_files){
438 oldpkg->installed_files = newpkg->installed_files;
439 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
440 newpkg->installed_files = NULL;
442 if (!oldpkg->essential)
443 oldpkg->essential = newpkg->essential;
448 abstract_pkg_t *abstract_pkg_new(void)
450 abstract_pkg_t * ab_pkg;
452 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
454 if (ab_pkg == NULL) {
455 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
459 if ( abstract_pkg_init(ab_pkg) < 0 )
465 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
467 ab_pkg->provided_by = abstract_pkg_vec_alloc();
468 if (ab_pkg->provided_by==NULL){
471 ab_pkg->dependencies_checked = 0;
472 ab_pkg->state_status = SS_NOT_INSTALLED;
477 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
480 char **raw_start=NULL;
482 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
483 temp_str = (char *) alloca (str_size);
484 memset(temp_str, 0 , str_size);
486 if (temp_str == NULL ){
487 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
490 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
492 raw = raw_start = read_raw_pkgs_from_file(temp_str);
494 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
499 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
500 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
515 void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
518 int flag_provide_false = 0;
520 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
521 goto UNKNOWN_FMT_FIELD;
528 if (strcasecmp(field, "Architecture") == 0) {
529 if (pkg->architecture) {
530 fprintf(fp, "Architecture: %s\n", pkg->architecture);
532 } else if (strcasecmp(field, "Auto-Installed") == 0) {
533 if (pkg->auto_installed)
534 fprintf(fp, "Auto-Installed: yes\n");
536 goto UNKNOWN_FMT_FIELD;
541 if (strcasecmp(field, "Conffiles") == 0) {
542 conffile_list_elt_t *iter;
544 if (nv_pair_list_empty(&pkg->conffiles))
547 fprintf(fp, "Conffiles:\n");
548 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
549 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
550 fprintf(fp, "%s %s\n",
551 ((conffile_t *)iter->data)->name,
552 ((conffile_t *)iter->data)->value);
555 } else if (strcasecmp(field, "Conflicts") == 0) {
556 if (pkg->conflicts_count) {
557 fprintf(fp, "Conflicts:");
558 for(i = 0; i < pkg->conflicts_count; i++) {
559 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
564 goto UNKNOWN_FMT_FIELD;
569 if (strcasecmp(field, "Depends") == 0) {
570 if (pkg->depends_count) {
571 fprintf(fp, "Depends:");
572 for(i = 0; i < pkg->depends_count; i++) {
573 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
577 } else if (strcasecmp(field, "Description") == 0) {
578 if (pkg->description) {
579 fprintf(fp, "Description: %s\n", pkg->description);
582 goto UNKNOWN_FMT_FIELD;
587 if (pkg->essential) {
588 fprintf(fp, "Essential: yes\n");
594 fprintf(fp, "Filename: %s\n", pkg->filename);
599 if (strcasecmp(field, "Installed-Size") == 0) {
600 fprintf(fp, "Installed-Size: %s\n", pkg->installed_size);
601 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
602 fprintf(fp, "Installed-Time: %lu\n", pkg->installed_time);
607 if (strcasecmp(field, "Maintainer") == 0) {
608 if (pkg->maintainer) {
609 fprintf(fp, "maintainer: %s\n", pkg->maintainer);
611 } else if (strcasecmp(field, "MD5sum") == 0) {
613 fprintf(fp, "MD5Sum: %s\n", pkg->md5sum);
616 goto UNKNOWN_FMT_FIELD;
621 if (strcasecmp(field, "Package") == 0) {
622 fprintf(fp, "Package: %s\n", pkg->name);
623 } else if (strcasecmp(field, "Priority") == 0) {
624 fprintf(fp, "Priority: %s\n", pkg->priority);
625 } else if (strcasecmp(field, "Provides") == 0) {
626 if (pkg->provides_count) {
627 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
628 for ( i=0; i < pkg->provides_count; i++ ){
629 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
630 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
631 flag_provide_false = 1;
634 if ( !flag_provide_false || /* Pigi there is not my trick flag */
635 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
636 fprintf(fp, "Provides:");
637 for(i = 0; i < pkg->provides_count; i++) {
638 if (strlen(pkg->provides_str[i])>0) {
639 fprintf(fp, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
646 goto UNKNOWN_FMT_FIELD;
651 if (strcasecmp (field, "Replaces") == 0) {
652 if (pkg->replaces_count) {
653 fprintf(fp, "Replaces:");
654 for (i = 0; i < pkg->replaces_count; i++) {
655 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
659 } else if (strcasecmp (field, "Recommends") == 0) {
660 if (pkg->recommends_count) {
661 fprintf(fp, "Recommends:");
662 for(i = 0; i < pkg->recommends_count; i++) {
663 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
668 goto UNKNOWN_FMT_FIELD;
673 if (strcasecmp(field, "Section") == 0) {
675 fprintf(fp, "Section: %s\n", pkg->section);
677 #if defined HAVE_SHA256
678 } else if (strcasecmp(field, "SHA256sum") == 0) {
679 if (pkg->sha256sum) {
680 fprintf(fp, "SHA256sum: %s\n", pkg->sha256sum);
683 } else if (strcasecmp(field, "Size") == 0) {
685 fprintf(fp, "Size: %s\n", pkg->size);
687 } else if (strcasecmp(field, "Source") == 0) {
689 fprintf(fp, "Source: %s\n", pkg->source);
691 } else if (strcasecmp(field, "Status") == 0) {
692 char *pflag = pkg_state_flag_to_str(pkg->state_flag);
693 char *pstat = pkg_state_status_to_str(pkg->state_status);
694 char *pwant = pkg_state_want_to_str(pkg->state_want);
696 if (pflag == NULL || pstat == NULL || pwant == NULL)
699 fprintf(fp, "Status: %s %s %s\n", pwant, pflag, pstat);
704 } else if (strcasecmp(field, "Suggests") == 0) {
705 if (pkg->suggests_count) {
706 fprintf(fp, "Suggests:");
707 for(i = 0; i < pkg->suggests_count; i++) {
708 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
713 goto UNKNOWN_FMT_FIELD;
718 if (strcasecmp(field, "Tags") == 0) {
720 fprintf(fp, "Tags: %s\n", pkg->tags);
727 char *version = pkg_version_str_alloc(pkg);
730 fprintf(fp, "Version: %s\n", version);
735 goto UNKNOWN_FMT_FIELD;
741 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
744 void pkg_formatted_info(FILE *fp, pkg_t *pkg)
746 pkg_formatted_field(fp, pkg, "Package");
747 pkg_formatted_field(fp, pkg, "Version");
748 pkg_formatted_field(fp, pkg, "Depends");
749 pkg_formatted_field(fp, pkg, "Recommends");
750 pkg_formatted_field(fp, pkg, "Suggests");
751 pkg_formatted_field(fp, pkg, "Provides");
752 pkg_formatted_field(fp, pkg, "Replaces");
753 pkg_formatted_field(fp, pkg, "Conflicts");
754 pkg_formatted_field(fp, pkg, "Status");
755 pkg_formatted_field(fp, pkg, "Section");
756 pkg_formatted_field(fp, pkg, "Essential");
757 pkg_formatted_field(fp, pkg, "Architecture");
758 pkg_formatted_field(fp, pkg, "Maintainer");
759 pkg_formatted_field(fp, pkg, "MD5sum");
760 pkg_formatted_field(fp, pkg, "Size");
761 pkg_formatted_field(fp, pkg, "Filename");
762 pkg_formatted_field(fp, pkg, "Conffiles");
763 pkg_formatted_field(fp, pkg, "Source");
764 pkg_formatted_field(fp, pkg, "Description");
765 pkg_formatted_field(fp, pkg, "Installed-Time");
766 pkg_formatted_field(fp, pkg, "Tags");
770 void pkg_print_status(pkg_t * pkg, FILE * file)
776 /* XXX: QUESTION: Do we actually want more fields here? The
777 original idea was to save space by installing only what was
778 needed for actual computation, (package, version, status,
779 essential, conffiles). The assumption is that all other fields
780 can be found in th available file.
782 But, someone proposed the idea to make it possible to
783 reconstruct a .opk from an installed package, (ie. for beaming
784 from one handheld to another). So, maybe we actually want a few
785 more fields here, (depends, suggests, etc.), so that that would
786 be guaranteed to work even in the absence of more information
787 from the available file.
789 28-MAR-03: kergoth and I discussed this yesterday. We think
790 the essential info needs to be here for all installed packages
791 because they may not appear in the Packages files on various
792 feeds. Furthermore, one should be able to install from URL or
793 local storage without requiring a Packages file from any feed.
796 pkg_formatted_field(file, pkg, "Package");
797 pkg_formatted_field(file, pkg, "Version");
798 pkg_formatted_field(file, pkg, "Depends");
799 pkg_formatted_field(file, pkg, "Recommends");
800 pkg_formatted_field(file, pkg, "Suggests");
801 pkg_formatted_field(file, pkg, "Provides");
802 pkg_formatted_field(file, pkg, "Replaces");
803 pkg_formatted_field(file, pkg, "Conflicts");
804 pkg_formatted_field(file, pkg, "Status");
805 pkg_formatted_field(file, pkg, "Essential");
806 pkg_formatted_field(file, pkg, "Architecture");
807 pkg_formatted_field(file, pkg, "Conffiles");
808 pkg_formatted_field(file, pkg, "Installed-Time");
809 pkg_formatted_field(file, pkg, "Auto-Installed");
814 * libdpkg - Debian packaging suite library routines
815 * vercmp.c - comparison of version numbers
817 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
819 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
823 if (pkg->epoch > ref_pkg->epoch) {
827 if (pkg->epoch < ref_pkg->epoch) {
831 r = verrevcmp(pkg->version, ref_pkg->version);
836 r = verrevcmp(pkg->revision, ref_pkg->revision);
844 /* assume ascii; warning: evaluates x multiple times! */
845 #define order(x) ((x) == '~' ? -1 \
848 : isalpha((x)) ? (x) \
851 static int verrevcmp(const char *val, const char *ref) {
855 while (*val || *ref) {
858 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
859 int vc= order(*val), rc= order(*ref);
860 if (vc != rc) return vc - rc;
864 while ( *val == '0' ) val++;
865 while ( *ref == '0' ) ref++;
866 while (isdigit(*val) && isdigit(*ref)) {
867 if (!first_diff) first_diff= *val - *ref;
870 if (isdigit(*val)) return 1;
871 if (isdigit(*ref)) return -1;
872 if (first_diff) return first_diff;
877 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
881 r = pkg_compare_versions(it, ref);
883 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
887 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
891 if (strcmp(op, "<<") == 0) {
895 if (strcmp(op, ">>") == 0) {
899 if (strcmp(op, "=") == 0) {
903 fprintf(stderr, "unknown operator: %s", op);
907 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
909 const pkg_t *a = *(const pkg_t**) p1;
910 const pkg_t *b = *(const pkg_t**) p2;
913 if (!a->name || !b->name) {
914 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
915 a, a->name, b, b->name);
919 namecmp = strcmp(a->name, b->name);
922 vercmp = pkg_compare_versions(a, b);
925 if (!a->arch_priority || !b->arch_priority) {
926 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
927 a, a->arch_priority, b, b->arch_priority);
930 if (a->arch_priority > b->arch_priority)
932 if (a->arch_priority < b->arch_priority)
937 int abstract_pkg_name_compare(const void *p1, const void *p2)
939 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
940 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
941 if (!a->name || !b->name) {
942 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
943 a, a->name, b, b->name);
946 return strcmp(a->name, b->name);
950 char *pkg_version_str_alloc(pkg_t *pkg)
952 char *complete_version;
957 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
959 epoch_str = strdup("");
962 if (pkg->revision && strlen(pkg->revision)) {
963 sprintf_alloc(&revision_str, "-%s", pkg->revision);
965 revision_str = strdup("");
969 sprintf_alloc(&complete_version, "%s%s%s",
970 epoch_str, pkg->version, revision_str);
975 return complete_version;
978 str_list_t *pkg_get_installed_files(pkg_t *pkg)
981 char *list_file_name = NULL;
982 FILE *list_file = NULL;
984 char *installed_file_name;
987 pkg->installed_files_ref_cnt++;
989 if (pkg->installed_files) {
990 return pkg->installed_files;
993 pkg->installed_files = str_list_alloc();
994 if (pkg->installed_files == NULL) {
995 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
999 /* For uninstalled packages, get the file list directly from the package.
1000 For installed packages, look at the package.list file in the database.
1002 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1003 if (pkg->local_filename == NULL) {
1004 return pkg->installed_files;
1006 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1007 file. In other words, change deb_extract so that it can
1008 simply return the file list as a char *[] rather than
1009 insisting on writing in to a FILE * as it does now. */
1010 list_file = tmpfile();
1011 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1014 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1015 __FUNCTION__, pkg->local_filename, strerror(err));
1016 return pkg->installed_files;
1020 sprintf_alloc(&list_file_name, "%s/%s.list",
1021 pkg->dest->info_dir, pkg->name);
1022 if (! file_exists(list_file_name)) {
1023 free(list_file_name);
1024 return pkg->installed_files;
1027 list_file = fopen(list_file_name, "r");
1028 if (list_file == NULL) {
1029 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1030 list_file_name, strerror(errno));
1031 free(list_file_name);
1032 return pkg->installed_files;
1034 free(list_file_name);
1037 rootdirlen = strlen( pkg->dest->root_dir );
1041 line = file_read_line_alloc(list_file);
1048 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1049 if( strncmp( pkg->dest->root_dir,
1052 if (*file_name == '.') {
1055 if (*file_name == '/') {
1059 /* Freed in pkg_free_installed_files */
1060 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1062 // already contains root_dir as header -> ABSOLUTE
1063 sprintf_alloc(&installed_file_name, "%s", file_name);
1065 str_list_append(pkg->installed_files, installed_file_name);
1066 free(installed_file_name);
1072 return pkg->installed_files;
1075 /* XXX: CLEANUP: This function and it's counterpart,
1076 (pkg_get_installed_files), do not match our init/deinit naming
1077 convention. Nor the alloc/free convention. But, then again, neither
1078 of these conventions currrently fit the way these two functions
1080 int pkg_free_installed_files(pkg_t *pkg)
1082 pkg->installed_files_ref_cnt--;
1084 if (pkg->installed_files_ref_cnt > 0)
1087 if (pkg->installed_files) {
1088 str_list_purge(pkg->installed_files);
1091 pkg->installed_files = NULL;
1096 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1099 char *list_file_name;
1101 //I don't think pkg_free_installed_files should be called here. Jamey
1102 //pkg_free_installed_files(pkg);
1104 sprintf_alloc(&list_file_name, "%s/%s.list",
1105 pkg->dest->info_dir, pkg->name);
1106 if (!conf->noaction) {
1107 err = unlink(list_file_name);
1108 free(list_file_name);
1117 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1119 conffile_list_elt_t *iter;
1120 conffile_t *conffile;
1126 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1127 conffile = (conffile_t *)iter->data;
1129 if (strcmp(conffile->name, file_name) == 0) {
1137 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1138 const char *script, const char *args)
1144 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1145 maintainer script within a chroot environment. */
1147 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1148 have scripts in pkg->tmp_unpack_dir. */
1149 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1150 if (pkg->dest == NULL) {
1151 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1152 __FUNCTION__, pkg->name);
1155 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1157 if (pkg->tmp_unpack_dir == NULL) {
1158 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1159 __FUNCTION__, pkg->name);
1162 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1165 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1166 if (conf->noaction) return 0;
1168 /* XXX: CLEANUP: There must be a better way to handle maintainer
1169 scripts when running with offline_root mode and/or a dest other
1170 than '/'. I've been playing around with some clever chroot
1171 tricks and I might come up with something workable. */
1173 * Attempt to provide a restricted environment for offline operation
1174 * Need the following set as a minimum:
1175 * OPKG_OFFLINE_ROOT = absolute path to root dir
1176 * D = absolute path to root dir (for OE generated postinst)
1177 * PATH = something safe (a restricted set of utilities)
1180 bool AllowOfflineMode = false;
1181 if (conf->offline_root) {
1182 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1183 setenv("D", conf->offline_root, 1);
1184 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1185 setenv("PATH", "/dev/null", 1);
1187 setenv("PATH", conf->offline_root_path, 1);
1188 AllowOfflineMode = true;
1193 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1195 if (! file_exists(path)) {
1200 if (conf->offline_root && !AllowOfflineMode) {
1201 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1206 sprintf_alloc(&cmd, "%s %s", path, args);
1213 fprintf(stderr, "%s script returned status %d\n", script, err);
1220 char *pkg_state_want_to_str(pkg_state_want_t sw)
1224 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1225 if (pkg_state_want_map[i].value == sw) {
1226 return strdup(pkg_state_want_map[i].str);
1230 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1232 return strdup("<STATE_WANT_UNKNOWN>");
1235 pkg_state_want_t pkg_state_want_from_str(char *str)
1239 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1240 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1241 return pkg_state_want_map[i].value;
1245 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1250 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1253 int len = 3; /* ok\000 is minimum */
1256 /* clear the temporary flags before converting to string */
1257 sf &= SF_NONVOLATILE_FLAGS;
1260 return strdup("ok");
1263 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1264 if (sf & pkg_state_flag_map[i].value) {
1265 len += strlen(pkg_state_flag_map[i].str) + 1;
1269 if ( str == NULL ) {
1270 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1274 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1275 if (sf & pkg_state_flag_map[i].value) {
1276 strcat(str, pkg_state_flag_map[i].str);
1281 str[len-1] = 0; /* squash last comma */
1286 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1291 if (strcmp(str, "ok") == 0) {
1294 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1295 const char *sfname = pkg_state_flag_map[i].str;
1296 int sfname_len = strlen(sfname);
1297 if (strncmp(str, sfname, sfname_len) == 0) {
1298 sf |= pkg_state_flag_map[i].value;
1300 if (str[0] == ',') {
1311 char *pkg_state_status_to_str(pkg_state_status_t ss)
1315 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1316 if (pkg_state_status_map[i].value == ss) {
1317 return strdup(pkg_state_status_map[i].str);
1321 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1323 return strdup("<STATE_STATUS_UNKNOWN>");
1326 pkg_state_status_t pkg_state_status_from_str(const char *str)
1330 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1331 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1332 return pkg_state_status_map[i].value;
1336 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1338 return SS_NOT_INSTALLED;
1341 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1343 nv_pair_list_elt_t *l;
1345 if (!pkg->architecture)
1348 list_for_each_entry(l , &conf->arch_list.head, node) {
1349 nv_pair_t *nv = (nv_pair_t *)l->data;
1350 if (strcmp(nv->name, pkg->architecture) == 0) {
1351 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1356 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1360 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1362 nv_pair_list_elt_t *l;
1364 list_for_each_entry(l , &conf->arch_list.head, node) {
1365 nv_pair_t *nv = (nv_pair_t *)l->data;
1366 if (strcmp(nv->name, archname) == 0) {
1367 int priority = strtol(nv->value, NULL, 0);
1374 int pkg_info_preinstall_check(opkg_conf_t *conf)
1377 hash_table_t *pkg_hash = &conf->pkg_hash;
1378 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1379 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1381 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1382 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1383 /* update arch_priority for each package */
1384 for (i = 0; i < available_pkgs->len; i++) {
1385 pkg_t *pkg = available_pkgs->pkgs[i];
1386 int arch_priority = 1;
1389 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1390 if (pkg->architecture)
1391 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1393 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1394 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1395 pkg->arch_priority = arch_priority;
1398 for (i = 0; i < available_pkgs->len; i++) {
1399 pkg_t *pkg = available_pkgs->pkgs[i];
1400 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1401 /* clear flags and want for any uninstallable package */
1402 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1403 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1404 pkg->state_want = SW_UNKNOWN;
1405 pkg->state_flag = 0;
1408 pkg_vec_free(available_pkgs);
1410 /* update the file owner data structure */
1411 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1412 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1413 for (i = 0; i < installed_pkgs->len; i++) {
1414 pkg_t *pkg = installed_pkgs->pkgs[i];
1415 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1416 str_list_elt_t *iter, *niter;
1417 if (installed_files == NULL) {
1418 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1421 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1423 iter = niter, niter = str_list_next(installed_files, iter)) {
1424 char *installed_file = (char *) iter->data;
1425 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1426 file_hash_set_file_owner(conf, installed_file, pkg);
1428 pkg_free_installed_files(pkg);
1430 pkg_vec_free(installed_pkgs);
1435 struct pkg_write_filelist_data {
1441 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1443 struct pkg_write_filelist_data *data = data_;
1444 pkg_t *entry = entry_;
1445 if (entry == data->pkg) {
1446 fprintf(data->stream, "%s\n", key);
1450 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1452 struct pkg_write_filelist_data data;
1453 char *list_file_name = NULL;
1457 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1460 opkg_message(conf, OPKG_INFO,
1461 " creating %s.list file\n", pkg->name);
1462 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1463 if (!list_file_name) {
1464 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1467 opkg_message(conf, OPKG_INFO,
1468 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1469 data.stream = fopen(list_file_name, "w");
1471 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1472 list_file_name, strerror(errno));
1477 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1478 fclose(data.stream);
1479 free(list_file_name);
1481 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1486 int pkg_write_changed_filelists(opkg_conf_t *conf)
1488 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1489 hash_table_t *pkg_hash = &conf->pkg_hash;
1495 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1496 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1497 for (i = 0; i < installed_pkgs->len; i++) {
1498 pkg_t *pkg = installed_pkgs->pkgs[i];
1499 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1500 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1501 err = pkg_write_filelist(conf, pkg);
1503 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1506 pkg_vec_free (installed_pkgs);