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);
1415 free(installed_file_name);
1421 return pkg->installed_files;
1424 /* XXX: CLEANUP: This function and it's counterpart,
1425 (pkg_get_installed_files), do not match our init/deinit naming
1426 convention. Nor the alloc/free convention. But, then again, neither
1427 of these conventions currrently fit the way these two functions
1429 int pkg_free_installed_files(pkg_t *pkg)
1431 pkg->installed_files_ref_cnt--;
1433 if (pkg->installed_files_ref_cnt > 0)
1436 if (pkg->installed_files) {
1437 str_list_purge(pkg->installed_files);
1440 pkg->installed_files = NULL;
1445 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1448 char *list_file_name;
1450 //I don't think pkg_free_installed_files should be called here. Jamey
1451 //pkg_free_installed_files(pkg);
1453 sprintf_alloc(&list_file_name, "%s/%s.list",
1454 pkg->dest->info_dir, pkg->name);
1455 if (!conf->noaction) {
1456 err = unlink(list_file_name);
1457 free(list_file_name);
1466 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1468 conffile_list_elt_t *iter;
1469 conffile_t *conffile;
1475 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1476 conffile = (conffile_t *)iter->data;
1478 if (strcmp(conffile->name, file_name) == 0) {
1486 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1487 const char *script, const char *args)
1493 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1494 maintainer script within a chroot environment. */
1496 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1497 have scripts in pkg->tmp_unpack_dir. */
1498 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1499 if (pkg->dest == NULL) {
1500 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1501 __FUNCTION__, pkg->name);
1504 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1506 if (pkg->tmp_unpack_dir == NULL) {
1507 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1508 __FUNCTION__, pkg->name);
1511 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1514 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1515 if (conf->noaction) return 0;
1517 /* XXX: CLEANUP: There must be a better way to handle maintainer
1518 scripts when running with offline_root mode and/or a dest other
1519 than '/'. I've been playing around with some clever chroot
1520 tricks and I might come up with something workable. */
1522 * Attempt to provide a restricted environment for offline operation
1523 * Need the following set as a minimum:
1524 * OPKG_OFFLINE_ROOT = absolute path to root dir
1525 * D = absolute path to root dir (for OE generated postinst)
1526 * PATH = something safe (a restricted set of utilities)
1529 bool AllowOfflineMode = false;
1530 if (conf->offline_root) {
1531 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1532 setenv("D", conf->offline_root, 1);
1533 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1534 setenv("PATH", "/dev/null", 1);
1536 setenv("PATH", conf->offline_root_path, 1);
1537 AllowOfflineMode = true;
1542 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1544 if (! file_exists(path)) {
1549 if (conf->offline_root && !AllowOfflineMode) {
1550 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1555 sprintf_alloc(&cmd, "%s %s", path, args);
1562 fprintf(stderr, "%s script returned status %d\n", script, err);
1569 char *pkg_state_want_to_str(pkg_state_want_t sw)
1573 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1574 if (pkg_state_want_map[i].value == sw) {
1575 return strdup(pkg_state_want_map[i].str);
1579 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1581 return strdup("<STATE_WANT_UNKNOWN>");
1584 pkg_state_want_t pkg_state_want_from_str(char *str)
1588 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1589 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1590 return pkg_state_want_map[i].value;
1594 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1599 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1602 int len = 3; /* ok\000 is minimum */
1605 /* clear the temporary flags before converting to string */
1606 sf &= SF_NONVOLATILE_FLAGS;
1609 return strdup("ok");
1612 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1613 if (sf & pkg_state_flag_map[i].value) {
1614 len += strlen(pkg_state_flag_map[i].str) + 1;
1618 if ( str == NULL ) {
1619 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1623 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1624 if (sf & pkg_state_flag_map[i].value) {
1625 strcat(str, pkg_state_flag_map[i].str);
1630 str[len-1] = 0; /* squash last comma */
1635 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1640 if (strcmp(str, "ok") == 0) {
1643 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1644 const char *sfname = pkg_state_flag_map[i].str;
1645 int sfname_len = strlen(sfname);
1646 if (strncmp(str, sfname, sfname_len) == 0) {
1647 sf |= pkg_state_flag_map[i].value;
1649 if (str[0] == ',') {
1660 char *pkg_state_status_to_str(pkg_state_status_t ss)
1664 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1665 if (pkg_state_status_map[i].value == ss) {
1666 return strdup(pkg_state_status_map[i].str);
1670 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1672 return strdup("<STATE_STATUS_UNKNOWN>");
1675 pkg_state_status_t pkg_state_status_from_str(const char *str)
1679 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1680 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1681 return pkg_state_status_map[i].value;
1685 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1687 return SS_NOT_INSTALLED;
1690 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1692 nv_pair_list_elt_t *l;
1694 if (!pkg->architecture)
1697 list_for_each_entry(l , &conf->arch_list.head, node) {
1698 nv_pair_t *nv = (nv_pair_t *)l->data;
1699 if (strcmp(nv->name, pkg->architecture) == 0) {
1700 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1705 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1709 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1711 nv_pair_list_elt_t *l;
1713 list_for_each_entry(l , &conf->arch_list.head, node) {
1714 nv_pair_t *nv = (nv_pair_t *)l->data;
1715 if (strcmp(nv->name, archname) == 0) {
1716 int priority = strtol(nv->value, NULL, 0);
1723 int pkg_info_preinstall_check(opkg_conf_t *conf)
1726 hash_table_t *pkg_hash = &conf->pkg_hash;
1727 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1728 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1730 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1731 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1732 /* update arch_priority for each package */
1733 for (i = 0; i < available_pkgs->len; i++) {
1734 pkg_t *pkg = available_pkgs->pkgs[i];
1735 int arch_priority = 1;
1738 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1739 if (pkg->architecture)
1740 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1742 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1743 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1744 pkg->arch_priority = arch_priority;
1747 for (i = 0; i < available_pkgs->len; i++) {
1748 pkg_t *pkg = available_pkgs->pkgs[i];
1749 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1750 /* clear flags and want for any uninstallable package */
1751 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1752 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1753 pkg->state_want = SW_UNKNOWN;
1754 pkg->state_flag = 0;
1757 pkg_vec_free(available_pkgs);
1759 /* update the file owner data structure */
1760 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1761 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1762 for (i = 0; i < installed_pkgs->len; i++) {
1763 pkg_t *pkg = installed_pkgs->pkgs[i];
1764 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1765 str_list_elt_t *iter, *niter;
1766 if (installed_files == NULL) {
1767 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1770 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1772 iter = niter, niter = str_list_next(installed_files, iter)) {
1773 char *installed_file = (char *) iter->data;
1774 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1775 file_hash_set_file_owner(conf, installed_file, pkg);
1777 pkg_free_installed_files(pkg);
1779 pkg_vec_free(installed_pkgs);
1784 struct pkg_write_filelist_data {
1790 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1792 struct pkg_write_filelist_data *data = data_;
1793 pkg_t *entry = entry_;
1794 if (entry == data->pkg) {
1795 fprintf(data->stream, "%s\n", key);
1799 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1801 struct pkg_write_filelist_data data;
1802 char *list_file_name = NULL;
1806 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1809 opkg_message(conf, OPKG_INFO,
1810 " creating %s.list file\n", pkg->name);
1811 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1812 if (!list_file_name) {
1813 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1816 opkg_message(conf, OPKG_INFO,
1817 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1818 data.stream = fopen(list_file_name, "w");
1820 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1821 list_file_name, strerror(errno));
1826 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1827 fclose(data.stream);
1828 free(list_file_name);
1830 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1835 int pkg_write_changed_filelists(opkg_conf_t *conf)
1837 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1838 hash_table_t *pkg_hash = &conf->pkg_hash;
1844 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1845 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1846 for (i = 0; i < installed_pkgs->len; i++) {
1847 pkg_t *pkg = installed_pkgs->pkgs[i];
1848 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1849 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1850 err = pkg_write_filelist(conf, pkg);
1852 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1855 pkg_vec_free (installed_pkgs);