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;
135 pkg->installed_size = NULL;
136 pkg->priority = NULL;
138 conffile_list_init(&pkg->conffiles);
139 pkg->installed_files = NULL;
140 pkg->installed_files_ref_cnt = 0;
142 pkg->provided_by_hand = 0;
147 void compound_depend_deinit (compound_depend_t *depends)
150 for (i = 0; i < depends->possibility_count; i++)
153 d = depends->possibilities[i];
157 free (depends->possibilities);
160 void pkg_deinit(pkg_t *pkg)
169 /* revision shares storage with version, so
171 pkg->revision = NULL;
172 /* owned by opkg_conf_t */
174 /* owned by opkg_conf_t */
176 free(pkg->architecture);
177 pkg->architecture = NULL;
178 free(pkg->maintainer);
179 pkg->maintainer = NULL;
182 free(pkg->description);
183 pkg->description = NULL;
184 pkg->state_want = SW_UNKNOWN;
185 pkg->state_flag = SF_OK;
186 pkg->state_status = SS_NOT_INSTALLED;
188 active_list_clear(&pkg->list);
190 free (pkg->replaces);
191 pkg->replaces = NULL;
193 for (i = 0; i < pkg->depends_count; i++)
194 free (pkg->depends_str[i]);
195 free(pkg->depends_str);
196 pkg->depends_str = NULL;
198 for (i = 0; i < pkg->provides_count; i++)
199 free (pkg->provides_str[i]);
200 free(pkg->provides_str);
201 pkg->provides_str = NULL;
203 for (i = 0; i < pkg->conflicts_count; i++)
204 free (pkg->conflicts_str[i]);
205 free(pkg->conflicts_str);
206 pkg->conflicts_str = NULL;
208 for (i = 0; i < pkg->replaces_count; i++)
209 free (pkg->replaces_str[i]);
210 free(pkg->replaces_str);
211 pkg->replaces_str = NULL;
213 for (i = 0; i < pkg->recommends_count; i++)
214 free (pkg->recommends_str[i]);
215 free(pkg->recommends_str);
216 pkg->recommends_str = NULL;
218 for (i = 0; i < pkg->suggests_count; i++)
219 free (pkg->suggests_str[i]);
220 free(pkg->suggests_str);
221 pkg->suggests_str = NULL;
225 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
228 for (x = 0; x < count; x++)
229 compound_depend_deinit (&pkg->depends[x]);
236 for (x = 0; x < pkg->conflicts_count; x++)
237 compound_depend_deinit (&pkg->conflicts[x]);
238 free (pkg->conflicts);
241 free (pkg->provides);
243 pkg->pre_depends_count = 0;
244 free(pkg->pre_depends_str);
245 pkg->pre_depends_str = NULL;
246 pkg->provides_count = 0;
248 pkg->filename = NULL;
249 free(pkg->local_filename);
250 pkg->local_filename = NULL;
251 /* CLEANUP: It'd be nice to pullin the cleanup function from
252 opkg_install.c here. See comment in
253 opkg_install.c:cleanup_temporary_files */
254 free(pkg->tmp_unpack_dir);
255 pkg->tmp_unpack_dir = NULL;
260 free(pkg->installed_size);
261 pkg->installed_size = NULL;
263 pkg->priority = NULL;
266 conffile_list_deinit(&pkg->conffiles);
267 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
268 since if they are calling deinit, they should know. Maybe do an
269 assertion here instead? */
270 pkg->installed_files_ref_cnt = 1;
271 pkg_free_installed_files(pkg);
277 int pkg_init_from_file(pkg_t *pkg, const char *filename)
284 if (err) { return err; }
286 pkg->local_filename = strdup(filename);
288 control_file = tmpfile();
289 err = pkg_extract_control_file_to_stream(pkg, control_file);
290 if (err) { return err; }
292 rewind(control_file);
293 raw = read_raw_pkgs_from_stream(control_file);
294 pkg_parse_raw(pkg, &raw, NULL, NULL);
296 fclose(control_file);
301 /* Merge any new information in newpkg into oldpkg */
302 /* XXX: CLEANUP: This function shouldn't actually modify anything in
303 newpkg, but should leave it usable. This rework is so that
304 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
306 * uh, i thought that i had originally written this so that it took
307 * two pkgs and returned a new one? we can do that again... -sma
309 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
311 if (oldpkg == newpkg) {
316 oldpkg->src = newpkg->src;
318 oldpkg->dest = newpkg->dest;
319 if (!oldpkg->architecture)
320 oldpkg->architecture = str_dup_safe(newpkg->architecture);
321 if (!oldpkg->arch_priority)
322 oldpkg->arch_priority = newpkg->arch_priority;
323 if (!oldpkg->section)
324 oldpkg->section = str_dup_safe(newpkg->section);
325 if(!oldpkg->maintainer)
326 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
327 if(!oldpkg->description)
328 oldpkg->description = str_dup_safe(newpkg->description);
330 /* merge the state_flags from the new package */
331 oldpkg->state_want = newpkg->state_want;
332 oldpkg->state_status = newpkg->state_status;
333 oldpkg->state_flag = newpkg->state_flag;
335 if (oldpkg->state_want == SW_UNKNOWN)
336 oldpkg->state_want = newpkg->state_want;
337 if (oldpkg->state_status == SS_NOT_INSTALLED)
338 oldpkg->state_status = newpkg->state_status;
339 oldpkg->state_flag |= newpkg->state_flag;
342 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
343 oldpkg->depends_str = newpkg->depends_str;
344 newpkg->depends_str = NULL;
345 oldpkg->depends_count = newpkg->depends_count;
346 newpkg->depends_count = 0;
348 oldpkg->depends = newpkg->depends;
349 newpkg->depends = NULL;
351 oldpkg->pre_depends_str = newpkg->pre_depends_str;
352 newpkg->pre_depends_str = NULL;
353 oldpkg->pre_depends_count = newpkg->pre_depends_count;
354 newpkg->pre_depends_count = 0;
356 oldpkg->recommends_str = newpkg->recommends_str;
357 newpkg->recommends_str = NULL;
358 oldpkg->recommends_count = newpkg->recommends_count;
359 newpkg->recommends_count = 0;
361 oldpkg->suggests_str = newpkg->suggests_str;
362 newpkg->suggests_str = NULL;
363 oldpkg->suggests_count = newpkg->suggests_count;
364 newpkg->suggests_count = 0;
367 if (!oldpkg->provides_str) {
368 oldpkg->provides_str = newpkg->provides_str;
369 newpkg->provides_str = NULL;
370 oldpkg->provides_count = newpkg->provides_count;
371 newpkg->provides_count = 0;
373 oldpkg->provides = newpkg->provides;
374 newpkg->provides = NULL;
377 if (!oldpkg->conflicts_str) {
378 oldpkg->conflicts_str = newpkg->conflicts_str;
379 newpkg->conflicts_str = NULL;
380 oldpkg->conflicts_count = newpkg->conflicts_count;
381 newpkg->conflicts_count = 0;
383 oldpkg->conflicts = newpkg->conflicts;
384 newpkg->conflicts = NULL;
387 if (!oldpkg->replaces_str) {
388 oldpkg->replaces_str = newpkg->replaces_str;
389 newpkg->replaces_str = NULL;
390 oldpkg->replaces_count = newpkg->replaces_count;
391 newpkg->replaces_count = 0;
393 oldpkg->replaces = newpkg->replaces;
394 newpkg->replaces = NULL;
397 if (!oldpkg->filename)
398 oldpkg->filename = str_dup_safe(newpkg->filename);
400 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
401 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
402 if (!oldpkg->local_filename)
403 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
404 if (!oldpkg->tmp_unpack_dir)
405 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
407 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
409 oldpkg->size = str_dup_safe(newpkg->size);
410 if (!oldpkg->installed_size)
411 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
412 if (!oldpkg->priority)
413 oldpkg->priority = str_dup_safe(newpkg->priority);
415 oldpkg->source = str_dup_safe(newpkg->source);
416 if (nv_pair_list_empty(&oldpkg->conffiles)){
417 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
418 conffile_list_init(&newpkg->conffiles);
420 if (!oldpkg->installed_files){
421 oldpkg->installed_files = newpkg->installed_files;
422 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
423 newpkg->installed_files = NULL;
425 if (!oldpkg->essential)
426 oldpkg->essential = newpkg->essential;
431 abstract_pkg_t *abstract_pkg_new(void)
433 abstract_pkg_t * ab_pkg;
435 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
437 if (ab_pkg == NULL) {
438 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
442 if ( abstract_pkg_init(ab_pkg) < 0 )
448 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
450 ab_pkg->provided_by = abstract_pkg_vec_alloc();
451 if (ab_pkg->provided_by==NULL){
454 ab_pkg->dependencies_checked = 0;
455 ab_pkg->state_status = SS_NOT_INSTALLED;
460 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
463 char **raw_start=NULL;
465 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
466 temp_str = (char *) alloca (str_size);
467 memset(temp_str, 0 , str_size);
469 if (temp_str == NULL ){
470 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
473 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
475 raw = raw_start = read_raw_pkgs_from_file(temp_str);
477 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
482 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
483 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
498 #define CHECK_BUFF_SIZE(buff, line, buf_size, page_size) do { \
499 if (strlen(buff) + strlen(line) >= (buf_size)) { \
500 buf_size += page_size; \
501 buff = realloc(buff, buf_size); \
504 char * pkg_formatted_info(pkg_t *pkg )
508 const size_t page_size = 8192;
509 size_t buff_size = page_size;
511 buff = calloc(1, buff_size);
513 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
517 line = pkg_formatted_field(pkg, "Package");
518 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
519 strncat(buff ,line, strlen(line));
522 line = pkg_formatted_field(pkg, "Version");
523 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
524 strncat(buff ,line, strlen(line));
527 line = pkg_formatted_field(pkg, "Depends");
528 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
529 strncat(buff ,line, strlen(line));
532 line = pkg_formatted_field(pkg, "Recommends");
533 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
534 strncat(buff ,line, strlen(line));
537 line = pkg_formatted_field(pkg, "Suggests");
538 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
539 strncat(buff ,line, strlen(line));
542 line = pkg_formatted_field(pkg, "Provides");
543 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
544 strncat(buff ,line, strlen(line));
547 line = pkg_formatted_field(pkg, "Replaces");
548 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
549 strncat(buff ,line, strlen(line));
552 line = pkg_formatted_field(pkg, "Conflicts");
553 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
554 strncat(buff ,line, strlen(line));
557 line = pkg_formatted_field(pkg, "Status");
558 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
559 strncat(buff ,line, strlen(line));
562 line = pkg_formatted_field(pkg, "Section");
563 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
564 strncat(buff ,line, strlen(line));
567 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
568 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
569 strncat(buff ,line, strlen(line));
572 line = pkg_formatted_field(pkg, "Architecture");
573 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
574 strncat(buff ,line, strlen(line));
577 line = pkg_formatted_field(pkg, "Maintainer");
578 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
579 strncat(buff ,line, strlen(line));
582 line = pkg_formatted_field(pkg, "MD5sum");
583 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
584 strncat(buff ,line, strlen(line));
587 line = pkg_formatted_field(pkg, "Size");
588 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
589 strncat(buff ,line, strlen(line));
592 line = pkg_formatted_field(pkg, "Filename");
593 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
594 strncat(buff ,line, strlen(line));
597 line = pkg_formatted_field(pkg, "Conffiles");
598 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
599 strncat(buff ,line, strlen(line));
602 line = pkg_formatted_field(pkg, "Source");
603 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
604 strncat(buff ,line, strlen(line));
607 line = pkg_formatted_field(pkg, "Description");
608 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
609 strncat(buff ,line, strlen(line));
612 line = pkg_formatted_field(pkg, "Installed-Time");
613 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
614 strncat(buff ,line, strlen(line));
617 line = pkg_formatted_field(pkg, "Tags");
618 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
619 strncat(buff ,line, strlen(line));
625 char * pkg_formatted_field(pkg_t *pkg, const char *field )
627 static size_t LINE_LEN = 128;
628 char * temp = (char *)malloc(1);
630 int flag_provide_false = 0;
633 Pigi: After some discussion with Florian we decided to modify the full procedure in
634 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
637 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
638 goto UNKNOWN_FMT_FIELD;
647 if (strcasecmp(field, "Architecture") == 0) {
649 if (pkg->architecture) {
650 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
652 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
656 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
658 } else if (strcasecmp(field, "Auto-Installed") == 0) {
659 /* Auto-Installed flag */
660 if (pkg->auto_installed) {
661 char * s = "Auto-Installed: yes\n";
662 temp = (char *)realloc(temp, strlen(s) + 1);
666 goto UNKNOWN_FMT_FIELD;
671 if (strcasecmp(field, "Conffiles") == 0) {
673 conffile_list_elt_t *iter;
674 char confstr[LINE_LEN];
676 if (nv_pair_list_empty(&pkg->conffiles)) {
681 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
682 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
683 len = len + (strlen(((conffile_t *)iter->data)->name)+strlen(((conffile_t *)iter->data)->value)+5);
686 temp = (char *)realloc(temp,len);
688 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
692 strncpy(temp, "Conffiles:\n", 12);
693 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
694 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
695 snprintf(confstr, LINE_LEN, "%s %s\n",
696 ((conffile_t *)iter->data)->name,
697 ((conffile_t *)iter->data)->value);
698 strncat(temp, confstr, strlen(confstr));
701 } else if (strcasecmp(field, "Conflicts") == 0) {
704 if (pkg->conflicts_count) {
705 char conflictstr[LINE_LEN];
707 for(i = 0; i < pkg->conflicts_count; i++) {
708 len = len + (strlen(pkg->conflicts_str[i])+5);
710 temp = (char *)realloc(temp,len);
712 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
716 strncpy(temp, "Conflicts:", 11);
717 for(i = 0; i < pkg->conflicts_count; i++) {
718 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
719 strncat(temp, conflictstr, strlen(conflictstr));
721 strncat(temp, "\n", strlen("\n"));
724 goto UNKNOWN_FMT_FIELD;
729 if (strcasecmp(field, "Depends") == 0) {
733 if (pkg->depends_count) {
734 char depstr[LINE_LEN];
736 for(i = 0; i < pkg->depends_count; i++) {
737 len = len + (strlen(pkg->depends_str[i])+4);
739 temp = (char *)realloc(temp,len);
741 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
745 strncpy(temp, "Depends:", 10);
746 for(i = 0; i < pkg->depends_count; i++) {
747 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
748 strncat(temp, depstr, strlen(depstr));
750 strncat(temp, "\n", strlen("\n"));
752 } else if (strcasecmp(field, "Description") == 0) {
754 if (pkg->description) {
755 temp = (char *)realloc(temp,strlen(pkg->description)+16);
757 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
761 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
764 goto UNKNOWN_FMT_FIELD;
770 if (pkg->essential) {
771 temp = (char *)realloc(temp,16);
773 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
777 snprintf(temp, (16), "Essential: yes\n");
785 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
787 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
791 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
797 if (strcasecmp(field, "Installed-Size") == 0) {
799 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
801 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
805 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
806 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
807 temp = (char *)realloc(temp,29);
809 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
813 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
819 /* Maintainer | MD5sum */
820 if (strcasecmp(field, "Maintainer") == 0) {
822 if (pkg->maintainer) {
823 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
825 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
829 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
831 } else if (strcasecmp(field, "MD5sum") == 0) {
834 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
836 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
840 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
843 goto UNKNOWN_FMT_FIELD;
849 if (strcasecmp(field, "Package") == 0) {
851 temp = (char *)realloc(temp,strlen(pkg->name)+11);
853 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
857 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
858 } else if (strcasecmp(field, "Priority") == 0) {
860 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
862 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
866 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
867 } else if (strcasecmp(field, "Provides") == 0) {
871 if (pkg->provides_count) {
872 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
873 for ( i=0; i < pkg->provides_count; i++ ){
874 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
875 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
876 flag_provide_false = 1;
879 if ( !flag_provide_false || /* Pigi there is not my trick flag */
880 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
881 char provstr[LINE_LEN];
883 for(i = 0; i < pkg->provides_count; i++) {
884 len = len + (strlen(pkg->provides_str[i])+5);
886 temp = (char *)realloc(temp,len);
888 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
892 strncpy(temp, "Provides:", 12);
893 for(i = 0; i < pkg->provides_count; i++) {
894 if (strlen(pkg->provides_str[i])>0){;
895 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
896 strncat(temp, provstr, strlen(provstr));
899 strncat(temp, "\n", strlen("\n"));
903 goto UNKNOWN_FMT_FIELD;
910 /* Replaces | Recommends*/
911 if (strcasecmp (field, "Replaces") == 0) {
912 if (pkg->replaces_count) {
913 char replstr[LINE_LEN];
915 for (i = 0; i < pkg->replaces_count; i++) {
916 len = len + (strlen(pkg->replaces_str[i])+5);
918 temp = (char *)realloc(temp,len);
920 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
924 strncpy(temp, "Replaces:", 12);
925 for (i = 0; i < pkg->replaces_count; i++) {
926 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
927 strncat(temp, replstr, strlen(replstr));
929 strncat(temp, "\n", strlen("\n"));
931 } else if (strcasecmp (field, "Recommends") == 0) {
932 if (pkg->recommends_count) {
933 char recstr[LINE_LEN];
935 for(i = 0; i < pkg->recommends_count; i++) {
936 len = len + (strlen( pkg->recommends_str[i])+5);
938 temp = (char *)realloc(temp,len);
940 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
944 strncpy(temp, "Recommends:", 13);
945 for(i = 0; i < pkg->recommends_count; i++) {
946 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
947 strncat(temp, recstr, strlen(recstr));
949 strncat(temp, "\n", strlen("\n"));
952 goto UNKNOWN_FMT_FIELD;
958 /* Section | Size | Source | Status | Suggests */
959 if (strcasecmp(field, "Section") == 0) {
962 temp = (char *)realloc(temp,strlen(pkg->section)+11);
964 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
968 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
970 } else if (strcasecmp(field, "Size") == 0) {
973 temp = (char *)realloc(temp,strlen(pkg->size)+8);
975 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
979 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
981 } else if (strcasecmp(field, "Source") == 0) {
984 temp = (char *)realloc(temp,strlen(pkg->source)+10);
986 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
990 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
992 } else if (strcasecmp(field, "Status") == 0) {
994 /* Benjamin Pineau note: we should avoid direct usage of
995 * strlen(arg) without keeping "arg" for later free()
997 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
998 char *pstat=pkg_state_status_to_str(pkg->state_status);
999 char *pwant=pkg_state_want_to_str(pkg->state_want);
1001 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
1002 temp = (char *)realloc(temp,sum_of_sizes);
1003 if ( temp == NULL ){
1004 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1008 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
1011 if(pstat) /* pfstat can be NULL if ENOMEM */
1013 } else if (strcasecmp(field, "Suggests") == 0) {
1014 if (pkg->suggests_count) {
1016 char sugstr[LINE_LEN];
1018 for(i = 0; i < pkg->suggests_count; i++) {
1019 len = len + (strlen(pkg->suggests_str[i])+5);
1021 temp = (char *)realloc(temp,len);
1022 if ( temp == NULL ){
1023 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1027 strncpy(temp, "Suggests:", 10);
1028 for(i = 0; i < pkg->suggests_count; i++) {
1029 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
1030 strncat(temp, sugstr, strlen(sugstr));
1032 strncat(temp, "\n", strlen("\n"));
1035 goto UNKNOWN_FMT_FIELD;
1041 if (strcasecmp(field, "Tags") == 0) {
1044 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1045 if ( temp == NULL ){
1046 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1050 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1057 char *version = pkg_version_str_alloc(pkg);
1058 temp = (char *)realloc(temp,strlen(version)+14);
1059 if ( temp == NULL ){
1060 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1064 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1069 goto UNKNOWN_FMT_FIELD;
1072 if ( strlen(temp)<2 ) {
1078 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1079 if ( strlen(temp)<2 ) {
1086 void pkg_print_info(pkg_t *pkg, FILE *file)
1094 buff = pkg_formatted_info(pkg);
1097 if (strlen(buff)>2){
1098 t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
1103 void pkg_print_status(pkg_t * pkg, FILE * file)
1109 /* XXX: QUESTION: Do we actually want more fields here? The
1110 original idea was to save space by installing only what was
1111 needed for actual computation, (package, version, status,
1112 essential, conffiles). The assumption is that all other fields
1113 can be found in th available file.
1115 But, someone proposed the idea to make it possible to
1116 reconstruct a .opk from an installed package, (ie. for beaming
1117 from one handheld to another). So, maybe we actually want a few
1118 more fields here, (depends, suggests, etc.), so that that would
1119 be guaranteed to work even in the absence of more information
1120 from the available file.
1122 28-MAR-03: kergoth and I discussed this yesterday. We think
1123 the essential info needs to be here for all installed packages
1124 because they may not appear in the Packages files on various
1125 feeds. Furthermore, one should be able to install from URL or
1126 local storage without requiring a Packages file from any feed.
1129 pkg_print_field(pkg, file, "Package");
1130 pkg_print_field(pkg, file, "Version");
1131 pkg_print_field(pkg, file, "Depends");
1132 pkg_print_field(pkg, file, "Recommends");
1133 pkg_print_field(pkg, file, "Suggests");
1134 pkg_print_field(pkg, file, "Provides");
1135 pkg_print_field(pkg, file, "Replaces");
1136 pkg_print_field(pkg, file, "Conflicts");
1137 pkg_print_field(pkg, file, "Status");
1138 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1139 pkg_print_field(pkg, file, "Architecture");
1140 pkg_print_field(pkg, file, "Conffiles");
1141 pkg_print_field(pkg, file, "Installed-Time");
1142 pkg_print_field(pkg, file, "Auto-Installed");
1146 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1149 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1150 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1151 __FUNCTION__, field);
1153 buff = pkg_formatted_field(pkg, field);
1154 if (strlen(buff)>2) {
1155 fprintf(file, "%s", buff);
1163 * libdpkg - Debian packaging suite library routines
1164 * vercmp.c - comparison of version numbers
1166 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1168 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1172 if (pkg->epoch > ref_pkg->epoch) {
1176 if (pkg->epoch < ref_pkg->epoch) {
1180 r = verrevcmp(pkg->version, ref_pkg->version);
1185 r = verrevcmp(pkg->revision, ref_pkg->revision);
1193 /* assume ascii; warning: evaluates x multiple times! */
1194 #define order(x) ((x) == '~' ? -1 \
1195 : isdigit((x)) ? 0 \
1197 : isalpha((x)) ? (x) \
1200 static int verrevcmp(const char *val, const char *ref) {
1204 while (*val || *ref) {
1207 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1208 int vc= order(*val), rc= order(*ref);
1209 if (vc != rc) return vc - rc;
1213 while ( *val == '0' ) val++;
1214 while ( *ref == '0' ) ref++;
1215 while (isdigit(*val) && isdigit(*ref)) {
1216 if (!first_diff) first_diff= *val - *ref;
1219 if (isdigit(*val)) return 1;
1220 if (isdigit(*ref)) return -1;
1221 if (first_diff) return first_diff;
1226 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1230 r = pkg_compare_versions(it, ref);
1232 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1236 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1240 if (strcmp(op, "<<") == 0) {
1244 if (strcmp(op, ">>") == 0) {
1248 if (strcmp(op, "=") == 0) {
1252 fprintf(stderr, "unknown operator: %s", op);
1256 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1258 const pkg_t *a = *(const pkg_t**) p1;
1259 const pkg_t *b = *(const pkg_t**) p2;
1262 if (!a->name || !b->name) {
1263 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1264 a, a->name, b, b->name);
1268 namecmp = strcmp(a->name, b->name);
1271 vercmp = pkg_compare_versions(a, b);
1274 if (!a->arch_priority || !b->arch_priority) {
1275 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1276 a, a->arch_priority, b, b->arch_priority);
1279 if (a->arch_priority > b->arch_priority)
1281 if (a->arch_priority < b->arch_priority)
1286 int abstract_pkg_name_compare(const void *p1, const void *p2)
1288 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1289 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1290 if (!a->name || !b->name) {
1291 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1292 a, a->name, b, b->name);
1295 return strcmp(a->name, b->name);
1299 char *pkg_version_str_alloc(pkg_t *pkg)
1301 char *complete_version;
1306 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1308 epoch_str = strdup("");
1311 if (pkg->revision && strlen(pkg->revision)) {
1312 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1314 revision_str = strdup("");
1318 sprintf_alloc(&complete_version, "%s%s%s",
1319 epoch_str, pkg->version, revision_str);
1324 return complete_version;
1327 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1330 char *list_file_name = NULL;
1331 FILE *list_file = NULL;
1333 char *installed_file_name;
1336 pkg->installed_files_ref_cnt++;
1338 if (pkg->installed_files) {
1339 return pkg->installed_files;
1342 pkg->installed_files = str_list_alloc();
1343 if (pkg->installed_files == NULL) {
1344 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1348 /* For uninstalled packages, get the file list directly from the package.
1349 For installed packages, look at the package.list file in the database.
1351 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1352 if (pkg->local_filename == NULL) {
1353 return pkg->installed_files;
1355 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1356 file. In other words, change deb_extract so that it can
1357 simply return the file list as a char *[] rather than
1358 insisting on writing in to a FILE * as it does now. */
1359 list_file = tmpfile();
1360 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1363 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1364 __FUNCTION__, pkg->local_filename, strerror(err));
1365 return pkg->installed_files;
1369 sprintf_alloc(&list_file_name, "%s/%s.list",
1370 pkg->dest->info_dir, pkg->name);
1371 if (! file_exists(list_file_name)) {
1372 free(list_file_name);
1373 return pkg->installed_files;
1376 list_file = fopen(list_file_name, "r");
1377 if (list_file == NULL) {
1378 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1379 list_file_name, strerror(errno));
1380 free(list_file_name);
1381 return pkg->installed_files;
1383 free(list_file_name);
1386 rootdirlen = strlen( pkg->dest->root_dir );
1390 line = file_read_line_alloc(list_file);
1397 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1398 if( strncmp( pkg->dest->root_dir,
1401 if (*file_name == '.') {
1404 if (*file_name == '/') {
1408 /* Freed in pkg_free_installed_files */
1409 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1411 // already contains root_dir as header -> ABSOLUTE
1412 sprintf_alloc(&installed_file_name, "%s", file_name);
1414 str_list_append(pkg->installed_files, installed_file_name);
1420 return pkg->installed_files;
1423 /* XXX: CLEANUP: This function and it's counterpart,
1424 (pkg_get_installed_files), do not match our init/deinit naming
1425 convention. Nor the alloc/free convention. But, then again, neither
1426 of these conventions currrently fit the way these two functions
1428 int pkg_free_installed_files(pkg_t *pkg)
1430 pkg->installed_files_ref_cnt--;
1432 if (pkg->installed_files_ref_cnt > 0)
1435 if (pkg->installed_files) {
1436 str_list_deinit(pkg->installed_files);
1439 pkg->installed_files = NULL;
1444 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1447 char *list_file_name;
1449 //I don't think pkg_free_installed_files should be called here. Jamey
1450 //pkg_free_installed_files(pkg);
1452 sprintf_alloc(&list_file_name, "%s/%s.list",
1453 pkg->dest->info_dir, pkg->name);
1454 if (!conf->noaction) {
1455 err = unlink(list_file_name);
1456 free(list_file_name);
1465 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1467 conffile_list_elt_t *iter;
1468 conffile_t *conffile;
1474 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1475 conffile = (conffile_t *)iter->data;
1477 if (strcmp(conffile->name, file_name) == 0) {
1485 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1486 const char *script, const char *args)
1492 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1493 maintainer script within a chroot environment. */
1495 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1496 have scripts in pkg->tmp_unpack_dir. */
1497 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1498 if (pkg->dest == NULL) {
1499 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1500 __FUNCTION__, pkg->name);
1503 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1505 if (pkg->tmp_unpack_dir == NULL) {
1506 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1507 __FUNCTION__, pkg->name);
1510 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1513 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1514 if (conf->noaction) return 0;
1516 /* XXX: CLEANUP: There must be a better way to handle maintainer
1517 scripts when running with offline_root mode and/or a dest other
1518 than '/'. I've been playing around with some clever chroot
1519 tricks and I might come up with something workable. */
1521 * Attempt to provide a restricted environment for offline operation
1522 * Need the following set as a minimum:
1523 * OPKG_OFFLINE_ROOT = absolute path to root dir
1524 * D = absolute path to root dir (for OE generated postinst)
1525 * PATH = something safe (a restricted set of utilities)
1528 bool AllowOfflineMode = false;
1529 if (conf->offline_root) {
1530 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1531 setenv("D", conf->offline_root, 1);
1532 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1533 setenv("PATH", "/dev/null", 1);
1535 setenv("PATH", conf->offline_root_path, 1);
1536 AllowOfflineMode = true;
1541 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1543 if (! file_exists(path)) {
1548 if (conf->offline_root && !AllowOfflineMode) {
1549 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1554 sprintf_alloc(&cmd, "%s %s", path, args);
1561 fprintf(stderr, "%s script returned status %d\n", script, err);
1568 char *pkg_state_want_to_str(pkg_state_want_t sw)
1572 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1573 if (pkg_state_want_map[i].value == sw) {
1574 return strdup(pkg_state_want_map[i].str);
1578 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1580 return strdup("<STATE_WANT_UNKNOWN>");
1583 pkg_state_want_t pkg_state_want_from_str(char *str)
1587 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1588 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1589 return pkg_state_want_map[i].value;
1593 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1598 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1601 int len = 3; /* ok\000 is minimum */
1604 /* clear the temporary flags before converting to string */
1605 sf &= SF_NONVOLATILE_FLAGS;
1608 return strdup("ok");
1611 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1612 if (sf & pkg_state_flag_map[i].value) {
1613 len += strlen(pkg_state_flag_map[i].str) + 1;
1617 if ( str == NULL ) {
1618 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1622 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1623 if (sf & pkg_state_flag_map[i].value) {
1624 strcat(str, pkg_state_flag_map[i].str);
1629 str[len-1] = 0; /* squash last comma */
1634 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1639 if (strcmp(str, "ok") == 0) {
1642 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1643 const char *sfname = pkg_state_flag_map[i].str;
1644 int sfname_len = strlen(sfname);
1645 if (strncmp(str, sfname, sfname_len) == 0) {
1646 sf |= pkg_state_flag_map[i].value;
1648 if (str[0] == ',') {
1659 char *pkg_state_status_to_str(pkg_state_status_t ss)
1663 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1664 if (pkg_state_status_map[i].value == ss) {
1665 return strdup(pkg_state_status_map[i].str);
1669 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1671 return strdup("<STATE_STATUS_UNKNOWN>");
1674 pkg_state_status_t pkg_state_status_from_str(const char *str)
1678 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1679 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1680 return pkg_state_status_map[i].value;
1684 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1686 return SS_NOT_INSTALLED;
1689 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1691 nv_pair_list_elt_t *l;
1693 if (!pkg->architecture)
1696 list_for_each_entry(l , &conf->arch_list.head, node) {
1697 nv_pair_t *nv = (nv_pair_t *)l->data;
1698 if (strcmp(nv->name, pkg->architecture) == 0) {
1699 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1704 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1708 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1710 nv_pair_list_elt_t *l;
1712 list_for_each_entry(l , &conf->arch_list.head, node) {
1713 nv_pair_t *nv = (nv_pair_t *)l->data;
1714 if (strcmp(nv->name, archname) == 0) {
1715 int priority = strtol(nv->value, NULL, 0);
1722 int pkg_info_preinstall_check(opkg_conf_t *conf)
1725 hash_table_t *pkg_hash = &conf->pkg_hash;
1726 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1727 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1729 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1730 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1731 /* update arch_priority for each package */
1732 for (i = 0; i < available_pkgs->len; i++) {
1733 pkg_t *pkg = available_pkgs->pkgs[i];
1734 int arch_priority = 1;
1737 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1738 if (pkg->architecture)
1739 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1741 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1742 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1743 pkg->arch_priority = arch_priority;
1746 for (i = 0; i < available_pkgs->len; i++) {
1747 pkg_t *pkg = available_pkgs->pkgs[i];
1748 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1749 /* clear flags and want for any uninstallable package */
1750 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1751 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1752 pkg->state_want = SW_UNKNOWN;
1753 pkg->state_flag = 0;
1756 pkg_vec_free(available_pkgs);
1758 /* update the file owner data structure */
1759 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1760 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1761 for (i = 0; i < installed_pkgs->len; i++) {
1762 pkg_t *pkg = installed_pkgs->pkgs[i];
1763 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1764 str_list_elt_t *iter;
1765 if (installed_files == NULL) {
1766 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1769 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1770 char *installed_file = (char *) iter->data;
1771 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1772 file_hash_set_file_owner(conf, installed_file, pkg);
1774 pkg_free_installed_files(pkg);
1776 pkg_vec_free(installed_pkgs);
1781 struct pkg_write_filelist_data {
1787 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1789 struct pkg_write_filelist_data *data = data_;
1790 pkg_t *entry = entry_;
1791 if (entry == data->pkg) {
1792 fprintf(data->stream, "%s\n", key);
1796 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1798 struct pkg_write_filelist_data data;
1799 char *list_file_name = NULL;
1803 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1806 opkg_message(conf, OPKG_INFO,
1807 " creating %s.list file\n", pkg->name);
1808 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1809 if (!list_file_name) {
1810 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1813 opkg_message(conf, OPKG_INFO,
1814 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1815 data.stream = fopen(list_file_name, "w");
1817 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1818 list_file_name, strerror(errno));
1823 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1824 fclose(data.stream);
1825 free(list_file_name);
1827 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1832 int pkg_write_changed_filelists(opkg_conf_t *conf)
1834 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1835 hash_table_t *pkg_hash = &conf->pkg_hash;
1841 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1842 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1843 for (i = 0; i < installed_pkgs->len; i++) {
1844 pkg_t *pkg = installed_pkgs->pkgs[i];
1845 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1846 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1847 err = pkg_write_filelist(conf, pkg);
1849 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1852 pkg_vec_free (installed_pkgs);