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.
26 #include "pkg_parse.h"
27 #include "pkg_extract.h"
28 #include "opkg_message.h"
29 #include "opkg_utils.h"
31 #include "sprintf_alloc.h"
32 #include "file_util.h"
35 #include "opkg_conf.h"
37 typedef struct enum_map enum_map_t;
44 static const enum_map_t pkg_state_want_map[] = {
45 { SW_UNKNOWN, "unknown"},
46 { SW_INSTALL, "install"},
47 { SW_DEINSTALL, "deinstall"},
51 static const enum_map_t pkg_state_flag_map[] = {
53 { SF_REINSTREQ, "reinstreq"},
55 { SF_REPLACE, "replace"},
56 { SF_NOPRUNE, "noprune"},
57 { SF_PREFER, "prefer"},
58 { SF_OBSOLETE, "obsolete"},
62 static const enum_map_t pkg_state_status_map[] = {
63 { SS_NOT_INSTALLED, "not-installed" },
64 { SS_UNPACKED, "unpacked" },
65 { SS_HALF_CONFIGURED, "half-configured" },
66 { SS_INSTALLED, "installed" },
67 { SS_HALF_INSTALLED, "half-installed" },
68 { SS_CONFIG_FILES, "config-files" },
69 { SS_POST_INST_FAILED, "post-inst-failed" },
70 { SS_REMOVAL_FAILED, "removal-failed" }
73 static int verrevcmp(const char *val, const char *ref);
80 pkg = calloc(1, sizeof(pkg_t));
82 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
91 int pkg_init(pkg_t *pkg)
99 pkg->architecture = NULL;
100 pkg->maintainer = NULL;
102 pkg->description = NULL;
103 pkg->state_want = SW_UNKNOWN;
104 pkg->state_flag = SF_OK;
105 pkg->state_status = SS_NOT_INSTALLED;
106 pkg->depends_str = NULL;
107 pkg->provides_str = NULL;
108 pkg->depends_count = 0;
110 pkg->suggests_str = NULL;
111 pkg->recommends_str = NULL;
112 pkg->suggests_count = 0;
113 pkg->recommends_count = 0;
115 active_list_init(&pkg->list);
117 /* Abhaya: added init for conflicts fields */
118 pkg->conflicts = NULL;
119 pkg->conflicts_count = 0;
121 /* added for replaces. Jamey 7/23/2002 */
122 pkg->replaces = NULL;
123 pkg->replaces_count = 0;
125 pkg->pre_depends_count = 0;
126 pkg->pre_depends_str = NULL;
127 pkg->provides_count = 0;
128 pkg->provides = NULL;
129 pkg->filename = NULL;
130 pkg->local_filename = NULL;
131 pkg->tmp_unpack_dir = NULL;
134 pkg->installed_size = NULL;
135 pkg->priority = NULL;
137 conffile_list_init(&pkg->conffiles);
138 pkg->installed_files = NULL;
139 pkg->installed_files_ref_cnt = 0;
141 pkg->provided_by_hand = 0;
146 void compound_depend_deinit (compound_depend_t *depends)
149 for (i = 0; i < depends->possibility_count; i++)
152 d = depends->possibilities[i];
156 free (depends->possibilities);
159 void pkg_deinit(pkg_t *pkg)
168 /* revision shares storage with version, so
170 pkg->revision = NULL;
171 /* owned by opkg_conf_t */
173 /* owned by opkg_conf_t */
175 free(pkg->architecture);
176 pkg->architecture = NULL;
177 free(pkg->maintainer);
178 pkg->maintainer = NULL;
181 free(pkg->description);
182 pkg->description = NULL;
183 pkg->state_want = SW_UNKNOWN;
184 pkg->state_flag = SF_OK;
185 pkg->state_status = SS_NOT_INSTALLED;
187 active_list_clear(&pkg->list);
189 free (pkg->replaces);
190 pkg->replaces = NULL;
192 for (i = 0; i < pkg->depends_count; i++)
193 free (pkg->depends_str[i]);
194 free(pkg->depends_str);
195 pkg->depends_str = NULL;
197 for (i = 0; i < pkg->provides_count; i++)
198 free (pkg->provides_str[i]);
199 free(pkg->provides_str);
200 pkg->provides_str = NULL;
202 for (i = 0; i < pkg->conflicts_count; i++)
203 free (pkg->conflicts_str[i]);
204 free(pkg->conflicts_str);
205 pkg->conflicts_str = NULL;
207 for (i = 0; i < pkg->replaces_count; i++)
208 free (pkg->replaces_str[i]);
209 free(pkg->replaces_str);
210 pkg->replaces_str = NULL;
212 for (i = 0; i < pkg->recommends_count; i++)
213 free (pkg->recommends_str[i]);
214 free(pkg->recommends_str);
215 pkg->recommends_str = NULL;
217 for (i = 0; i < pkg->suggests_count; i++)
218 free (pkg->suggests_str[i]);
219 free(pkg->suggests_str);
220 pkg->suggests_str = NULL;
224 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
227 for (x = 0; x < count; x++)
228 compound_depend_deinit (&pkg->depends[x]);
235 for (x = 0; x < pkg->conflicts_count; x++)
236 compound_depend_deinit (&pkg->conflicts[x]);
237 free (pkg->conflicts);
240 free (pkg->provides);
242 pkg->pre_depends_count = 0;
243 free(pkg->pre_depends_str);
244 pkg->pre_depends_str = NULL;
245 pkg->provides_count = 0;
247 pkg->filename = NULL;
248 free(pkg->local_filename);
249 pkg->local_filename = NULL;
250 /* CLEANUP: It'd be nice to pullin the cleanup function from
251 opkg_install.c here. See comment in
252 opkg_install.c:cleanup_temporary_files */
253 free(pkg->tmp_unpack_dir);
254 pkg->tmp_unpack_dir = NULL;
259 free(pkg->installed_size);
260 pkg->installed_size = NULL;
262 pkg->priority = NULL;
265 conffile_list_deinit(&pkg->conffiles);
266 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
267 since if they are calling deinit, they should know. Maybe do an
268 assertion here instead? */
269 pkg->installed_files_ref_cnt = 1;
270 pkg_free_installed_files(pkg);
276 int pkg_init_from_file(pkg_t *pkg, const char *filename)
283 if (err) { return err; }
285 pkg->local_filename = strdup(filename);
287 control_file = tmpfile();
288 err = pkg_extract_control_file_to_stream(pkg, control_file);
289 if (err) { return err; }
291 rewind(control_file);
292 raw = read_raw_pkgs_from_stream(control_file);
293 pkg_parse_raw(pkg, &raw, NULL, NULL);
295 fclose(control_file);
300 /* Merge any new information in newpkg into oldpkg */
301 /* XXX: CLEANUP: This function shouldn't actually modify anything in
302 newpkg, but should leave it usable. This rework is so that
303 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
305 * uh, i thought that i had originally written this so that it took
306 * two pkgs and returned a new one? we can do that again... -sma
308 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
310 if (oldpkg == newpkg) {
315 oldpkg->src = newpkg->src;
317 oldpkg->dest = newpkg->dest;
318 if (!oldpkg->architecture)
319 oldpkg->architecture = str_dup_safe(newpkg->architecture);
320 if (!oldpkg->arch_priority)
321 oldpkg->arch_priority = newpkg->arch_priority;
322 if (!oldpkg->section)
323 oldpkg->section = str_dup_safe(newpkg->section);
324 if(!oldpkg->maintainer)
325 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
326 if(!oldpkg->description)
327 oldpkg->description = str_dup_safe(newpkg->description);
329 /* merge the state_flags from the new package */
330 oldpkg->state_want = newpkg->state_want;
331 oldpkg->state_status = newpkg->state_status;
332 oldpkg->state_flag = newpkg->state_flag;
334 if (oldpkg->state_want == SW_UNKNOWN)
335 oldpkg->state_want = newpkg->state_want;
336 if (oldpkg->state_status == SS_NOT_INSTALLED)
337 oldpkg->state_status = newpkg->state_status;
338 oldpkg->state_flag |= newpkg->state_flag;
341 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
342 oldpkg->depends_str = newpkg->depends_str;
343 newpkg->depends_str = NULL;
344 oldpkg->depends_count = newpkg->depends_count;
345 newpkg->depends_count = 0;
347 oldpkg->depends = newpkg->depends;
348 newpkg->depends = NULL;
350 oldpkg->pre_depends_str = newpkg->pre_depends_str;
351 newpkg->pre_depends_str = NULL;
352 oldpkg->pre_depends_count = newpkg->pre_depends_count;
353 newpkg->pre_depends_count = 0;
355 oldpkg->recommends_str = newpkg->recommends_str;
356 newpkg->recommends_str = NULL;
357 oldpkg->recommends_count = newpkg->recommends_count;
358 newpkg->recommends_count = 0;
360 oldpkg->suggests_str = newpkg->suggests_str;
361 newpkg->suggests_str = NULL;
362 oldpkg->suggests_count = newpkg->suggests_count;
363 newpkg->suggests_count = 0;
366 if (!oldpkg->provides_str) {
367 oldpkg->provides_str = newpkg->provides_str;
368 newpkg->provides_str = NULL;
369 oldpkg->provides_count = newpkg->provides_count;
370 newpkg->provides_count = 0;
372 oldpkg->provides = newpkg->provides;
373 newpkg->provides = NULL;
376 if (!oldpkg->conflicts_str) {
377 oldpkg->conflicts_str = newpkg->conflicts_str;
378 newpkg->conflicts_str = NULL;
379 oldpkg->conflicts_count = newpkg->conflicts_count;
380 newpkg->conflicts_count = 0;
382 oldpkg->conflicts = newpkg->conflicts;
383 newpkg->conflicts = NULL;
386 if (!oldpkg->replaces_str) {
387 oldpkg->replaces_str = newpkg->replaces_str;
388 newpkg->replaces_str = NULL;
389 oldpkg->replaces_count = newpkg->replaces_count;
390 newpkg->replaces_count = 0;
392 oldpkg->replaces = newpkg->replaces;
393 newpkg->replaces = NULL;
396 if (!oldpkg->filename)
397 oldpkg->filename = str_dup_safe(newpkg->filename);
399 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
400 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
401 if (!oldpkg->local_filename)
402 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
403 if (!oldpkg->tmp_unpack_dir)
404 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
406 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
408 oldpkg->size = str_dup_safe(newpkg->size);
409 if (!oldpkg->installed_size)
410 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
411 if (!oldpkg->priority)
412 oldpkg->priority = str_dup_safe(newpkg->priority);
414 oldpkg->source = str_dup_safe(newpkg->source);
415 if (nv_pair_list_empty(&oldpkg->conffiles)){
416 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
417 conffile_list_init(&newpkg->conffiles);
419 if (!oldpkg->installed_files){
420 oldpkg->installed_files = newpkg->installed_files;
421 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
422 newpkg->installed_files = NULL;
424 if (!oldpkg->essential)
425 oldpkg->essential = newpkg->essential;
430 abstract_pkg_t *abstract_pkg_new(void)
432 abstract_pkg_t * ab_pkg;
434 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
436 if (ab_pkg == NULL) {
437 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
441 if ( abstract_pkg_init(ab_pkg) < 0 )
447 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
449 ab_pkg->provided_by = abstract_pkg_vec_alloc();
450 if (ab_pkg->provided_by==NULL){
453 ab_pkg->dependencies_checked = 0;
454 ab_pkg->state_status = SS_NOT_INSTALLED;
459 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
462 char **raw_start=NULL;
464 temp_str = (char *) calloc (1, strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
465 if (temp_str == NULL ){
466 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
469 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
471 raw = raw_start = read_raw_pkgs_from_file(temp_str);
473 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
478 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
479 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
495 #define CHECK_BUFF_SIZE(buff, line, buf_size, page_size) do { \
496 if (strlen(buff) + strlen(line) >= (buf_size)) { \
497 buf_size += page_size; \
498 buff = realloc(buff, buf_size); \
501 char * pkg_formatted_info(pkg_t *pkg )
505 const size_t page_size = 8192;
506 size_t buff_size = page_size;
508 buff = calloc(1, buff_size);
510 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
514 line = pkg_formatted_field(pkg, "Package");
515 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
516 strncat(buff ,line, strlen(line));
519 line = pkg_formatted_field(pkg, "Version");
520 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
521 strncat(buff ,line, strlen(line));
524 line = pkg_formatted_field(pkg, "Depends");
525 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
526 strncat(buff ,line, strlen(line));
529 line = pkg_formatted_field(pkg, "Recommends");
530 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
531 strncat(buff ,line, strlen(line));
534 line = pkg_formatted_field(pkg, "Suggests");
535 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
536 strncat(buff ,line, strlen(line));
539 line = pkg_formatted_field(pkg, "Provides");
540 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
541 strncat(buff ,line, strlen(line));
544 line = pkg_formatted_field(pkg, "Replaces");
545 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
546 strncat(buff ,line, strlen(line));
549 line = pkg_formatted_field(pkg, "Conflicts");
550 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
551 strncat(buff ,line, strlen(line));
554 line = pkg_formatted_field(pkg, "Status");
555 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
556 strncat(buff ,line, strlen(line));
559 line = pkg_formatted_field(pkg, "Section");
560 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
561 strncat(buff ,line, strlen(line));
564 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
565 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
566 strncat(buff ,line, strlen(line));
569 line = pkg_formatted_field(pkg, "Architecture");
570 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
571 strncat(buff ,line, strlen(line));
574 line = pkg_formatted_field(pkg, "Maintainer");
575 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
576 strncat(buff ,line, strlen(line));
579 line = pkg_formatted_field(pkg, "MD5sum");
580 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
581 strncat(buff ,line, strlen(line));
584 line = pkg_formatted_field(pkg, "Size");
585 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
586 strncat(buff ,line, strlen(line));
589 line = pkg_formatted_field(pkg, "Filename");
590 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
591 strncat(buff ,line, strlen(line));
594 line = pkg_formatted_field(pkg, "Conffiles");
595 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
596 strncat(buff ,line, strlen(line));
599 line = pkg_formatted_field(pkg, "Source");
600 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
601 strncat(buff ,line, strlen(line));
604 line = pkg_formatted_field(pkg, "Description");
605 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
606 strncat(buff ,line, strlen(line));
609 line = pkg_formatted_field(pkg, "Installed-Time");
610 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
611 strncat(buff ,line, strlen(line));
614 line = pkg_formatted_field(pkg, "Tags");
615 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
616 strncat(buff ,line, strlen(line));
622 char * pkg_formatted_field(pkg_t *pkg, const char *field )
624 static size_t LINE_LEN = 128;
625 char * temp = (char *)malloc(1);
627 int flag_provide_false = 0;
630 Pigi: After some discussion with Florian we decided to modify the full procedure in
631 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
634 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
635 goto UNKNOWN_FMT_FIELD;
644 if (strcasecmp(field, "Architecture") == 0) {
646 if (pkg->architecture) {
647 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
649 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
653 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
655 } else if (strcasecmp(field, "Auto-Installed") == 0) {
656 /* Auto-Installed flag */
657 if (pkg->auto_installed) {
658 char * s = "Auto-Installed: yes\n";
659 temp = (char *)realloc(temp, strlen(s) + 1);
663 goto UNKNOWN_FMT_FIELD;
668 if (strcasecmp(field, "Conffiles") == 0) {
670 conffile_list_elt_t *iter;
671 char confstr[LINE_LEN];
673 if (nv_pair_list_empty(&pkg->conffiles)) {
678 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
679 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
680 len = len + (strlen(((conffile_t *)iter->data)->name)+strlen(((conffile_t *)iter->data)->value)+5);
683 temp = (char *)realloc(temp,len);
685 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
689 strncpy(temp, "Conffiles:\n", 12);
690 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
691 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
692 snprintf(confstr, LINE_LEN, "%s %s\n",
693 ((conffile_t *)iter->data)->name,
694 ((conffile_t *)iter->data)->value);
695 strncat(temp, confstr, strlen(confstr));
698 } else if (strcasecmp(field, "Conflicts") == 0) {
701 if (pkg->conflicts_count) {
702 char conflictstr[LINE_LEN];
704 for(i = 0; i < pkg->conflicts_count; i++) {
705 len = len + (strlen(pkg->conflicts_str[i])+5);
707 temp = (char *)realloc(temp,len);
709 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
713 strncpy(temp, "Conflicts:", 11);
714 for(i = 0; i < pkg->conflicts_count; i++) {
715 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
716 strncat(temp, conflictstr, strlen(conflictstr));
718 strncat(temp, "\n", strlen("\n"));
721 goto UNKNOWN_FMT_FIELD;
726 if (strcasecmp(field, "Depends") == 0) {
730 if (pkg->depends_count) {
731 char depstr[LINE_LEN];
733 for(i = 0; i < pkg->depends_count; i++) {
734 len = len + (strlen(pkg->depends_str[i])+4);
736 temp = (char *)realloc(temp,len);
738 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
742 strncpy(temp, "Depends:", 10);
743 for(i = 0; i < pkg->depends_count; i++) {
744 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
745 strncat(temp, depstr, strlen(depstr));
747 strncat(temp, "\n", strlen("\n"));
749 } else if (strcasecmp(field, "Description") == 0) {
751 if (pkg->description) {
752 temp = (char *)realloc(temp,strlen(pkg->description)+16);
754 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
758 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
761 goto UNKNOWN_FMT_FIELD;
767 if (pkg->essential) {
768 temp = (char *)realloc(temp,16);
770 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
774 snprintf(temp, (16), "Essential: yes\n");
782 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
784 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
788 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
794 if (strcasecmp(field, "Installed-Size") == 0) {
796 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
798 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
802 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
803 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
804 temp = (char *)realloc(temp,29);
806 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
810 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
816 /* Maintainer | MD5sum */
817 if (strcasecmp(field, "Maintainer") == 0) {
819 if (pkg->maintainer) {
820 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
822 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
826 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
828 } else if (strcasecmp(field, "MD5sum") == 0) {
831 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
833 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
837 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
840 goto UNKNOWN_FMT_FIELD;
846 if (strcasecmp(field, "Package") == 0) {
848 temp = (char *)realloc(temp,strlen(pkg->name)+11);
850 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
854 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
855 } else if (strcasecmp(field, "Priority") == 0) {
857 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
859 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
863 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
864 } else if (strcasecmp(field, "Provides") == 0) {
868 if (pkg->provides_count) {
869 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
870 for ( i=0; i < pkg->provides_count; i++ ){
871 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
872 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
873 flag_provide_false = 1;
876 if ( !flag_provide_false || /* Pigi there is not my trick flag */
877 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
878 char provstr[LINE_LEN];
880 for(i = 0; i < pkg->provides_count; i++) {
881 len = len + (strlen(pkg->provides_str[i])+5);
883 temp = (char *)realloc(temp,len);
885 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
889 strncpy(temp, "Provides:", 12);
890 for(i = 0; i < pkg->provides_count; i++) {
891 if (strlen(pkg->provides_str[i])>0){;
892 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
893 strncat(temp, provstr, strlen(provstr));
896 strncat(temp, "\n", strlen("\n"));
900 goto UNKNOWN_FMT_FIELD;
907 /* Replaces | Recommends*/
908 if (strcasecmp (field, "Replaces") == 0) {
909 if (pkg->replaces_count) {
910 char replstr[LINE_LEN];
912 for (i = 0; i < pkg->replaces_count; i++) {
913 len = len + (strlen(pkg->replaces_str[i])+5);
915 temp = (char *)realloc(temp,len);
917 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
921 strncpy(temp, "Replaces:", 12);
922 for (i = 0; i < pkg->replaces_count; i++) {
923 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
924 strncat(temp, replstr, strlen(replstr));
926 strncat(temp, "\n", strlen("\n"));
928 } else if (strcasecmp (field, "Recommends") == 0) {
929 if (pkg->recommends_count) {
930 char recstr[LINE_LEN];
932 for(i = 0; i < pkg->recommends_count; i++) {
933 len = len + (strlen( pkg->recommends_str[i])+5);
935 temp = (char *)realloc(temp,len);
937 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
941 strncpy(temp, "Recommends:", 13);
942 for(i = 0; i < pkg->recommends_count; i++) {
943 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
944 strncat(temp, recstr, strlen(recstr));
946 strncat(temp, "\n", strlen("\n"));
949 goto UNKNOWN_FMT_FIELD;
955 /* Section | Size | Source | Status | Suggests */
956 if (strcasecmp(field, "Section") == 0) {
959 temp = (char *)realloc(temp,strlen(pkg->section)+11);
961 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
965 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
967 } else if (strcasecmp(field, "Size") == 0) {
970 temp = (char *)realloc(temp,strlen(pkg->size)+8);
972 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
976 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
978 } else if (strcasecmp(field, "Source") == 0) {
981 temp = (char *)realloc(temp,strlen(pkg->source)+10);
983 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
987 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
989 } else if (strcasecmp(field, "Status") == 0) {
991 /* Benjamin Pineau note: we should avoid direct usage of
992 * strlen(arg) without keeping "arg" for later free()
994 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
995 char *pstat=pkg_state_status_to_str(pkg->state_status);
996 char *pwant=pkg_state_want_to_str(pkg->state_want);
998 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
999 temp = (char *)realloc(temp,sum_of_sizes);
1000 if ( temp == NULL ){
1001 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1005 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
1008 if(pstat) /* pfstat can be NULL if ENOMEM */
1010 } else if (strcasecmp(field, "Suggests") == 0) {
1011 if (pkg->suggests_count) {
1013 char sugstr[LINE_LEN];
1015 for(i = 0; i < pkg->suggests_count; i++) {
1016 len = len + (strlen(pkg->suggests_str[i])+5);
1018 temp = (char *)realloc(temp,len);
1019 if ( temp == NULL ){
1020 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1024 strncpy(temp, "Suggests:", 10);
1025 for(i = 0; i < pkg->suggests_count; i++) {
1026 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
1027 strncat(temp, sugstr, strlen(sugstr));
1029 strncat(temp, "\n", strlen("\n"));
1032 goto UNKNOWN_FMT_FIELD;
1038 if (strcasecmp(field, "Tags") == 0) {
1041 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1042 if ( temp == NULL ){
1043 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1047 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1054 char *version = pkg_version_str_alloc(pkg);
1055 temp = (char *)realloc(temp,strlen(version)+14);
1056 if ( temp == NULL ){
1057 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1061 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1066 goto UNKNOWN_FMT_FIELD;
1069 if ( strlen(temp)<2 ) {
1075 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1076 if ( strlen(temp)<2 ) {
1083 void pkg_print_info(pkg_t *pkg, FILE *file)
1091 buff = pkg_formatted_info(pkg);
1094 if (strlen(buff)>2){
1095 t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
1100 void pkg_print_status(pkg_t * pkg, FILE * file)
1106 /* XXX: QUESTION: Do we actually want more fields here? The
1107 original idea was to save space by installing only what was
1108 needed for actual computation, (package, version, status,
1109 essential, conffiles). The assumption is that all other fields
1110 can be found in th available file.
1112 But, someone proposed the idea to make it possible to
1113 reconstruct a .opk from an installed package, (ie. for beaming
1114 from one handheld to another). So, maybe we actually want a few
1115 more fields here, (depends, suggests, etc.), so that that would
1116 be guaranteed to work even in the absence of more information
1117 from the available file.
1119 28-MAR-03: kergoth and I discussed this yesterday. We think
1120 the essential info needs to be here for all installed packages
1121 because they may not appear in the Packages files on various
1122 feeds. Furthermore, one should be able to install from URL or
1123 local storage without requiring a Packages file from any feed.
1126 pkg_print_field(pkg, file, "Package");
1127 pkg_print_field(pkg, file, "Version");
1128 pkg_print_field(pkg, file, "Depends");
1129 pkg_print_field(pkg, file, "Recommends");
1130 pkg_print_field(pkg, file, "Suggests");
1131 pkg_print_field(pkg, file, "Provides");
1132 pkg_print_field(pkg, file, "Replaces");
1133 pkg_print_field(pkg, file, "Conflicts");
1134 pkg_print_field(pkg, file, "Status");
1135 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1136 pkg_print_field(pkg, file, "Architecture");
1137 pkg_print_field(pkg, file, "Conffiles");
1138 pkg_print_field(pkg, file, "Installed-Time");
1139 pkg_print_field(pkg, file, "Auto-Installed");
1143 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1146 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1147 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1148 __FUNCTION__, field);
1150 buff = pkg_formatted_field(pkg, field);
1151 if (strlen(buff)>2) {
1152 fprintf(file, "%s", buff);
1160 * libdpkg - Debian packaging suite library routines
1161 * vercmp.c - comparison of version numbers
1163 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1165 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1169 if (pkg->epoch > ref_pkg->epoch) {
1173 if (pkg->epoch < ref_pkg->epoch) {
1177 r = verrevcmp(pkg->version, ref_pkg->version);
1182 r = verrevcmp(pkg->revision, ref_pkg->revision);
1190 /* assume ascii; warning: evaluates x multiple times! */
1191 #define order(x) ((x) == '~' ? -1 \
1192 : isdigit((x)) ? 0 \
1194 : isalpha((x)) ? (x) \
1197 static int verrevcmp(const char *val, const char *ref) {
1201 while (*val || *ref) {
1204 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1205 int vc= order(*val), rc= order(*ref);
1206 if (vc != rc) return vc - rc;
1210 while ( *val == '0' ) val++;
1211 while ( *ref == '0' ) ref++;
1212 while (isdigit(*val) && isdigit(*ref)) {
1213 if (!first_diff) first_diff= *val - *ref;
1216 if (isdigit(*val)) return 1;
1217 if (isdigit(*ref)) return -1;
1218 if (first_diff) return first_diff;
1223 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1227 r = pkg_compare_versions(it, ref);
1229 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1233 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1237 if (strcmp(op, "<<") == 0) {
1241 if (strcmp(op, ">>") == 0) {
1245 if (strcmp(op, "=") == 0) {
1249 fprintf(stderr, "unknown operator: %s", op);
1253 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1255 const pkg_t *a = *(const pkg_t**) p1;
1256 const pkg_t *b = *(const pkg_t**) p2;
1259 if (!a->name || !b->name) {
1260 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1261 a, a->name, b, b->name);
1265 namecmp = strcmp(a->name, b->name);
1268 vercmp = pkg_compare_versions(a, b);
1271 if (!a->arch_priority || !b->arch_priority) {
1272 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1273 a, a->arch_priority, b, b->arch_priority);
1276 if (a->arch_priority > b->arch_priority)
1278 if (a->arch_priority < b->arch_priority)
1283 int abstract_pkg_name_compare(const void *p1, const void *p2)
1285 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1286 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1287 if (!a->name || !b->name) {
1288 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1289 a, a->name, b, b->name);
1292 return strcmp(a->name, b->name);
1296 char *pkg_version_str_alloc(pkg_t *pkg)
1298 char *complete_version;
1303 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1305 epoch_str = strdup("");
1308 if (pkg->revision && strlen(pkg->revision)) {
1309 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1311 revision_str = strdup("");
1315 sprintf_alloc(&complete_version, "%s%s%s",
1316 epoch_str, pkg->version, revision_str);
1321 return complete_version;
1324 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1327 char *list_file_name = NULL;
1328 FILE *list_file = NULL;
1330 char *installed_file_name;
1333 pkg->installed_files_ref_cnt++;
1335 if (pkg->installed_files) {
1336 return pkg->installed_files;
1339 pkg->installed_files = str_list_alloc();
1340 if (pkg->installed_files == NULL) {
1341 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1345 /* For uninstalled packages, get the file list directly from the package.
1346 For installed packages, look at the package.list file in the database.
1348 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1349 if (pkg->local_filename == NULL) {
1350 return pkg->installed_files;
1352 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1353 file. In other words, change deb_extract so that it can
1354 simply return the file list as a char *[] rather than
1355 insisting on writing in to a FILE * as it does now. */
1356 list_file = tmpfile();
1357 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1360 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1361 __FUNCTION__, pkg->local_filename, strerror(err));
1362 return pkg->installed_files;
1366 sprintf_alloc(&list_file_name, "%s/%s.list",
1367 pkg->dest->info_dir, pkg->name);
1368 if (! file_exists(list_file_name)) {
1369 free(list_file_name);
1370 return pkg->installed_files;
1373 list_file = fopen(list_file_name, "r");
1374 if (list_file == NULL) {
1375 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1376 list_file_name, strerror(errno));
1377 free(list_file_name);
1378 return pkg->installed_files;
1380 free(list_file_name);
1383 rootdirlen = strlen( pkg->dest->root_dir );
1387 line = file_read_line_alloc(list_file);
1394 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1395 if( strncmp( pkg->dest->root_dir,
1398 if (*file_name == '.') {
1401 if (*file_name == '/') {
1405 /* Freed in pkg_free_installed_files */
1406 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1408 // already contains root_dir as header -> ABSOLUTE
1409 sprintf_alloc(&installed_file_name, "%s", file_name);
1411 str_list_append(pkg->installed_files, installed_file_name);
1417 return pkg->installed_files;
1420 /* XXX: CLEANUP: This function and it's counterpart,
1421 (pkg_get_installed_files), do not match our init/deinit naming
1422 convention. Nor the alloc/free convention. But, then again, neither
1423 of these conventions currrently fit the way these two functions
1425 int pkg_free_installed_files(pkg_t *pkg)
1427 pkg->installed_files_ref_cnt--;
1429 if (pkg->installed_files_ref_cnt > 0)
1432 if (pkg->installed_files) {
1433 str_list_deinit(pkg->installed_files);
1436 pkg->installed_files = NULL;
1441 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1444 char *list_file_name;
1446 //I don't think pkg_free_installed_files should be called here. Jamey
1447 //pkg_free_installed_files(pkg);
1449 sprintf_alloc(&list_file_name, "%s/%s.list",
1450 pkg->dest->info_dir, pkg->name);
1451 if (!conf->noaction) {
1452 err = unlink(list_file_name);
1453 free(list_file_name);
1462 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1464 conffile_list_elt_t *iter;
1465 conffile_t *conffile;
1471 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1472 conffile = (conffile_t *)iter->data;
1474 if (strcmp(conffile->name, file_name) == 0) {
1482 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1483 const char *script, const char *args)
1489 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1490 maintainer script within a chroot environment. */
1492 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1493 have scripts in pkg->tmp_unpack_dir. */
1494 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1495 if (pkg->dest == NULL) {
1496 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1497 __FUNCTION__, pkg->name);
1500 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1502 if (pkg->tmp_unpack_dir == NULL) {
1503 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1504 __FUNCTION__, pkg->name);
1507 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1510 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1511 if (conf->noaction) return 0;
1513 /* XXX: CLEANUP: There must be a better way to handle maintainer
1514 scripts when running with offline_root mode and/or a dest other
1515 than '/'. I've been playing around with some clever chroot
1516 tricks and I might come up with something workable. */
1518 * Attempt to provide a restricted environment for offline operation
1519 * Need the following set as a minimum:
1520 * OPKG_OFFLINE_ROOT = absolute path to root dir
1521 * D = absolute path to root dir (for OE generated postinst)
1522 * PATH = something safe (a restricted set of utilities)
1525 bool AllowOfflineMode = false;
1526 if (conf->offline_root) {
1527 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1528 setenv("D", conf->offline_root, 1);
1529 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1530 setenv("PATH", "/dev/null", 1);
1532 setenv("PATH", conf->offline_root_path, 1);
1533 AllowOfflineMode = true;
1538 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1540 if (! file_exists(path)) {
1545 if (conf->offline_root && !AllowOfflineMode) {
1546 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1551 sprintf_alloc(&cmd, "%s %s", path, args);
1558 fprintf(stderr, "%s script returned status %d\n", script, err);
1565 char *pkg_state_want_to_str(pkg_state_want_t sw)
1569 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1570 if (pkg_state_want_map[i].value == sw) {
1571 return strdup(pkg_state_want_map[i].str);
1575 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1577 return strdup("<STATE_WANT_UNKNOWN>");
1580 pkg_state_want_t pkg_state_want_from_str(char *str)
1584 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1585 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1586 return pkg_state_want_map[i].value;
1590 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1595 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1598 int len = 3; /* ok\000 is minimum */
1601 /* clear the temporary flags before converting to string */
1602 sf &= SF_NONVOLATILE_FLAGS;
1605 return strdup("ok");
1608 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1609 if (sf & pkg_state_flag_map[i].value) {
1610 len += strlen(pkg_state_flag_map[i].str) + 1;
1614 if ( str == NULL ) {
1615 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1619 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1620 if (sf & pkg_state_flag_map[i].value) {
1621 strcat(str, pkg_state_flag_map[i].str);
1626 str[len-1] = 0; /* squash last comma */
1631 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1636 if (strcmp(str, "ok") == 0) {
1639 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1640 const char *sfname = pkg_state_flag_map[i].str;
1641 int sfname_len = strlen(sfname);
1642 if (strncmp(str, sfname, sfname_len) == 0) {
1643 sf |= pkg_state_flag_map[i].value;
1645 if (str[0] == ',') {
1656 char *pkg_state_status_to_str(pkg_state_status_t ss)
1660 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1661 if (pkg_state_status_map[i].value == ss) {
1662 return strdup(pkg_state_status_map[i].str);
1666 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1668 return strdup("<STATE_STATUS_UNKNOWN>");
1671 pkg_state_status_t pkg_state_status_from_str(const char *str)
1675 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1676 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1677 return pkg_state_status_map[i].value;
1681 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1683 return SS_NOT_INSTALLED;
1686 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1688 nv_pair_list_elt_t *l;
1690 if (!pkg->architecture)
1693 list_for_each_entry(l , &conf->arch_list.head, node) {
1694 nv_pair_t *nv = (nv_pair_t *)l->data;
1695 if (strcmp(nv->name, pkg->architecture) == 0) {
1696 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1701 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1705 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1707 nv_pair_list_elt_t *l;
1709 list_for_each_entry(l , &conf->arch_list.head, node) {
1710 nv_pair_t *nv = (nv_pair_t *)l->data;
1711 if (strcmp(nv->name, archname) == 0) {
1712 int priority = strtol(nv->value, NULL, 0);
1719 int pkg_info_preinstall_check(opkg_conf_t *conf)
1722 hash_table_t *pkg_hash = &conf->pkg_hash;
1723 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1724 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1726 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1727 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1728 /* update arch_priority for each package */
1729 for (i = 0; i < available_pkgs->len; i++) {
1730 pkg_t *pkg = available_pkgs->pkgs[i];
1731 int arch_priority = 1;
1734 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1735 if (pkg->architecture)
1736 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1738 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1739 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1740 pkg->arch_priority = arch_priority;
1743 for (i = 0; i < available_pkgs->len; i++) {
1744 pkg_t *pkg = available_pkgs->pkgs[i];
1745 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1746 /* clear flags and want for any uninstallable package */
1747 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1748 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1749 pkg->state_want = SW_UNKNOWN;
1750 pkg->state_flag = 0;
1753 pkg_vec_free(available_pkgs);
1755 /* update the file owner data structure */
1756 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1757 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1758 for (i = 0; i < installed_pkgs->len; i++) {
1759 pkg_t *pkg = installed_pkgs->pkgs[i];
1760 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1761 str_list_elt_t *iter;
1762 if (installed_files == NULL) {
1763 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1766 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1767 char *installed_file = (char *) iter->data;
1768 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1769 file_hash_set_file_owner(conf, installed_file, pkg);
1771 pkg_free_installed_files(pkg);
1773 pkg_vec_free(installed_pkgs);
1778 struct pkg_write_filelist_data {
1784 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1786 struct pkg_write_filelist_data *data = data_;
1787 pkg_t *entry = entry_;
1788 if (entry == data->pkg) {
1789 fprintf(data->stream, "%s\n", key);
1793 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1795 struct pkg_write_filelist_data data;
1796 char *list_file_name = NULL;
1800 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1803 opkg_message(conf, OPKG_INFO,
1804 " creating %s.list file\n", pkg->name);
1805 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1806 if (!list_file_name) {
1807 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1810 opkg_message(conf, OPKG_INFO,
1811 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1812 data.stream = fopen(list_file_name, "w");
1814 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1815 list_file_name, strerror(errno));
1820 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1821 fclose(data.stream);
1822 free(list_file_name);
1824 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1829 int pkg_write_changed_filelists(opkg_conf_t *conf)
1831 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1832 hash_table_t *pkg_hash = &conf->pkg_hash;
1838 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1839 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1840 for (i = 0; i < installed_pkgs->len; i++) {
1841 pkg_t *pkg = installed_pkgs->pkgs[i];
1842 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1843 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1844 err = pkg_write_filelist(conf, pkg);
1846 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1849 pkg_vec_free (installed_pkgs);