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)
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 = read_raw_pkgs_from_stream(control_file);
301 pkg_parse_raw(pkg, &raw, NULL, NULL);
303 fclose(control_file);
308 /* Merge any new information in newpkg into oldpkg */
309 /* XXX: CLEANUP: This function shouldn't actually modify anything in
310 newpkg, but should leave it usable. This rework is so that
311 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
313 * uh, i thought that i had originally written this so that it took
314 * two pkgs and returned a new one? we can do that again... -sma
316 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
318 if (oldpkg == newpkg) {
323 oldpkg->src = newpkg->src;
325 oldpkg->dest = newpkg->dest;
326 if (!oldpkg->architecture)
327 oldpkg->architecture = str_dup_safe(newpkg->architecture);
328 if (!oldpkg->arch_priority)
329 oldpkg->arch_priority = newpkg->arch_priority;
330 if (!oldpkg->section)
331 oldpkg->section = str_dup_safe(newpkg->section);
332 if(!oldpkg->maintainer)
333 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
334 if(!oldpkg->description)
335 oldpkg->description = str_dup_safe(newpkg->description);
337 /* merge the state_flags from the new package */
338 oldpkg->state_want = newpkg->state_want;
339 oldpkg->state_status = newpkg->state_status;
340 oldpkg->state_flag = newpkg->state_flag;
342 if (oldpkg->state_want == SW_UNKNOWN)
343 oldpkg->state_want = newpkg->state_want;
344 if (oldpkg->state_status == SS_NOT_INSTALLED)
345 oldpkg->state_status = newpkg->state_status;
346 oldpkg->state_flag |= newpkg->state_flag;
349 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
350 oldpkg->depends_str = newpkg->depends_str;
351 newpkg->depends_str = NULL;
352 oldpkg->depends_count = newpkg->depends_count;
353 newpkg->depends_count = 0;
355 oldpkg->depends = newpkg->depends;
356 newpkg->depends = NULL;
358 oldpkg->pre_depends_str = newpkg->pre_depends_str;
359 newpkg->pre_depends_str = NULL;
360 oldpkg->pre_depends_count = newpkg->pre_depends_count;
361 newpkg->pre_depends_count = 0;
363 oldpkg->recommends_str = newpkg->recommends_str;
364 newpkg->recommends_str = NULL;
365 oldpkg->recommends_count = newpkg->recommends_count;
366 newpkg->recommends_count = 0;
368 oldpkg->suggests_str = newpkg->suggests_str;
369 newpkg->suggests_str = NULL;
370 oldpkg->suggests_count = newpkg->suggests_count;
371 newpkg->suggests_count = 0;
374 if (!oldpkg->provides_str) {
375 oldpkg->provides_str = newpkg->provides_str;
376 newpkg->provides_str = NULL;
377 oldpkg->provides_count = newpkg->provides_count;
378 newpkg->provides_count = 0;
380 oldpkg->provides = newpkg->provides;
381 newpkg->provides = NULL;
384 if (!oldpkg->conflicts_str) {
385 oldpkg->conflicts_str = newpkg->conflicts_str;
386 newpkg->conflicts_str = NULL;
387 oldpkg->conflicts_count = newpkg->conflicts_count;
388 newpkg->conflicts_count = 0;
390 oldpkg->conflicts = newpkg->conflicts;
391 newpkg->conflicts = NULL;
394 if (!oldpkg->replaces_str) {
395 oldpkg->replaces_str = newpkg->replaces_str;
396 newpkg->replaces_str = NULL;
397 oldpkg->replaces_count = newpkg->replaces_count;
398 newpkg->replaces_count = 0;
400 oldpkg->replaces = newpkg->replaces;
401 newpkg->replaces = NULL;
404 if (!oldpkg->filename)
405 oldpkg->filename = str_dup_safe(newpkg->filename);
407 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
408 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
409 if (!oldpkg->local_filename)
410 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
411 if (!oldpkg->tmp_unpack_dir)
412 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
414 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
415 #if defined HAVE_SHA256
416 if (!oldpkg->sha256sum)
417 oldpkg->sha256sum = str_dup_safe(newpkg->sha256sum);
420 oldpkg->size = str_dup_safe(newpkg->size);
421 if (!oldpkg->installed_size)
422 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
423 if (!oldpkg->priority)
424 oldpkg->priority = str_dup_safe(newpkg->priority);
426 oldpkg->source = str_dup_safe(newpkg->source);
427 if (nv_pair_list_empty(&oldpkg->conffiles)){
428 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
429 conffile_list_init(&newpkg->conffiles);
431 if (!oldpkg->installed_files){
432 oldpkg->installed_files = newpkg->installed_files;
433 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
434 newpkg->installed_files = NULL;
436 if (!oldpkg->essential)
437 oldpkg->essential = newpkg->essential;
442 abstract_pkg_t *abstract_pkg_new(void)
444 abstract_pkg_t * ab_pkg;
446 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
448 if (ab_pkg == NULL) {
449 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
453 if ( abstract_pkg_init(ab_pkg) < 0 )
459 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
461 ab_pkg->provided_by = abstract_pkg_vec_alloc();
462 if (ab_pkg->provided_by==NULL){
465 ab_pkg->dependencies_checked = 0;
466 ab_pkg->state_status = SS_NOT_INSTALLED;
471 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
474 char **raw_start=NULL;
476 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
477 temp_str = (char *) alloca (str_size);
478 memset(temp_str, 0 , str_size);
480 if (temp_str == NULL ){
481 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
484 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
486 raw = raw_start = read_raw_pkgs_from_file(temp_str);
488 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
493 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
494 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
509 #define CHECK_BUFF_SIZE(buff, line, buf_size, page_size) do { \
510 if (strlen(buff) + strlen(line) >= (buf_size)) { \
511 buf_size += page_size; \
512 buff = realloc(buff, buf_size); \
515 char * pkg_formatted_info(pkg_t *pkg )
519 const size_t page_size = 8192;
520 size_t buff_size = page_size;
522 buff = calloc(1, buff_size);
524 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
528 line = pkg_formatted_field(pkg, "Package");
529 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
530 strncat(buff ,line, strlen(line));
533 line = pkg_formatted_field(pkg, "Version");
534 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
535 strncat(buff ,line, strlen(line));
538 line = pkg_formatted_field(pkg, "Depends");
539 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
540 strncat(buff ,line, strlen(line));
543 line = pkg_formatted_field(pkg, "Recommends");
544 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
545 strncat(buff ,line, strlen(line));
548 line = pkg_formatted_field(pkg, "Suggests");
549 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
550 strncat(buff ,line, strlen(line));
553 line = pkg_formatted_field(pkg, "Provides");
554 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
555 strncat(buff ,line, strlen(line));
558 line = pkg_formatted_field(pkg, "Replaces");
559 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
560 strncat(buff ,line, strlen(line));
563 line = pkg_formatted_field(pkg, "Conflicts");
564 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
565 strncat(buff ,line, strlen(line));
568 line = pkg_formatted_field(pkg, "Status");
569 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
570 strncat(buff ,line, strlen(line));
573 line = pkg_formatted_field(pkg, "Section");
574 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
575 strncat(buff ,line, strlen(line));
578 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
579 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
580 strncat(buff ,line, strlen(line));
583 line = pkg_formatted_field(pkg, "Architecture");
584 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
585 strncat(buff ,line, strlen(line));
588 line = pkg_formatted_field(pkg, "Maintainer");
589 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
590 strncat(buff ,line, strlen(line));
593 line = pkg_formatted_field(pkg, "MD5sum");
594 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
595 strncat(buff ,line, strlen(line));
598 line = pkg_formatted_field(pkg, "Size");
599 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
600 strncat(buff ,line, strlen(line));
603 line = pkg_formatted_field(pkg, "Filename");
604 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
605 strncat(buff ,line, strlen(line));
608 line = pkg_formatted_field(pkg, "Conffiles");
609 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
610 strncat(buff ,line, strlen(line));
613 line = pkg_formatted_field(pkg, "Source");
614 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
615 strncat(buff ,line, strlen(line));
618 line = pkg_formatted_field(pkg, "Description");
619 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
620 strncat(buff ,line, strlen(line));
623 line = pkg_formatted_field(pkg, "Installed-Time");
624 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
625 strncat(buff ,line, strlen(line));
628 line = pkg_formatted_field(pkg, "Tags");
629 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
630 strncat(buff ,line, strlen(line));
636 char * pkg_formatted_field(pkg_t *pkg, const char *field )
638 static size_t LINE_LEN = 128;
639 char * temp = (char *)malloc(1);
641 int flag_provide_false = 0;
644 Pigi: After some discussion with Florian we decided to modify the full procedure in
645 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
648 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
649 goto UNKNOWN_FMT_FIELD;
658 if (strcasecmp(field, "Architecture") == 0) {
660 if (pkg->architecture) {
661 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
663 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
667 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
669 } else if (strcasecmp(field, "Auto-Installed") == 0) {
670 /* Auto-Installed flag */
671 if (pkg->auto_installed) {
672 char * s = "Auto-Installed: yes\n";
673 temp = (char *)realloc(temp, strlen(s) + 1);
677 goto UNKNOWN_FMT_FIELD;
682 if (strcasecmp(field, "Conffiles") == 0) {
684 conffile_list_elt_t *iter;
685 char confstr[LINE_LEN];
687 if (nv_pair_list_empty(&pkg->conffiles)) {
692 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
693 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
694 len = len + (strlen(((conffile_t *)iter->data)->name)+strlen(((conffile_t *)iter->data)->value)+5);
697 temp = (char *)realloc(temp,len);
699 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
703 strncpy(temp, "Conffiles:\n", 12);
704 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
705 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
706 snprintf(confstr, LINE_LEN, "%s %s\n",
707 ((conffile_t *)iter->data)->name,
708 ((conffile_t *)iter->data)->value);
709 strncat(temp, confstr, strlen(confstr));
712 } else if (strcasecmp(field, "Conflicts") == 0) {
715 if (pkg->conflicts_count) {
716 char conflictstr[LINE_LEN];
718 for(i = 0; i < pkg->conflicts_count; i++) {
719 len = len + (strlen(pkg->conflicts_str[i])+5);
721 temp = (char *)realloc(temp,len);
723 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
727 strncpy(temp, "Conflicts:", 11);
728 for(i = 0; i < pkg->conflicts_count; i++) {
729 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
730 strncat(temp, conflictstr, strlen(conflictstr));
732 strncat(temp, "\n", strlen("\n"));
735 goto UNKNOWN_FMT_FIELD;
740 if (strcasecmp(field, "Depends") == 0) {
744 if (pkg->depends_count) {
745 char depstr[LINE_LEN];
747 for(i = 0; i < pkg->depends_count; i++) {
748 len = len + (strlen(pkg->depends_str[i])+4);
750 temp = (char *)realloc(temp,len);
752 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
756 strncpy(temp, "Depends:", 10);
757 for(i = 0; i < pkg->depends_count; i++) {
758 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
759 strncat(temp, depstr, strlen(depstr));
761 strncat(temp, "\n", strlen("\n"));
763 } else if (strcasecmp(field, "Description") == 0) {
765 if (pkg->description) {
766 temp = (char *)realloc(temp,strlen(pkg->description)+16);
768 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
772 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
775 goto UNKNOWN_FMT_FIELD;
781 if (pkg->essential) {
782 temp = (char *)realloc(temp,16);
784 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
788 snprintf(temp, (16), "Essential: yes\n");
796 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
798 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
802 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
808 if (strcasecmp(field, "Installed-Size") == 0) {
810 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
812 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
816 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
817 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
818 temp = (char *)realloc(temp,29);
820 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
824 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
830 /* Maintainer | MD5sum */
831 if (strcasecmp(field, "Maintainer") == 0) {
833 if (pkg->maintainer) {
834 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
836 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
840 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
842 } else if (strcasecmp(field, "MD5sum") == 0) {
845 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
847 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
851 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
854 goto UNKNOWN_FMT_FIELD;
860 if (strcasecmp(field, "Package") == 0) {
862 temp = (char *)realloc(temp,strlen(pkg->name)+11);
864 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
868 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
869 } else if (strcasecmp(field, "Priority") == 0) {
871 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
873 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
877 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
878 } else if (strcasecmp(field, "Provides") == 0) {
882 if (pkg->provides_count) {
883 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
884 for ( i=0; i < pkg->provides_count; i++ ){
885 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
886 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
887 flag_provide_false = 1;
890 if ( !flag_provide_false || /* Pigi there is not my trick flag */
891 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
892 char provstr[LINE_LEN];
894 for(i = 0; i < pkg->provides_count; i++) {
895 len = len + (strlen(pkg->provides_str[i])+5);
897 temp = (char *)realloc(temp,len);
899 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
903 strncpy(temp, "Provides:", 12);
904 for(i = 0; i < pkg->provides_count; i++) {
905 if (strlen(pkg->provides_str[i])>0){;
906 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
907 strncat(temp, provstr, strlen(provstr));
910 strncat(temp, "\n", strlen("\n"));
914 goto UNKNOWN_FMT_FIELD;
921 /* Replaces | Recommends*/
922 if (strcasecmp (field, "Replaces") == 0) {
923 if (pkg->replaces_count) {
924 char replstr[LINE_LEN];
926 for (i = 0; i < pkg->replaces_count; i++) {
927 len = len + (strlen(pkg->replaces_str[i])+5);
929 temp = (char *)realloc(temp,len);
931 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
935 strncpy(temp, "Replaces:", 12);
936 for (i = 0; i < pkg->replaces_count; i++) {
937 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
938 strncat(temp, replstr, strlen(replstr));
940 strncat(temp, "\n", strlen("\n"));
942 } else if (strcasecmp (field, "Recommends") == 0) {
943 if (pkg->recommends_count) {
944 char recstr[LINE_LEN];
946 for(i = 0; i < pkg->recommends_count; i++) {
947 len = len + (strlen( pkg->recommends_str[i])+5);
949 temp = (char *)realloc(temp,len);
951 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
955 strncpy(temp, "Recommends:", 13);
956 for(i = 0; i < pkg->recommends_count; i++) {
957 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
958 strncat(temp, recstr, strlen(recstr));
960 strncat(temp, "\n", strlen("\n"));
963 goto UNKNOWN_FMT_FIELD;
969 /* Section | SHA256sum | Size | Source | Status | Suggests */
970 if (strcasecmp(field, "Section") == 0) {
973 temp = (char *)realloc(temp,strlen(pkg->section)+11);
975 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
979 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
981 #if defined HAVE_SHA256
982 } else if (strcasecmp(field, "SHA256sum") == 0) {
984 if (pkg->sha256sum) {
985 temp = (char *)realloc(temp,strlen(pkg->sha256sum)+13);
987 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
991 snprintf(temp, (strlen(pkg->sha256sum)+13), "SHA256sum: %s\n", pkg->sha256sum);
994 } else if (strcasecmp(field, "Size") == 0) {
997 temp = (char *)realloc(temp,strlen(pkg->size)+8);
999 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1003 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
1005 } else if (strcasecmp(field, "Source") == 0) {
1008 temp = (char *)realloc(temp,strlen(pkg->source)+10);
1009 if ( temp == NULL ){
1010 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1014 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
1016 } else if (strcasecmp(field, "Status") == 0) {
1018 /* Benjamin Pineau note: we should avoid direct usage of
1019 * strlen(arg) without keeping "arg" for later free()
1021 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
1022 char *pstat=pkg_state_status_to_str(pkg->state_status);
1023 char *pwant=pkg_state_want_to_str(pkg->state_want);
1025 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
1026 temp = (char *)realloc(temp,sum_of_sizes);
1027 if ( temp == NULL ){
1028 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1032 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
1035 if(pstat) /* pfstat can be NULL if ENOMEM */
1037 } else if (strcasecmp(field, "Suggests") == 0) {
1038 if (pkg->suggests_count) {
1040 char sugstr[LINE_LEN];
1042 for(i = 0; i < pkg->suggests_count; i++) {
1043 len = len + (strlen(pkg->suggests_str[i])+5);
1045 temp = (char *)realloc(temp,len);
1046 if ( temp == NULL ){
1047 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1051 strncpy(temp, "Suggests:", 10);
1052 for(i = 0; i < pkg->suggests_count; i++) {
1053 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
1054 strncat(temp, sugstr, strlen(sugstr));
1056 strncat(temp, "\n", strlen("\n"));
1059 goto UNKNOWN_FMT_FIELD;
1065 if (strcasecmp(field, "Tags") == 0) {
1068 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1069 if ( temp == NULL ){
1070 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1074 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1081 char *version = pkg_version_str_alloc(pkg);
1082 temp = (char *)realloc(temp,strlen(version)+14);
1083 if ( temp == NULL ){
1084 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1088 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1093 goto UNKNOWN_FMT_FIELD;
1096 if ( strlen(temp)<2 ) {
1102 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1103 if ( strlen(temp)<2 ) {
1110 void pkg_print_info(pkg_t *pkg, FILE *file)
1118 buff = pkg_formatted_info(pkg);
1121 if (strlen(buff)>2){
1122 t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
1127 void pkg_print_status(pkg_t * pkg, FILE * file)
1133 /* XXX: QUESTION: Do we actually want more fields here? The
1134 original idea was to save space by installing only what was
1135 needed for actual computation, (package, version, status,
1136 essential, conffiles). The assumption is that all other fields
1137 can be found in th available file.
1139 But, someone proposed the idea to make it possible to
1140 reconstruct a .opk from an installed package, (ie. for beaming
1141 from one handheld to another). So, maybe we actually want a few
1142 more fields here, (depends, suggests, etc.), so that that would
1143 be guaranteed to work even in the absence of more information
1144 from the available file.
1146 28-MAR-03: kergoth and I discussed this yesterday. We think
1147 the essential info needs to be here for all installed packages
1148 because they may not appear in the Packages files on various
1149 feeds. Furthermore, one should be able to install from URL or
1150 local storage without requiring a Packages file from any feed.
1153 pkg_print_field(pkg, file, "Package");
1154 pkg_print_field(pkg, file, "Version");
1155 pkg_print_field(pkg, file, "Depends");
1156 pkg_print_field(pkg, file, "Recommends");
1157 pkg_print_field(pkg, file, "Suggests");
1158 pkg_print_field(pkg, file, "Provides");
1159 pkg_print_field(pkg, file, "Replaces");
1160 pkg_print_field(pkg, file, "Conflicts");
1161 pkg_print_field(pkg, file, "Status");
1162 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1163 pkg_print_field(pkg, file, "Architecture");
1164 pkg_print_field(pkg, file, "Conffiles");
1165 pkg_print_field(pkg, file, "Installed-Time");
1166 pkg_print_field(pkg, file, "Auto-Installed");
1170 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1173 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1174 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1175 __FUNCTION__, field);
1177 buff = pkg_formatted_field(pkg, field);
1178 if (strlen(buff)>2) {
1179 fprintf(file, "%s", buff);
1187 * libdpkg - Debian packaging suite library routines
1188 * vercmp.c - comparison of version numbers
1190 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1192 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1196 if (pkg->epoch > ref_pkg->epoch) {
1200 if (pkg->epoch < ref_pkg->epoch) {
1204 r = verrevcmp(pkg->version, ref_pkg->version);
1209 r = verrevcmp(pkg->revision, ref_pkg->revision);
1217 /* assume ascii; warning: evaluates x multiple times! */
1218 #define order(x) ((x) == '~' ? -1 \
1219 : isdigit((x)) ? 0 \
1221 : isalpha((x)) ? (x) \
1224 static int verrevcmp(const char *val, const char *ref) {
1228 while (*val || *ref) {
1231 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1232 int vc= order(*val), rc= order(*ref);
1233 if (vc != rc) return vc - rc;
1237 while ( *val == '0' ) val++;
1238 while ( *ref == '0' ) ref++;
1239 while (isdigit(*val) && isdigit(*ref)) {
1240 if (!first_diff) first_diff= *val - *ref;
1243 if (isdigit(*val)) return 1;
1244 if (isdigit(*ref)) return -1;
1245 if (first_diff) return first_diff;
1250 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1254 r = pkg_compare_versions(it, ref);
1256 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1260 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1264 if (strcmp(op, "<<") == 0) {
1268 if (strcmp(op, ">>") == 0) {
1272 if (strcmp(op, "=") == 0) {
1276 fprintf(stderr, "unknown operator: %s", op);
1280 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1282 const pkg_t *a = *(const pkg_t**) p1;
1283 const pkg_t *b = *(const pkg_t**) p2;
1286 if (!a->name || !b->name) {
1287 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1288 a, a->name, b, b->name);
1292 namecmp = strcmp(a->name, b->name);
1295 vercmp = pkg_compare_versions(a, b);
1298 if (!a->arch_priority || !b->arch_priority) {
1299 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1300 a, a->arch_priority, b, b->arch_priority);
1303 if (a->arch_priority > b->arch_priority)
1305 if (a->arch_priority < b->arch_priority)
1310 int abstract_pkg_name_compare(const void *p1, const void *p2)
1312 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1313 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1314 if (!a->name || !b->name) {
1315 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1316 a, a->name, b, b->name);
1319 return strcmp(a->name, b->name);
1323 char *pkg_version_str_alloc(pkg_t *pkg)
1325 char *complete_version;
1330 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1332 epoch_str = strdup("");
1335 if (pkg->revision && strlen(pkg->revision)) {
1336 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1338 revision_str = strdup("");
1342 sprintf_alloc(&complete_version, "%s%s%s",
1343 epoch_str, pkg->version, revision_str);
1348 return complete_version;
1351 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1354 char *list_file_name = NULL;
1355 FILE *list_file = NULL;
1357 char *installed_file_name;
1360 pkg->installed_files_ref_cnt++;
1362 if (pkg->installed_files) {
1363 return pkg->installed_files;
1366 pkg->installed_files = str_list_alloc();
1367 if (pkg->installed_files == NULL) {
1368 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1372 /* For uninstalled packages, get the file list directly from the package.
1373 For installed packages, look at the package.list file in the database.
1375 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1376 if (pkg->local_filename == NULL) {
1377 return pkg->installed_files;
1379 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1380 file. In other words, change deb_extract so that it can
1381 simply return the file list as a char *[] rather than
1382 insisting on writing in to a FILE * as it does now. */
1383 list_file = tmpfile();
1384 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1387 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1388 __FUNCTION__, pkg->local_filename, strerror(err));
1389 return pkg->installed_files;
1393 sprintf_alloc(&list_file_name, "%s/%s.list",
1394 pkg->dest->info_dir, pkg->name);
1395 if (! file_exists(list_file_name)) {
1396 free(list_file_name);
1397 return pkg->installed_files;
1400 list_file = fopen(list_file_name, "r");
1401 if (list_file == NULL) {
1402 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1403 list_file_name, strerror(errno));
1404 free(list_file_name);
1405 return pkg->installed_files;
1407 free(list_file_name);
1410 rootdirlen = strlen( pkg->dest->root_dir );
1414 line = file_read_line_alloc(list_file);
1421 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1422 if( strncmp( pkg->dest->root_dir,
1425 if (*file_name == '.') {
1428 if (*file_name == '/') {
1432 /* Freed in pkg_free_installed_files */
1433 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1435 // already contains root_dir as header -> ABSOLUTE
1436 sprintf_alloc(&installed_file_name, "%s", file_name);
1438 str_list_append(pkg->installed_files, installed_file_name);
1439 free(installed_file_name);
1445 return pkg->installed_files;
1448 /* XXX: CLEANUP: This function and it's counterpart,
1449 (pkg_get_installed_files), do not match our init/deinit naming
1450 convention. Nor the alloc/free convention. But, then again, neither
1451 of these conventions currrently fit the way these two functions
1453 int pkg_free_installed_files(pkg_t *pkg)
1455 pkg->installed_files_ref_cnt--;
1457 if (pkg->installed_files_ref_cnt > 0)
1460 if (pkg->installed_files) {
1461 str_list_purge(pkg->installed_files);
1464 pkg->installed_files = NULL;
1469 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1472 char *list_file_name;
1474 //I don't think pkg_free_installed_files should be called here. Jamey
1475 //pkg_free_installed_files(pkg);
1477 sprintf_alloc(&list_file_name, "%s/%s.list",
1478 pkg->dest->info_dir, pkg->name);
1479 if (!conf->noaction) {
1480 err = unlink(list_file_name);
1481 free(list_file_name);
1490 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1492 conffile_list_elt_t *iter;
1493 conffile_t *conffile;
1499 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1500 conffile = (conffile_t *)iter->data;
1502 if (strcmp(conffile->name, file_name) == 0) {
1510 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1511 const char *script, const char *args)
1517 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1518 maintainer script within a chroot environment. */
1520 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1521 have scripts in pkg->tmp_unpack_dir. */
1522 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1523 if (pkg->dest == NULL) {
1524 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1525 __FUNCTION__, pkg->name);
1528 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1530 if (pkg->tmp_unpack_dir == NULL) {
1531 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1532 __FUNCTION__, pkg->name);
1535 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1538 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1539 if (conf->noaction) return 0;
1541 /* XXX: CLEANUP: There must be a better way to handle maintainer
1542 scripts when running with offline_root mode and/or a dest other
1543 than '/'. I've been playing around with some clever chroot
1544 tricks and I might come up with something workable. */
1546 * Attempt to provide a restricted environment for offline operation
1547 * Need the following set as a minimum:
1548 * OPKG_OFFLINE_ROOT = absolute path to root dir
1549 * D = absolute path to root dir (for OE generated postinst)
1550 * PATH = something safe (a restricted set of utilities)
1553 bool AllowOfflineMode = false;
1554 if (conf->offline_root) {
1555 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1556 setenv("D", conf->offline_root, 1);
1557 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1558 setenv("PATH", "/dev/null", 1);
1560 setenv("PATH", conf->offline_root_path, 1);
1561 AllowOfflineMode = true;
1566 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1568 if (! file_exists(path)) {
1573 if (conf->offline_root && !AllowOfflineMode) {
1574 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1579 sprintf_alloc(&cmd, "%s %s", path, args);
1586 fprintf(stderr, "%s script returned status %d\n", script, err);
1593 char *pkg_state_want_to_str(pkg_state_want_t sw)
1597 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1598 if (pkg_state_want_map[i].value == sw) {
1599 return strdup(pkg_state_want_map[i].str);
1603 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1605 return strdup("<STATE_WANT_UNKNOWN>");
1608 pkg_state_want_t pkg_state_want_from_str(char *str)
1612 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1613 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1614 return pkg_state_want_map[i].value;
1618 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1623 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1626 int len = 3; /* ok\000 is minimum */
1629 /* clear the temporary flags before converting to string */
1630 sf &= SF_NONVOLATILE_FLAGS;
1633 return strdup("ok");
1636 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1637 if (sf & pkg_state_flag_map[i].value) {
1638 len += strlen(pkg_state_flag_map[i].str) + 1;
1642 if ( str == NULL ) {
1643 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1647 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1648 if (sf & pkg_state_flag_map[i].value) {
1649 strcat(str, pkg_state_flag_map[i].str);
1654 str[len-1] = 0; /* squash last comma */
1659 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1664 if (strcmp(str, "ok") == 0) {
1667 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1668 const char *sfname = pkg_state_flag_map[i].str;
1669 int sfname_len = strlen(sfname);
1670 if (strncmp(str, sfname, sfname_len) == 0) {
1671 sf |= pkg_state_flag_map[i].value;
1673 if (str[0] == ',') {
1684 char *pkg_state_status_to_str(pkg_state_status_t ss)
1688 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1689 if (pkg_state_status_map[i].value == ss) {
1690 return strdup(pkg_state_status_map[i].str);
1694 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1696 return strdup("<STATE_STATUS_UNKNOWN>");
1699 pkg_state_status_t pkg_state_status_from_str(const char *str)
1703 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1704 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1705 return pkg_state_status_map[i].value;
1709 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1711 return SS_NOT_INSTALLED;
1714 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1716 nv_pair_list_elt_t *l;
1718 if (!pkg->architecture)
1721 list_for_each_entry(l , &conf->arch_list.head, node) {
1722 nv_pair_t *nv = (nv_pair_t *)l->data;
1723 if (strcmp(nv->name, pkg->architecture) == 0) {
1724 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1729 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1733 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1735 nv_pair_list_elt_t *l;
1737 list_for_each_entry(l , &conf->arch_list.head, node) {
1738 nv_pair_t *nv = (nv_pair_t *)l->data;
1739 if (strcmp(nv->name, archname) == 0) {
1740 int priority = strtol(nv->value, NULL, 0);
1747 int pkg_info_preinstall_check(opkg_conf_t *conf)
1750 hash_table_t *pkg_hash = &conf->pkg_hash;
1751 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1752 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1754 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1755 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1756 /* update arch_priority for each package */
1757 for (i = 0; i < available_pkgs->len; i++) {
1758 pkg_t *pkg = available_pkgs->pkgs[i];
1759 int arch_priority = 1;
1762 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1763 if (pkg->architecture)
1764 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1766 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1767 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1768 pkg->arch_priority = arch_priority;
1771 for (i = 0; i < available_pkgs->len; i++) {
1772 pkg_t *pkg = available_pkgs->pkgs[i];
1773 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1774 /* clear flags and want for any uninstallable package */
1775 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1776 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1777 pkg->state_want = SW_UNKNOWN;
1778 pkg->state_flag = 0;
1781 pkg_vec_free(available_pkgs);
1783 /* update the file owner data structure */
1784 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1785 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1786 for (i = 0; i < installed_pkgs->len; i++) {
1787 pkg_t *pkg = installed_pkgs->pkgs[i];
1788 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1789 str_list_elt_t *iter, *niter;
1790 if (installed_files == NULL) {
1791 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1794 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1796 iter = niter, niter = str_list_next(installed_files, iter)) {
1797 char *installed_file = (char *) iter->data;
1798 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1799 file_hash_set_file_owner(conf, installed_file, pkg);
1801 pkg_free_installed_files(pkg);
1803 pkg_vec_free(installed_pkgs);
1808 struct pkg_write_filelist_data {
1814 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1816 struct pkg_write_filelist_data *data = data_;
1817 pkg_t *entry = entry_;
1818 if (entry == data->pkg) {
1819 fprintf(data->stream, "%s\n", key);
1823 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1825 struct pkg_write_filelist_data data;
1826 char *list_file_name = NULL;
1830 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1833 opkg_message(conf, OPKG_INFO,
1834 " creating %s.list file\n", pkg->name);
1835 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1836 if (!list_file_name) {
1837 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1840 opkg_message(conf, OPKG_INFO,
1841 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1842 data.stream = fopen(list_file_name, "w");
1844 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1845 list_file_name, strerror(errno));
1850 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1851 fclose(data.stream);
1852 free(list_file_name);
1854 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1859 int pkg_write_changed_filelists(opkg_conf_t *conf)
1861 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1862 hash_table_t *pkg_hash = &conf->pkg_hash;
1868 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1869 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1870 for (i = 0; i < installed_pkgs->len; i++) {
1871 pkg_t *pkg = installed_pkgs->pkgs[i];
1872 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1873 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1874 err = pkg_write_filelist(conf, pkg);
1876 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1879 pkg_vec_free (installed_pkgs);