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.
25 #include "pkg_parse.h"
26 #include "pkg_extract.h"
27 #include "opkg_message.h"
28 #include "opkg_utils.h"
30 #include "sprintf_alloc.h"
31 #include "file_util.h"
34 #include "opkg_conf.h"
36 typedef struct enum_map enum_map_t;
43 static const enum_map_t pkg_state_want_map[] = {
44 { SW_UNKNOWN, "unknown"},
45 { SW_INSTALL, "install"},
46 { SW_DEINSTALL, "deinstall"},
50 static const enum_map_t pkg_state_flag_map[] = {
52 { SF_REINSTREQ, "reinstreq"},
54 { SF_REPLACE, "replace"},
55 { SF_NOPRUNE, "noprune"},
56 { SF_PREFER, "prefer"},
57 { SF_OBSOLETE, "obsolete"},
61 static const enum_map_t pkg_state_status_map[] = {
62 { SS_NOT_INSTALLED, "not-installed" },
63 { SS_UNPACKED, "unpacked" },
64 { SS_HALF_CONFIGURED, "half-configured" },
65 { SS_INSTALLED, "installed" },
66 { SS_HALF_INSTALLED, "half-installed" },
67 { SS_CONFIG_FILES, "config-files" },
68 { SS_POST_INST_FAILED, "post-inst-failed" },
69 { SS_REMOVAL_FAILED, "removal-failed" }
72 static int verrevcmp(const char *val, const char *ref);
79 pkg = malloc(sizeof(pkg_t));
81 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
90 int pkg_init(pkg_t *pkg)
92 memset(pkg, 0, sizeof(pkg_t));
97 pkg->familiar_revision = NULL;
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 /* Abhaya: added init for conflicts fields */
117 pkg->conflicts = NULL;
118 pkg->conflicts_count = 0;
120 /* added for replaces. Jamey 7/23/2002 */
121 pkg->replaces = NULL;
122 pkg->replaces_count = 0;
124 pkg->pre_depends_count = 0;
125 pkg->pre_depends_str = NULL;
126 pkg->provides_count = 0;
127 pkg->provides = NULL;
128 pkg->filename = NULL;
129 pkg->local_filename = NULL;
130 pkg->tmp_unpack_dir = NULL;
133 pkg->installed_size = NULL;
134 pkg->priority = NULL;
136 conffile_list_init(&pkg->conffiles);
137 pkg->installed_files = NULL;
138 pkg->installed_files_ref_cnt = 0;
140 pkg->provided_by_hand = 0;
145 void compound_depend_deinit (compound_depend_t *depends)
148 for (i = 0; i < depends->possibility_count; i++)
151 d = depends->possibilities[i];
155 free (depends->possibilities);
158 void pkg_deinit(pkg_t *pkg)
167 /* revision and familiar_revision share storage with version, so
169 pkg->revision = NULL;
170 pkg->familiar_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 //for (i = 0; i < pkg->replaces_count; i++)
188 free (pkg->replaces);
189 pkg->replaces = NULL;
191 for (i = 0; i < pkg->depends_count; i++)
192 free (pkg->depends_str[i]);
193 free(pkg->depends_str);
194 pkg->depends_str = NULL;
196 for (i = 0; i < pkg->provides_count; i++)
197 free (pkg->provides_str[i]);
198 free(pkg->provides_str);
199 pkg->provides_str = NULL;
201 for (i = 0; i < pkg->conflicts_count; i++)
202 free (pkg->conflicts_str[i]);
203 free(pkg->conflicts_str);
204 pkg->conflicts_str = NULL;
206 for (i = 0; i < pkg->replaces_count; i++)
207 free (pkg->replaces_str[i]);
208 free(pkg->replaces_str);
209 pkg->replaces_str = NULL;
211 for (i = 0; i < pkg->recommends_count; i++)
212 free (pkg->recommends_str[i]);
213 free(pkg->recommends_str);
214 pkg->recommends_str = NULL;
216 for (i = 0; i < pkg->suggests_count; i++)
217 free (pkg->suggests_str[i]);
218 free(pkg->suggests_str);
219 pkg->suggests_str = NULL;
223 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
226 for (x = 0; x < count; x++)
227 compound_depend_deinit (&pkg->depends[x]);
234 for (x = 0; x < pkg->conflicts_count; x++)
235 compound_depend_deinit (&pkg->conflicts[x]);
236 free (pkg->conflicts);
239 free (pkg->provides);
241 pkg->pre_depends_count = 0;
242 free(pkg->pre_depends_str);
243 pkg->pre_depends_str = NULL;
244 pkg->provides_count = 0;
246 pkg->filename = NULL;
247 free(pkg->local_filename);
248 pkg->local_filename = NULL;
249 /* CLEANUP: It'd be nice to pullin the cleanup function from
250 opkg_install.c here. See comment in
251 opkg_install.c:cleanup_temporary_files */
252 free(pkg->tmp_unpack_dir);
253 pkg->tmp_unpack_dir = NULL;
258 free(pkg->installed_size);
259 pkg->installed_size = NULL;
261 pkg->priority = NULL;
264 conffile_list_deinit(&pkg->conffiles);
265 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
266 since if they are calling deinit, they should know. Maybe do an
267 assertion here instead? */
268 pkg->installed_files_ref_cnt = 1;
269 pkg_free_installed_files(pkg);
275 int pkg_init_from_file(pkg_t *pkg, const char *filename)
282 if (err) { return err; }
284 pkg->local_filename = strdup(filename);
286 control_file = tmpfile();
287 err = pkg_extract_control_file_to_stream(pkg, control_file);
288 if (err) { return err; }
290 rewind(control_file);
291 raw = read_raw_pkgs_from_stream(control_file);
292 pkg_parse_raw(pkg, &raw, NULL, NULL);
294 fclose(control_file);
299 /* Merge any new information in newpkg into oldpkg */
300 /* XXX: CLEANUP: This function shouldn't actually modify anything in
301 newpkg, but should leave it usable. This rework is so that
302 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
304 * uh, i thought that i had originally written this so that it took
305 * two pkgs and returned a new one? we can do that again... -sma
307 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
309 if (oldpkg == newpkg) {
314 oldpkg->src = newpkg->src;
316 oldpkg->dest = newpkg->dest;
317 if (!oldpkg->architecture)
318 oldpkg->architecture = str_dup_safe(newpkg->architecture);
319 if (!oldpkg->arch_priority)
320 oldpkg->arch_priority = newpkg->arch_priority;
321 if (!oldpkg->section)
322 oldpkg->section = str_dup_safe(newpkg->section);
323 if(!oldpkg->maintainer)
324 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
325 if(!oldpkg->description)
326 oldpkg->description = str_dup_safe(newpkg->description);
328 /* merge the state_flags from the new package */
329 oldpkg->state_want = newpkg->state_want;
330 oldpkg->state_status = newpkg->state_status;
331 oldpkg->state_flag = newpkg->state_flag;
333 if (oldpkg->state_want == SW_UNKNOWN)
334 oldpkg->state_want = newpkg->state_want;
335 if (oldpkg->state_status == SS_NOT_INSTALLED)
336 oldpkg->state_status = newpkg->state_status;
337 oldpkg->state_flag |= newpkg->state_flag;
340 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
341 oldpkg->depends_str = newpkg->depends_str;
342 newpkg->depends_str = NULL;
343 oldpkg->depends_count = newpkg->depends_count;
344 newpkg->depends_count = 0;
346 oldpkg->depends = newpkg->depends;
347 newpkg->depends = NULL;
349 oldpkg->pre_depends_str = newpkg->pre_depends_str;
350 newpkg->pre_depends_str = NULL;
351 oldpkg->pre_depends_count = newpkg->pre_depends_count;
352 newpkg->pre_depends_count = 0;
354 oldpkg->recommends_str = newpkg->recommends_str;
355 newpkg->recommends_str = NULL;
356 oldpkg->recommends_count = newpkg->recommends_count;
357 newpkg->recommends_count = 0;
359 oldpkg->suggests_str = newpkg->suggests_str;
360 newpkg->suggests_str = NULL;
361 oldpkg->suggests_count = newpkg->suggests_count;
362 newpkg->suggests_count = 0;
365 if (!oldpkg->provides_str) {
366 oldpkg->provides_str = newpkg->provides_str;
367 newpkg->provides_str = NULL;
368 oldpkg->provides_count = newpkg->provides_count;
369 newpkg->provides_count = 0;
371 oldpkg->provides = newpkg->provides;
372 newpkg->provides = NULL;
375 if (!oldpkg->conflicts_str) {
376 oldpkg->conflicts_str = newpkg->conflicts_str;
377 newpkg->conflicts_str = NULL;
378 oldpkg->conflicts_count = newpkg->conflicts_count;
379 newpkg->conflicts_count = 0;
381 oldpkg->conflicts = newpkg->conflicts;
382 newpkg->conflicts = NULL;
385 if (!oldpkg->replaces_str) {
386 oldpkg->replaces_str = newpkg->replaces_str;
387 newpkg->replaces_str = NULL;
388 oldpkg->replaces_count = newpkg->replaces_count;
389 newpkg->replaces_count = 0;
391 oldpkg->replaces = newpkg->replaces;
392 newpkg->replaces = NULL;
395 if (!oldpkg->filename)
396 oldpkg->filename = str_dup_safe(newpkg->filename);
398 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
399 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
400 if (!oldpkg->local_filename)
401 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
402 if (!oldpkg->tmp_unpack_dir)
403 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
405 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
407 oldpkg->size = str_dup_safe(newpkg->size);
408 if (!oldpkg->installed_size)
409 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
410 if (!oldpkg->priority)
411 oldpkg->priority = str_dup_safe(newpkg->priority);
413 oldpkg->source = str_dup_safe(newpkg->source);
414 if (oldpkg->conffiles.head == NULL){
415 oldpkg->conffiles = newpkg->conffiles;
416 conffile_list_init(&newpkg->conffiles);
418 if (!oldpkg->installed_files){
419 oldpkg->installed_files = newpkg->installed_files;
420 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
421 newpkg->installed_files = NULL;
423 if (!oldpkg->essential)
424 oldpkg->essential = newpkg->essential;
429 abstract_pkg_t *abstract_pkg_new(void)
431 abstract_pkg_t * ab_pkg;
433 ab_pkg = malloc(sizeof(abstract_pkg_t));
435 if (ab_pkg == NULL) {
436 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
440 if ( abstract_pkg_init(ab_pkg) < 0 )
446 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
448 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
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 temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
466 if (temp_str == NULL ){
467 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
470 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
472 raw = raw_start = read_raw_pkgs_from_file(temp_str);
474 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
479 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
480 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
496 char * pkg_formatted_info(pkg_t *pkg )
503 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
509 line = pkg_formatted_field(pkg, "Package");
510 strncat(buff ,line, strlen(line));
513 line = pkg_formatted_field(pkg, "Version");
514 strncat(buff ,line, strlen(line));
517 line = pkg_formatted_field(pkg, "Depends");
518 strncat(buff ,line, strlen(line));
521 line = pkg_formatted_field(pkg, "Recommends");
522 strncat(buff ,line, strlen(line));
525 line = pkg_formatted_field(pkg, "Suggests");
526 strncat(buff ,line, strlen(line));
529 line = pkg_formatted_field(pkg, "Provides");
530 strncat(buff ,line, strlen(line));
533 line = pkg_formatted_field(pkg, "Replaces");
534 strncat(buff ,line, strlen(line));
537 line = pkg_formatted_field(pkg, "Conflicts");
538 strncat(buff ,line, strlen(line));
541 line = pkg_formatted_field(pkg, "Status");
542 strncat(buff ,line, strlen(line));
545 line = pkg_formatted_field(pkg, "Section");
546 strncat(buff ,line, strlen(line));
549 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
550 strncat(buff ,line, strlen(line));
553 line = pkg_formatted_field(pkg, "Architecture");
554 strncat(buff ,line, strlen(line));
557 line = pkg_formatted_field(pkg, "Maintainer");
558 strncat(buff ,line, strlen(line));
561 line = pkg_formatted_field(pkg, "MD5sum");
562 strncat(buff ,line, strlen(line));
565 line = pkg_formatted_field(pkg, "Size");
566 strncat(buff ,line, strlen(line));
569 line = pkg_formatted_field(pkg, "Filename");
570 strncat(buff ,line, strlen(line));
573 line = pkg_formatted_field(pkg, "Conffiles");
574 strncat(buff ,line, strlen(line));
577 line = pkg_formatted_field(pkg, "Source");
578 strncat(buff ,line, strlen(line));
581 line = pkg_formatted_field(pkg, "Description");
582 strncat(buff ,line, strlen(line));
585 line = pkg_formatted_field(pkg, "Installed-Time");
586 strncat(buff ,line, strlen(line));
589 line = pkg_formatted_field(pkg, "Tags");
590 strncat(buff ,line, strlen(line));
596 char * pkg_formatted_field(pkg_t *pkg, const char *field )
598 static size_t LINE_LEN = 128;
599 char * temp = (char *)malloc(1);
601 int flag_provide_false = 0;
604 Pigi: After some discussion with Florian we decided to modify the full procedure in
605 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
608 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
609 goto UNKNOWN_FMT_FIELD;
618 if (strcasecmp(field, "Architecture") == 0) {
620 if (pkg->architecture) {
621 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
623 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
627 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
629 } else if (strcasecmp(field, "Auto-Installed") == 0) {
630 /* Auto-Installed flag */
631 if (pkg->auto_installed) {
632 char * s = "Auto-Installed: yes\n";
633 temp = (char *)realloc(temp, strlen(s) + 1);
637 goto UNKNOWN_FMT_FIELD;
642 if (strcasecmp(field, "Conffiles") == 0) {
644 conffile_list_elt_t *iter;
645 char confstr[LINE_LEN];
647 if (pkg->conffiles.head == NULL) {
652 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
653 if (iter->data->name && iter->data->value) {
654 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
657 temp = (char *)realloc(temp,len);
659 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
663 strncpy(temp, "Conffiles:\n", 12);
664 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
665 if (iter->data->name && iter->data->value) {
666 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
667 strncat(temp, confstr, strlen(confstr));
670 } else if (strcasecmp(field, "Conflicts") == 0) {
673 if (pkg->conflicts_count) {
674 char conflictstr[LINE_LEN];
676 for(i = 0; i < pkg->conflicts_count; i++) {
677 len = len + (strlen(pkg->conflicts_str[i])+5);
679 temp = (char *)realloc(temp,len);
681 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
685 strncpy(temp, "Conflicts:", 11);
686 for(i = 0; i < pkg->conflicts_count; i++) {
687 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
688 strncat(temp, conflictstr, strlen(conflictstr));
690 strncat(temp, "\n", strlen("\n"));
693 goto UNKNOWN_FMT_FIELD;
698 if (strcasecmp(field, "Depends") == 0) {
702 if (pkg->depends_count) {
703 char depstr[LINE_LEN];
705 for(i = 0; i < pkg->depends_count; i++) {
706 len = len + (strlen(pkg->depends_str[i])+4);
708 temp = (char *)realloc(temp,len);
710 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
714 strncpy(temp, "Depends:", 10);
715 for(i = 0; i < pkg->depends_count; i++) {
716 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
717 strncat(temp, depstr, strlen(depstr));
719 strncat(temp, "\n", strlen("\n"));
721 } else if (strcasecmp(field, "Description") == 0) {
723 if (pkg->description) {
724 temp = (char *)realloc(temp,strlen(pkg->description)+16);
726 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
730 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
733 goto UNKNOWN_FMT_FIELD;
739 if (pkg->essential) {
740 temp = (char *)realloc(temp,16);
742 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
746 snprintf(temp, (16), "Essential: yes\n");
754 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
756 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
760 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
766 if (strcasecmp(field, "Installed-Size") == 0) {
768 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
770 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
774 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
775 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
776 temp = (char *)realloc(temp,29);
778 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
782 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
788 /* Maintainer | MD5sum */
789 if (strcasecmp(field, "Maintainer") == 0) {
791 if (pkg->maintainer) {
792 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
794 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
798 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
800 } else if (strcasecmp(field, "MD5sum") == 0) {
803 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
805 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
809 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
812 goto UNKNOWN_FMT_FIELD;
818 if (strcasecmp(field, "Package") == 0) {
820 temp = (char *)realloc(temp,strlen(pkg->name)+11);
822 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
826 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
827 } else if (strcasecmp(field, "Priority") == 0) {
829 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
831 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
835 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
836 } else if (strcasecmp(field, "Provides") == 0) {
840 if (pkg->provides_count) {
841 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
842 for ( i=0; i < pkg->provides_count; i++ ){
843 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
844 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
845 flag_provide_false = 1;
848 if ( !flag_provide_false || /* Pigi there is not my trick flag */
849 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
850 char provstr[LINE_LEN];
852 for(i = 0; i < pkg->provides_count; i++) {
853 len = len + (strlen(pkg->provides_str[i])+5);
855 temp = (char *)realloc(temp,len);
857 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
861 strncpy(temp, "Provides:", 12);
862 for(i = 0; i < pkg->provides_count; i++) {
863 if (strlen(pkg->provides_str[i])>0){;
864 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
865 strncat(temp, provstr, strlen(provstr));
868 strncat(temp, "\n", strlen("\n"));
872 goto UNKNOWN_FMT_FIELD;
879 /* Replaces | Recommends*/
880 if (strcasecmp (field, "Replaces") == 0) {
881 if (pkg->replaces_count) {
882 char replstr[LINE_LEN];
884 for (i = 0; i < pkg->replaces_count; i++) {
885 len = len + (strlen(pkg->replaces_str[i])+5);
887 temp = (char *)realloc(temp,len);
889 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
893 strncpy(temp, "Replaces:", 12);
894 for (i = 0; i < pkg->replaces_count; i++) {
895 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
896 strncat(temp, replstr, strlen(replstr));
898 strncat(temp, "\n", strlen("\n"));
900 } else if (strcasecmp (field, "Recommends") == 0) {
901 if (pkg->recommends_count) {
902 char recstr[LINE_LEN];
904 for(i = 0; i < pkg->recommends_count; i++) {
905 len = len + (strlen( pkg->recommends_str[i])+5);
907 temp = (char *)realloc(temp,len);
909 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
913 strncpy(temp, "Recommends:", 13);
914 for(i = 0; i < pkg->recommends_count; i++) {
915 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
916 strncat(temp, recstr, strlen(recstr));
918 strncat(temp, "\n", strlen("\n"));
921 goto UNKNOWN_FMT_FIELD;
927 /* Section | Size | Source | Status | Suggests */
928 if (strcasecmp(field, "Section") == 0) {
931 temp = (char *)realloc(temp,strlen(pkg->section)+11);
933 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
937 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
939 } else if (strcasecmp(field, "Size") == 0) {
942 temp = (char *)realloc(temp,strlen(pkg->size)+8);
944 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
948 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
950 } else if (strcasecmp(field, "Source") == 0) {
953 temp = (char *)realloc(temp,strlen(pkg->source)+10);
955 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
959 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
961 } else if (strcasecmp(field, "Status") == 0) {
963 /* Benjamin Pineau note: we should avoid direct usage of
964 * strlen(arg) without keeping "arg" for later free()
966 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
967 char *pstat=pkg_state_status_to_str(pkg->state_status);
968 char *pwant=pkg_state_want_to_str(pkg->state_want);
970 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
971 temp = (char *)realloc(temp,sum_of_sizes);
973 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
977 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
980 if(pstat) /* pfstat can be NULL if ENOMEM */
982 } else if (strcasecmp(field, "Suggests") == 0) {
983 if (pkg->suggests_count) {
985 char sugstr[LINE_LEN];
987 for(i = 0; i < pkg->suggests_count; i++) {
988 len = len + (strlen(pkg->suggests_str[i])+5);
990 temp = (char *)realloc(temp,len);
992 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
996 strncpy(temp, "Suggests:", 10);
997 for(i = 0; i < pkg->suggests_count; i++) {
998 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
999 strncat(temp, sugstr, strlen(sugstr));
1001 strncat(temp, "\n", strlen("\n"));
1004 goto UNKNOWN_FMT_FIELD;
1010 if (strcasecmp(field, "Tags") == 0) {
1013 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1014 if ( temp == NULL ){
1015 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1019 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1026 char *version = pkg_version_str_alloc(pkg);
1027 temp = (char *)realloc(temp,strlen(version)+14);
1028 if ( temp == NULL ){
1029 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1033 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1038 goto UNKNOWN_FMT_FIELD;
1041 if ( strlen(temp)<2 ) {
1047 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1048 if ( strlen(temp)<2 ) {
1055 void pkg_print_info(pkg_t *pkg, FILE *file)
1062 buff = pkg_formatted_info(pkg);
1065 if (strlen(buff)>2){
1066 fwrite(buff, 1, strlen(buff), file);
1071 void pkg_print_status(pkg_t * pkg, FILE * file)
1077 /* XXX: QUESTION: Do we actually want more fields here? The
1078 original idea was to save space by installing only what was
1079 needed for actual computation, (package, version, status,
1080 essential, conffiles). The assumption is that all other fields
1081 can be found in th available file.
1083 But, someone proposed the idea to make it possible to
1084 reconstruct a .ipk from an installed package, (ie. for beaming
1085 from one handheld to another). So, maybe we actually want a few
1086 more fields here, (depends, suggests, etc.), so that that would
1087 be guaranteed to work even in the absence of more information
1088 from the available file.
1090 28-MAR-03: kergoth and I discussed this yesterday. We think
1091 the essential info needs to be here for all installed packages
1092 because they may not appear in the Packages files on various
1093 feeds. Furthermore, one should be able to install from URL or
1094 local storage without requiring a Packages file from any feed.
1097 pkg_print_field(pkg, file, "Package");
1098 pkg_print_field(pkg, file, "Version");
1099 pkg_print_field(pkg, file, "Depends");
1100 pkg_print_field(pkg, file, "Recommends");
1101 pkg_print_field(pkg, file, "Suggests");
1102 pkg_print_field(pkg, file, "Provides");
1103 pkg_print_field(pkg, file, "Replaces");
1104 pkg_print_field(pkg, file, "Conflicts");
1105 pkg_print_field(pkg, file, "Status");
1106 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1107 pkg_print_field(pkg, file, "Architecture");
1108 pkg_print_field(pkg, file, "Conffiles");
1109 pkg_print_field(pkg, file, "Installed-Time");
1110 pkg_print_field(pkg, file, "Auto-Installed");
1114 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1117 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1118 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1119 __FUNCTION__, field);
1121 buff = pkg_formatted_field(pkg, field);
1122 if (strlen(buff)>2) {
1123 fprintf(file, "%s", buff);
1131 * libdpkg - Debian packaging suite library routines
1132 * vercmp.c - comparison of version numbers
1134 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1136 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1140 if (pkg->epoch > ref_pkg->epoch) {
1144 if (pkg->epoch < ref_pkg->epoch) {
1148 r = verrevcmp(pkg->version, ref_pkg->version);
1153 r = verrevcmp(pkg->revision, ref_pkg->revision);
1161 /* assume ascii; warning: evaluates x multiple times! */
1162 #define order(x) ((x) == '~' ? -1 \
1163 : isdigit((x)) ? 0 \
1165 : isalpha((x)) ? (x) \
1168 static int verrevcmp(const char *val, const char *ref) {
1172 while (*val || *ref) {
1175 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1176 int vc= order(*val), rc= order(*ref);
1177 if (vc != rc) return vc - rc;
1181 while ( *val == '0' ) val++;
1182 while ( *ref == '0' ) ref++;
1183 while (isdigit(*val) && isdigit(*ref)) {
1184 if (!first_diff) first_diff= *val - *ref;
1187 if (isdigit(*val)) return 1;
1188 if (isdigit(*ref)) return -1;
1189 if (first_diff) return first_diff;
1194 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1198 r = pkg_compare_versions(it, ref);
1200 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1204 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1208 if (strcmp(op, "<<") == 0) {
1212 if (strcmp(op, ">>") == 0) {
1216 if (strcmp(op, "=") == 0) {
1220 fprintf(stderr, "unknown operator: %s", op);
1224 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1226 const pkg_t *a = *(const pkg_t**) p1;
1227 const pkg_t *b = *(const pkg_t**) p2;
1230 if (!a->name || !b->name) {
1231 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1232 a, a->name, b, b->name);
1236 namecmp = strcmp(a->name, b->name);
1239 vercmp = pkg_compare_versions(a, b);
1242 if (!a->arch_priority || !b->arch_priority) {
1243 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1244 a, a->arch_priority, b, b->arch_priority);
1247 if (a->arch_priority > b->arch_priority)
1249 if (a->arch_priority < b->arch_priority)
1254 int abstract_pkg_name_compare(const void *p1, const void *p2)
1256 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1257 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1258 if (!a->name || !b->name) {
1259 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1260 a, a->name, b, b->name);
1263 return strcmp(a->name, b->name);
1267 char *pkg_version_str_alloc(pkg_t *pkg)
1269 char *complete_version;
1274 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1276 epoch_str = strdup("");
1279 if (pkg->revision && strlen(pkg->revision)) {
1280 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1282 revision_str = strdup("");
1286 sprintf_alloc(&complete_version, "%s%s%s",
1287 epoch_str, pkg->version, revision_str);
1292 return complete_version;
1295 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1298 char *list_file_name = NULL;
1299 FILE *list_file = NULL;
1301 char *installed_file_name;
1304 pkg->installed_files_ref_cnt++;
1306 if (pkg->installed_files) {
1307 return pkg->installed_files;
1310 pkg->installed_files = str_list_alloc();
1311 if (pkg->installed_files == NULL) {
1312 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1316 /* For uninstalled packages, get the file list firectly from the package.
1317 For installed packages, look at the package.list file in the database.
1319 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1320 if (pkg->local_filename == NULL) {
1321 return pkg->installed_files;
1323 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1324 file. In other words, change deb_extract so that it can
1325 simply return the file list as a char *[] rather than
1326 insisting on writing in to a FILE * as it does now. */
1327 list_file = tmpfile();
1328 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1331 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1332 __FUNCTION__, pkg->local_filename, strerror(err));
1333 return pkg->installed_files;
1337 sprintf_alloc(&list_file_name, "%s/%s.list",
1338 pkg->dest->info_dir, pkg->name);
1339 if (! file_exists(list_file_name)) {
1340 free(list_file_name);
1341 return pkg->installed_files;
1344 list_file = fopen(list_file_name, "r");
1345 if (list_file == NULL) {
1346 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1347 list_file_name, strerror(errno));
1348 free(list_file_name);
1349 return pkg->installed_files;
1351 free(list_file_name);
1354 rootdirlen = strlen( pkg->dest->root_dir );
1358 line = file_read_line_alloc(list_file);
1365 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1366 if( strncmp( pkg->dest->root_dir,
1369 if (*file_name == '.') {
1372 if (*file_name == '/') {
1376 /* Freed in pkg_free_installed_files */
1377 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1379 // already contains root_dir as header -> ABSOLUTE
1380 sprintf_alloc(&installed_file_name, "%s", file_name);
1382 str_list_append(pkg->installed_files, installed_file_name);
1388 return pkg->installed_files;
1391 /* XXX: CLEANUP: This function and it's counterpart,
1392 (pkg_get_installed_files), do not match our init/deinit naming
1393 convention. Nor the alloc/free convention. But, then again, neither
1394 of these conventions currrently fit the way these two functions
1396 int pkg_free_installed_files(pkg_t *pkg)
1398 str_list_elt_t *iter;
1400 pkg->installed_files_ref_cnt--;
1401 if (pkg->installed_files_ref_cnt > 0) {
1405 if (pkg->installed_files) {
1407 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1408 /* malloced in pkg_get_installed_files */
1413 str_list_deinit(pkg->installed_files);
1414 free (pkg->installed_files);
1417 pkg->installed_files = NULL;
1422 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1425 char *list_file_name;
1427 //I don't think pkg_free_installed_files should be called here. Jamey
1428 //pkg_free_installed_files(pkg);
1430 sprintf_alloc(&list_file_name, "%s/%s.list",
1431 pkg->dest->info_dir, pkg->name);
1432 if (!conf->noaction) {
1433 err = unlink(list_file_name);
1434 free(list_file_name);
1443 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1445 conffile_list_elt_t *iter;
1446 conffile_t *conffile;
1452 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1453 conffile = iter->data;
1455 if (strcmp(conffile->name, file_name) == 0) {
1463 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1464 const char *script, const char *args)
1470 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1471 maintainer script within a chroot environment. */
1473 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1474 have scripts in pkg->tmp_unpack_dir. */
1475 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1476 if (pkg->dest == NULL) {
1477 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1478 __FUNCTION__, pkg->name);
1481 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1483 if (pkg->tmp_unpack_dir == NULL) {
1484 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1485 __FUNCTION__, pkg->name);
1488 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1491 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1492 if (conf->noaction) return 0;
1494 /* XXX: CLEANUP: There must be a better way to handle maintainer
1495 scripts when running with offline_root mode and/or a dest other
1496 than '/'. I've been playing around with some clever chroot
1497 tricks and I might come up with something workable. */
1498 if (conf->offline_root) {
1499 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1503 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1505 if (! file_exists(path)) {
1510 if (conf->offline_root) {
1511 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1516 sprintf_alloc(&cmd, "%s %s", path, args);
1523 fprintf(stderr, "%s script returned status %d\n", script, err);
1530 char *pkg_state_want_to_str(pkg_state_want_t sw)
1534 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1535 if (pkg_state_want_map[i].value == sw) {
1536 return strdup(pkg_state_want_map[i].str);
1540 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1542 return strdup("<STATE_WANT_UNKNOWN>");
1545 pkg_state_want_t pkg_state_want_from_str(char *str)
1549 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1550 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1551 return pkg_state_want_map[i].value;
1555 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1560 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1563 int len = 3; /* ok\000 is minimum */
1566 /* clear the temporary flags before converting to string */
1567 sf &= SF_NONVOLATILE_FLAGS;
1570 return strdup("ok");
1573 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1574 if (sf & pkg_state_flag_map[i].value) {
1575 len += strlen(pkg_state_flag_map[i].str) + 1;
1579 if ( str == NULL ) {
1580 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1584 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1585 if (sf & pkg_state_flag_map[i].value) {
1586 strcat(str, pkg_state_flag_map[i].str);
1591 str[len-1] = 0; /* squash last comma */
1596 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1601 if (strcmp(str, "ok") == 0) {
1604 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1605 const char *sfname = pkg_state_flag_map[i].str;
1606 int sfname_len = strlen(sfname);
1607 if (strncmp(str, sfname, sfname_len) == 0) {
1608 sf |= pkg_state_flag_map[i].value;
1610 if (str[0] == ',') {
1621 char *pkg_state_status_to_str(pkg_state_status_t ss)
1625 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1626 if (pkg_state_status_map[i].value == ss) {
1627 return strdup(pkg_state_status_map[i].str);
1631 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1633 return strdup("<STATE_STATUS_UNKNOWN>");
1636 pkg_state_status_t pkg_state_status_from_str(const char *str)
1640 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1641 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1642 return pkg_state_status_map[i].value;
1646 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1648 return SS_NOT_INSTALLED;
1651 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1653 nv_pair_list_elt_t *l;
1655 if (!pkg->architecture)
1658 l = conf->arch_list.head;
1661 nv_pair_t *nv = l->data;
1662 if (strcmp(nv->name, pkg->architecture) == 0) {
1663 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1669 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1673 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1675 nv_pair_list_elt_t *l;
1677 l = conf->arch_list.head;
1680 nv_pair_t *nv = l->data;
1681 if (strcmp(nv->name, archname) == 0) {
1682 int priority = strtol(nv->value, NULL, 0);
1690 int pkg_info_preinstall_check(opkg_conf_t *conf)
1693 hash_table_t *pkg_hash = &conf->pkg_hash;
1694 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1695 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1697 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1698 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1699 /* update arch_priority for each package */
1700 for (i = 0; i < available_pkgs->len; i++) {
1701 pkg_t *pkg = available_pkgs->pkgs[i];
1702 int arch_priority = 1;
1705 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1706 if (pkg->architecture)
1707 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1709 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1710 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1711 pkg->arch_priority = arch_priority;
1714 for (i = 0; i < available_pkgs->len; i++) {
1715 pkg_t *pkg = available_pkgs->pkgs[i];
1716 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1717 /* clear flags and want for any uninstallable package */
1718 opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1719 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1720 pkg->state_want = SW_UNKNOWN;
1721 pkg->state_flag = 0;
1724 pkg_vec_free(available_pkgs);
1726 /* update the file owner data structure */
1727 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1728 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1729 for (i = 0; i < installed_pkgs->len; i++) {
1730 pkg_t *pkg = installed_pkgs->pkgs[i];
1731 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1732 str_list_elt_t *iter;
1733 if (installed_files == NULL) {
1734 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1737 for (iter = installed_files->head; iter; iter = iter->next) {
1738 char *installed_file = iter->data;
1739 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1740 file_hash_set_file_owner(conf, installed_file, pkg);
1743 pkg_vec_free(installed_pkgs);
1748 struct pkg_write_filelist_data {
1754 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1756 struct pkg_write_filelist_data *data = data_;
1757 pkg_t *entry = entry_;
1758 if (entry == data->pkg) {
1759 fprintf(data->stream, "%s\n", key);
1763 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1765 struct pkg_write_filelist_data data;
1766 char *list_file_name = NULL;
1770 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1773 opkg_message(conf, OPKG_INFO,
1774 " creating %s.list file\n", pkg->name);
1775 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1776 if (!list_file_name) {
1777 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1780 opkg_message(conf, OPKG_INFO,
1781 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1782 data.stream = fopen(list_file_name, "w");
1784 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1785 list_file_name, strerror(errno));
1790 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1791 fclose(data.stream);
1792 free(list_file_name);
1797 int pkg_write_changed_filelists(opkg_conf_t *conf)
1799 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1800 hash_table_t *pkg_hash = &conf->pkg_hash;
1806 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1807 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1808 for (i = 0; i < installed_pkgs->len; i++) {
1809 pkg_t *pkg = installed_pkgs->pkgs[i];
1810 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1811 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1812 err = pkg_write_filelist(conf, pkg);
1814 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1817 pkg_vec_free (installed_pkgs);