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 pkg_deinit(pkg_t *pkg)
154 /* revision and familiar_revision share storage with version, so
156 pkg->revision = NULL;
157 pkg->familiar_revision = NULL;
158 /* owned by opkg_conf_t */
160 /* owned by opkg_conf_t */
162 free(pkg->architecture);
163 pkg->architecture = NULL;
164 free(pkg->maintainer);
165 pkg->maintainer = NULL;
168 free(pkg->description);
169 pkg->description = NULL;
170 pkg->state_want = SW_UNKNOWN;
171 pkg->state_flag = SF_OK;
172 pkg->state_status = SS_NOT_INSTALLED;
174 for (i = 0; i < pkg->depends_count; i++)
175 free (pkg->depends_str[i]);
176 free(pkg->depends_str);
177 pkg->depends_str = NULL;
178 pkg->depends_count = 0;
180 for (i = 0; i < pkg->provides_count; i++)
181 free (pkg->provides_str[i]);
182 free(pkg->provides_str);
183 pkg->provides_str = NULL;
184 pkg->provides_count = 0;
186 for (i = 0; i < pkg->conflicts_count; i++)
187 free (pkg->conflicts_str[i]);
188 free(pkg->conflicts_str);
189 pkg->conflicts_str = NULL;
190 pkg->conflicts_count = 0;
192 for (i = 0; i < pkg->replaces_count; i++)
193 free (pkg->replaces_str[i]);
194 free(pkg->replaces_str);
195 pkg->replaces_str = NULL;
196 pkg->replaces_count = 0;
198 for (i = 0; i < pkg->recommends_count; i++)
199 free (pkg->recommends_str[i]);
200 free(pkg->recommends_str);
201 pkg->recommends_str = NULL;
202 pkg->recommends_count = 0;
206 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
209 for (x = 0; x < count; x++)
211 compound_depend_t *depends;
212 depends = &pkg->depends[x];
214 for (i = 0; i < depends->possibility_count; i++)
217 d = depends->possibilities[i];
221 free (depends->possibilities);
225 free (pkg->provides);
226 free (pkg->conflicts);
228 pkg->pre_depends_count = 0;
229 free(pkg->pre_depends_str);
230 pkg->pre_depends_str = NULL;
231 pkg->provides_count = 0;
233 pkg->filename = NULL;
234 free(pkg->local_filename);
235 pkg->local_filename = NULL;
236 /* CLEANUP: It'd be nice to pullin the cleanup function from
237 opkg_install.c here. See comment in
238 opkg_install.c:cleanup_temporary_files */
239 free(pkg->tmp_unpack_dir);
240 pkg->tmp_unpack_dir = NULL;
245 free(pkg->installed_size);
246 pkg->installed_size = NULL;
248 pkg->priority = NULL;
251 conffile_list_deinit(&pkg->conffiles);
252 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
253 since if they are calling deinit, they should know. Maybe do an
254 assertion here instead? */
255 pkg->installed_files_ref_cnt = 1;
256 pkg_free_installed_files(pkg);
262 int pkg_init_from_file(pkg_t *pkg, const char *filename)
269 if (err) { return err; }
271 pkg->local_filename = strdup(filename);
273 control_file = tmpfile();
274 err = pkg_extract_control_file_to_stream(pkg, control_file);
275 if (err) { return err; }
277 rewind(control_file);
278 raw = read_raw_pkgs_from_stream(control_file);
279 pkg_parse_raw(pkg, &raw, NULL, NULL);
281 fclose(control_file);
286 /* Merge any new information in newpkg into oldpkg */
287 /* XXX: CLEANUP: This function shouldn't actually modify anything in
288 newpkg, but should leave it usable. This rework is so that
289 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
291 * uh, i thought that i had originally written this so that it took
292 * two pkgs and returned a new one? we can do that again... -sma
294 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
296 if (oldpkg == newpkg) {
301 oldpkg->src = newpkg->src;
303 oldpkg->dest = newpkg->dest;
304 if (!oldpkg->architecture)
305 oldpkg->architecture = str_dup_safe(newpkg->architecture);
306 if (!oldpkg->arch_priority)
307 oldpkg->arch_priority = newpkg->arch_priority;
308 if (!oldpkg->section)
309 oldpkg->section = str_dup_safe(newpkg->section);
310 if(!oldpkg->maintainer)
311 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
312 if(!oldpkg->description)
313 oldpkg->description = str_dup_safe(newpkg->description);
315 /* merge the state_flags from the new package */
316 oldpkg->state_want = newpkg->state_want;
317 oldpkg->state_status = newpkg->state_status;
318 oldpkg->state_flag = newpkg->state_flag;
320 if (oldpkg->state_want == SW_UNKNOWN)
321 oldpkg->state_want = newpkg->state_want;
322 if (oldpkg->state_status == SS_NOT_INSTALLED)
323 oldpkg->state_status = newpkg->state_status;
324 oldpkg->state_flag |= newpkg->state_flag;
327 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
328 oldpkg->depends_str = newpkg->depends_str;
329 newpkg->depends_str = NULL;
330 oldpkg->depends_count = newpkg->depends_count;
331 newpkg->depends_count = 0;
333 oldpkg->depends = newpkg->depends;
334 newpkg->depends = NULL;
336 oldpkg->pre_depends_str = newpkg->pre_depends_str;
337 newpkg->pre_depends_str = NULL;
338 oldpkg->pre_depends_count = newpkg->pre_depends_count;
339 newpkg->pre_depends_count = 0;
341 oldpkg->recommends_str = newpkg->recommends_str;
342 newpkg->recommends_str = NULL;
343 oldpkg->recommends_count = newpkg->recommends_count;
344 newpkg->recommends_count = 0;
346 oldpkg->suggests_str = newpkg->suggests_str;
347 newpkg->suggests_str = NULL;
348 oldpkg->suggests_count = newpkg->suggests_count;
349 newpkg->suggests_count = 0;
352 if (!oldpkg->provides_str) {
353 oldpkg->provides_str = newpkg->provides_str;
354 newpkg->provides_str = NULL;
355 oldpkg->provides_count = newpkg->provides_count;
356 newpkg->provides_count = 0;
358 oldpkg->provides = newpkg->provides;
359 newpkg->provides = NULL;
362 if (!oldpkg->conflicts_str) {
363 oldpkg->conflicts_str = newpkg->conflicts_str;
364 newpkg->conflicts_str = NULL;
365 oldpkg->conflicts_count = newpkg->conflicts_count;
366 newpkg->conflicts_count = 0;
368 oldpkg->conflicts = newpkg->conflicts;
369 newpkg->conflicts = NULL;
372 if (!oldpkg->replaces_str) {
373 oldpkg->replaces_str = newpkg->replaces_str;
374 newpkg->replaces_str = NULL;
375 oldpkg->replaces_count = newpkg->replaces_count;
376 newpkg->replaces_count = 0;
378 oldpkg->replaces = newpkg->replaces;
379 newpkg->replaces = NULL;
382 if (!oldpkg->filename)
383 oldpkg->filename = str_dup_safe(newpkg->filename);
385 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
386 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
387 if (!oldpkg->local_filename)
388 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
389 if (!oldpkg->tmp_unpack_dir)
390 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
392 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
394 oldpkg->size = str_dup_safe(newpkg->size);
395 if (!oldpkg->installed_size)
396 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
397 if (!oldpkg->priority)
398 oldpkg->priority = str_dup_safe(newpkg->priority);
400 oldpkg->source = str_dup_safe(newpkg->source);
401 if (oldpkg->conffiles.head == NULL){
402 oldpkg->conffiles = newpkg->conffiles;
403 conffile_list_init(&newpkg->conffiles);
405 if (!oldpkg->installed_files){
406 oldpkg->installed_files = newpkg->installed_files;
407 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
408 newpkg->installed_files = NULL;
410 if (!oldpkg->essential)
411 oldpkg->essential = newpkg->essential;
416 abstract_pkg_t *abstract_pkg_new(void)
418 abstract_pkg_t * ab_pkg;
420 ab_pkg = malloc(sizeof(abstract_pkg_t));
422 if (ab_pkg == NULL) {
423 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
427 if ( abstract_pkg_init(ab_pkg) < 0 )
433 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
435 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
437 ab_pkg->provided_by = abstract_pkg_vec_alloc();
438 if (ab_pkg->provided_by==NULL){
441 ab_pkg->dependencies_checked = 0;
442 ab_pkg->state_status = SS_NOT_INSTALLED;
447 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
450 char **raw_start=NULL;
452 temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
453 if (temp_str == NULL ){
454 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
457 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
459 raw = raw_start = read_raw_pkgs_from_file(temp_str);
461 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
466 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
467 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
483 char * pkg_formatted_info(pkg_t *pkg )
490 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
496 line = pkg_formatted_field(pkg, "Package");
497 strncat(buff ,line, strlen(line));
500 line = pkg_formatted_field(pkg, "Version");
501 strncat(buff ,line, strlen(line));
504 line = pkg_formatted_field(pkg, "Depends");
505 strncat(buff ,line, strlen(line));
508 line = pkg_formatted_field(pkg, "Recommends");
509 strncat(buff ,line, strlen(line));
512 line = pkg_formatted_field(pkg, "Suggests");
513 strncat(buff ,line, strlen(line));
516 line = pkg_formatted_field(pkg, "Provides");
517 strncat(buff ,line, strlen(line));
520 line = pkg_formatted_field(pkg, "Replaces");
521 strncat(buff ,line, strlen(line));
524 line = pkg_formatted_field(pkg, "Conflicts");
525 strncat(buff ,line, strlen(line));
528 line = pkg_formatted_field(pkg, "Status");
529 strncat(buff ,line, strlen(line));
532 line = pkg_formatted_field(pkg, "Section");
533 strncat(buff ,line, strlen(line));
536 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
537 strncat(buff ,line, strlen(line));
540 line = pkg_formatted_field(pkg, "Architecture");
541 strncat(buff ,line, strlen(line));
544 line = pkg_formatted_field(pkg, "Maintainer");
545 strncat(buff ,line, strlen(line));
548 line = pkg_formatted_field(pkg, "MD5sum");
549 strncat(buff ,line, strlen(line));
552 line = pkg_formatted_field(pkg, "Size");
553 strncat(buff ,line, strlen(line));
556 line = pkg_formatted_field(pkg, "Filename");
557 strncat(buff ,line, strlen(line));
560 line = pkg_formatted_field(pkg, "Conffiles");
561 strncat(buff ,line, strlen(line));
564 line = pkg_formatted_field(pkg, "Source");
565 strncat(buff ,line, strlen(line));
568 line = pkg_formatted_field(pkg, "Description");
569 strncat(buff ,line, strlen(line));
572 line = pkg_formatted_field(pkg, "Installed-Time");
573 strncat(buff ,line, strlen(line));
576 line = pkg_formatted_field(pkg, "Tags");
577 strncat(buff ,line, strlen(line));
583 char * pkg_formatted_field(pkg_t *pkg, const char *field )
585 static size_t LINE_LEN = 128;
586 char * temp = (char *)malloc(1);
588 int flag_provide_false = 0;
591 Pigi: After some discussion with Florian we decided to modify the full procedure in
592 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
595 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
596 goto UNKNOWN_FMT_FIELD;
605 if (strcasecmp(field, "Architecture") == 0) {
607 if (pkg->architecture) {
608 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
610 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
614 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
616 } else if (strcasecmp(field, "Auto-Installed") == 0) {
617 /* Auto-Installed flag */
618 if (pkg->auto_installed) {
619 char * s = "Auto-Installed: yes\n";
620 temp = (char *)realloc(temp, strlen(s) + 1);
624 goto UNKNOWN_FMT_FIELD;
629 if (strcasecmp(field, "Conffiles") == 0) {
631 conffile_list_elt_t *iter;
632 char confstr[LINE_LEN];
634 if (pkg->conffiles.head == NULL) {
639 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
640 if (iter->data->name && iter->data->value) {
641 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
644 temp = (char *)realloc(temp,len);
646 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
650 strncpy(temp, "Conffiles:\n", 12);
651 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
652 if (iter->data->name && iter->data->value) {
653 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
654 strncat(temp, confstr, strlen(confstr));
657 } else if (strcasecmp(field, "Conflicts") == 0) {
660 if (pkg->conflicts_count) {
661 char conflictstr[LINE_LEN];
663 for(i = 0; i < pkg->conflicts_count; i++) {
664 len = len + (strlen(pkg->conflicts_str[i])+5);
666 temp = (char *)realloc(temp,len);
668 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
672 strncpy(temp, "Conflicts:", 11);
673 for(i = 0; i < pkg->conflicts_count; i++) {
674 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
675 strncat(temp, conflictstr, strlen(conflictstr));
677 strncat(temp, "\n", strlen("\n"));
680 goto UNKNOWN_FMT_FIELD;
685 if (strcasecmp(field, "Depends") == 0) {
689 if (pkg->depends_count) {
690 char depstr[LINE_LEN];
692 for(i = 0; i < pkg->depends_count; i++) {
693 len = len + (strlen(pkg->depends_str[i])+4);
695 temp = (char *)realloc(temp,len);
697 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
701 strncpy(temp, "Depends:", 10);
702 for(i = 0; i < pkg->depends_count; i++) {
703 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
704 strncat(temp, depstr, strlen(depstr));
706 strncat(temp, "\n", strlen("\n"));
708 } else if (strcasecmp(field, "Description") == 0) {
710 if (pkg->description) {
711 temp = (char *)realloc(temp,strlen(pkg->description)+16);
713 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
717 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
720 goto UNKNOWN_FMT_FIELD;
726 if (pkg->essential) {
727 temp = (char *)realloc(temp,16);
729 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
733 snprintf(temp, (16), "Essential: yes\n");
741 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
743 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
747 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
753 if (strcasecmp(field, "Installed-Size") == 0) {
755 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
757 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
761 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
762 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
763 temp = (char *)realloc(temp,29);
765 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
769 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
775 /* Maintainer | MD5sum */
776 if (strcasecmp(field, "Maintainer") == 0) {
778 if (pkg->maintainer) {
779 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
781 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
785 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
787 } else if (strcasecmp(field, "MD5sum") == 0) {
790 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
792 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
796 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
799 goto UNKNOWN_FMT_FIELD;
805 if (strcasecmp(field, "Package") == 0) {
807 temp = (char *)realloc(temp,strlen(pkg->name)+11);
809 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
813 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
814 } else if (strcasecmp(field, "Priority") == 0) {
816 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
818 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
822 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
823 } else if (strcasecmp(field, "Provides") == 0) {
827 if (pkg->provides_count) {
828 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
829 for ( i=0; i < pkg->provides_count; i++ ){
830 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
831 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
832 flag_provide_false = 1;
835 if ( !flag_provide_false || /* Pigi there is not my trick flag */
836 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
837 char provstr[LINE_LEN];
839 for(i = 0; i < pkg->provides_count; i++) {
840 len = len + (strlen(pkg->provides_str[i])+5);
842 temp = (char *)realloc(temp,len);
844 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
848 strncpy(temp, "Provides:", 12);
849 for(i = 0; i < pkg->provides_count; i++) {
850 if (strlen(pkg->provides_str[i])>0){;
851 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
852 strncat(temp, provstr, strlen(provstr));
855 strncat(temp, "\n", strlen("\n"));
859 goto UNKNOWN_FMT_FIELD;
866 /* Replaces | Recommends*/
867 if (strcasecmp (field, "Replaces") == 0) {
868 if (pkg->replaces_count) {
869 char replstr[LINE_LEN];
871 for (i = 0; i < pkg->replaces_count; i++) {
872 len = len + (strlen(pkg->replaces_str[i])+5);
874 temp = (char *)realloc(temp,len);
876 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
880 strncpy(temp, "Replaces:", 12);
881 for (i = 0; i < pkg->replaces_count; i++) {
882 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
883 strncat(temp, replstr, strlen(replstr));
885 strncat(temp, "\n", strlen("\n"));
887 } else if (strcasecmp (field, "Recommends") == 0) {
888 if (pkg->recommends_count) {
889 char recstr[LINE_LEN];
891 for(i = 0; i < pkg->recommends_count; i++) {
892 len = len + (strlen( pkg->recommends_str[i])+5);
894 temp = (char *)realloc(temp,len);
896 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
900 strncpy(temp, "Recommends:", 13);
901 for(i = 0; i < pkg->recommends_count; i++) {
902 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
903 strncat(temp, recstr, strlen(recstr));
905 strncat(temp, "\n", strlen("\n"));
908 goto UNKNOWN_FMT_FIELD;
914 /* Section | Size | Source | Status | Suggests */
915 if (strcasecmp(field, "Section") == 0) {
918 temp = (char *)realloc(temp,strlen(pkg->section)+11);
920 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
924 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
926 } else if (strcasecmp(field, "Size") == 0) {
929 temp = (char *)realloc(temp,strlen(pkg->size)+8);
931 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
935 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
937 } else if (strcasecmp(field, "Source") == 0) {
940 temp = (char *)realloc(temp,strlen(pkg->source)+10);
942 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
946 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
948 } else if (strcasecmp(field, "Status") == 0) {
950 /* Benjamin Pineau note: we should avoid direct usage of
951 * strlen(arg) without keeping "arg" for later free()
953 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
954 char *pstat=pkg_state_status_to_str(pkg->state_status);
955 char *pwant=pkg_state_want_to_str(pkg->state_want);
957 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
958 temp = (char *)realloc(temp,sum_of_sizes);
960 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
964 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
967 if(pstat) /* pfstat can be NULL if ENOMEM */
969 } else if (strcasecmp(field, "Suggests") == 0) {
970 if (pkg->suggests_count) {
972 char sugstr[LINE_LEN];
974 for(i = 0; i < pkg->suggests_count; i++) {
975 len = len + (strlen(pkg->suggests_str[i])+5);
977 temp = (char *)realloc(temp,len);
979 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
983 strncpy(temp, "Suggests:", 10);
984 for(i = 0; i < pkg->suggests_count; i++) {
985 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
986 strncat(temp, sugstr, strlen(sugstr));
988 strncat(temp, "\n", strlen("\n"));
991 goto UNKNOWN_FMT_FIELD;
997 if (strcasecmp(field, "Tags") == 0) {
1000 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1001 if ( temp == NULL ){
1002 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1006 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1013 char *version = pkg_version_str_alloc(pkg);
1014 temp = (char *)realloc(temp,strlen(version)+14);
1015 if ( temp == NULL ){
1016 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1020 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1025 goto UNKNOWN_FMT_FIELD;
1028 if ( strlen(temp)<2 ) {
1034 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1035 if ( strlen(temp)<2 ) {
1042 void pkg_print_info(pkg_t *pkg, FILE *file)
1049 buff = pkg_formatted_info(pkg);
1052 if (strlen(buff)>2){
1053 fwrite(buff, 1, strlen(buff), file);
1058 void pkg_print_status(pkg_t * pkg, FILE * file)
1064 /* XXX: QUESTION: Do we actually want more fields here? The
1065 original idea was to save space by installing only what was
1066 needed for actual computation, (package, version, status,
1067 essential, conffiles). The assumption is that all other fields
1068 can be found in th available file.
1070 But, someone proposed the idea to make it possible to
1071 reconstruct a .ipk from an installed package, (ie. for beaming
1072 from one handheld to another). So, maybe we actually want a few
1073 more fields here, (depends, suggests, etc.), so that that would
1074 be guaranteed to work even in the absence of more information
1075 from the available file.
1077 28-MAR-03: kergoth and I discussed this yesterday. We think
1078 the essential info needs to be here for all installed packages
1079 because they may not appear in the Packages files on various
1080 feeds. Furthermore, one should be able to install from URL or
1081 local storage without requiring a Packages file from any feed.
1084 pkg_print_field(pkg, file, "Package");
1085 pkg_print_field(pkg, file, "Version");
1086 pkg_print_field(pkg, file, "Depends");
1087 pkg_print_field(pkg, file, "Recommends");
1088 pkg_print_field(pkg, file, "Suggests");
1089 pkg_print_field(pkg, file, "Provides");
1090 pkg_print_field(pkg, file, "Replaces");
1091 pkg_print_field(pkg, file, "Conflicts");
1092 pkg_print_field(pkg, file, "Status");
1093 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1094 pkg_print_field(pkg, file, "Architecture");
1095 pkg_print_field(pkg, file, "Conffiles");
1096 pkg_print_field(pkg, file, "Installed-Time");
1097 pkg_print_field(pkg, file, "Auto-Installed");
1101 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1104 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1105 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1106 __FUNCTION__, field);
1108 buff = pkg_formatted_field(pkg, field);
1109 if (strlen(buff)>2) {
1110 fprintf(file, "%s", buff);
1118 * libdpkg - Debian packaging suite library routines
1119 * vercmp.c - comparison of version numbers
1121 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1123 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1127 if (pkg->epoch > ref_pkg->epoch) {
1131 if (pkg->epoch < ref_pkg->epoch) {
1135 r = verrevcmp(pkg->version, ref_pkg->version);
1140 r = verrevcmp(pkg->revision, ref_pkg->revision);
1148 /* assume ascii; warning: evaluates x multiple times! */
1149 #define order(x) ((x) == '~' ? -1 \
1150 : isdigit((x)) ? 0 \
1152 : isalpha((x)) ? (x) \
1155 static int verrevcmp(const char *val, const char *ref) {
1159 while (*val || *ref) {
1162 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1163 int vc= order(*val), rc= order(*ref);
1164 if (vc != rc) return vc - rc;
1168 while ( *val == '0' ) val++;
1169 while ( *ref == '0' ) ref++;
1170 while (isdigit(*val) && isdigit(*ref)) {
1171 if (!first_diff) first_diff= *val - *ref;
1174 if (isdigit(*val)) return 1;
1175 if (isdigit(*ref)) return -1;
1176 if (first_diff) return first_diff;
1181 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1185 r = pkg_compare_versions(it, ref);
1187 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1191 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1195 if (strcmp(op, "<<") == 0) {
1199 if (strcmp(op, ">>") == 0) {
1203 if (strcmp(op, "=") == 0) {
1207 fprintf(stderr, "unknown operator: %s", op);
1211 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1213 const pkg_t *a = *(const pkg_t**) p1;
1214 const pkg_t *b = *(const pkg_t**) p2;
1217 if (!a->name || !b->name) {
1218 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1219 a, a->name, b, b->name);
1223 namecmp = strcmp(a->name, b->name);
1226 vercmp = pkg_compare_versions(a, b);
1229 if (!a->arch_priority || !b->arch_priority) {
1230 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1231 a, a->arch_priority, b, b->arch_priority);
1234 if (a->arch_priority > b->arch_priority)
1236 if (a->arch_priority < b->arch_priority)
1241 int abstract_pkg_name_compare(const void *p1, const void *p2)
1243 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1244 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1245 if (!a->name || !b->name) {
1246 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1247 a, a->name, b, b->name);
1250 return strcmp(a->name, b->name);
1254 char *pkg_version_str_alloc(pkg_t *pkg)
1256 char *complete_version;
1261 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1263 epoch_str = strdup("");
1266 if (pkg->revision && strlen(pkg->revision)) {
1267 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1269 revision_str = strdup("");
1273 sprintf_alloc(&complete_version, "%s%s%s",
1274 epoch_str, pkg->version, revision_str);
1279 return complete_version;
1282 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1285 char *list_file_name = NULL;
1286 FILE *list_file = NULL;
1288 char *installed_file_name;
1291 pkg->installed_files_ref_cnt++;
1293 if (pkg->installed_files) {
1294 return pkg->installed_files;
1297 pkg->installed_files = str_list_alloc();
1298 if (pkg->installed_files == NULL) {
1299 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1303 /* For uninstalled packages, get the file list firectly from the package.
1304 For installed packages, look at the package.list file in the database.
1306 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1307 if (pkg->local_filename == NULL) {
1308 return pkg->installed_files;
1310 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1311 file. In other words, change deb_extract so that it can
1312 simply return the file list as a char *[] rather than
1313 insisting on writing in to a FILE * as it does now. */
1314 list_file = tmpfile();
1315 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1318 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1319 __FUNCTION__, pkg->local_filename, strerror(err));
1320 return pkg->installed_files;
1324 sprintf_alloc(&list_file_name, "%s/%s.list",
1325 pkg->dest->info_dir, pkg->name);
1326 if (! file_exists(list_file_name)) {
1327 free(list_file_name);
1328 return pkg->installed_files;
1331 list_file = fopen(list_file_name, "r");
1332 if (list_file == NULL) {
1333 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1334 list_file_name, strerror(errno));
1335 free(list_file_name);
1336 return pkg->installed_files;
1338 free(list_file_name);
1341 rootdirlen = strlen( pkg->dest->root_dir );
1345 line = file_read_line_alloc(list_file);
1352 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1353 if( strncmp( pkg->dest->root_dir,
1356 if (*file_name == '.') {
1359 if (*file_name == '/') {
1363 /* Freed in pkg_free_installed_files */
1364 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1366 // already contains root_dir as header -> ABSOLUTE
1367 sprintf_alloc(&installed_file_name, "%s", file_name);
1369 str_list_append(pkg->installed_files, installed_file_name);
1375 return pkg->installed_files;
1378 /* XXX: CLEANUP: This function and it's counterpart,
1379 (pkg_get_installed_files), do not match our init/deinit naming
1380 convention. Nor the alloc/free convention. But, then again, neither
1381 of these conventions currrently fit the way these two functions
1383 int pkg_free_installed_files(pkg_t *pkg)
1385 str_list_elt_t *iter;
1387 pkg->installed_files_ref_cnt--;
1388 if (pkg->installed_files_ref_cnt > 0) {
1392 if (pkg->installed_files) {
1394 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1395 /* malloced in pkg_get_installed_files */
1400 str_list_deinit(pkg->installed_files);
1403 pkg->installed_files = NULL;
1408 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1411 char *list_file_name;
1413 //I don't think pkg_free_installed_files should be called here. Jamey
1414 //pkg_free_installed_files(pkg);
1416 sprintf_alloc(&list_file_name, "%s/%s.list",
1417 pkg->dest->info_dir, pkg->name);
1418 if (!conf->noaction) {
1419 err = unlink(list_file_name);
1420 free(list_file_name);
1429 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1431 conffile_list_elt_t *iter;
1432 conffile_t *conffile;
1438 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1439 conffile = iter->data;
1441 if (strcmp(conffile->name, file_name) == 0) {
1449 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1450 const char *script, const char *args)
1456 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1457 maintainer script within a chroot environment. */
1459 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1460 have scripts in pkg->tmp_unpack_dir. */
1461 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1462 if (pkg->dest == NULL) {
1463 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1464 __FUNCTION__, pkg->name);
1467 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1469 if (pkg->tmp_unpack_dir == NULL) {
1470 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1471 __FUNCTION__, pkg->name);
1474 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1477 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1478 if (conf->noaction) return 0;
1480 /* XXX: CLEANUP: There must be a better way to handle maintainer
1481 scripts when running with offline_root mode and/or a dest other
1482 than '/'. I've been playing around with some clever chroot
1483 tricks and I might come up with something workable. */
1484 if (conf->offline_root) {
1485 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1489 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1491 if (! file_exists(path)) {
1496 if (conf->offline_root) {
1497 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1502 sprintf_alloc(&cmd, "%s %s", path, args);
1509 fprintf(stderr, "%s script returned status %d\n", script, err);
1516 char *pkg_state_want_to_str(pkg_state_want_t sw)
1520 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1521 if (pkg_state_want_map[i].value == sw) {
1522 return strdup(pkg_state_want_map[i].str);
1526 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1528 return strdup("<STATE_WANT_UNKNOWN>");
1531 pkg_state_want_t pkg_state_want_from_str(char *str)
1535 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1536 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1537 return pkg_state_want_map[i].value;
1541 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1546 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1549 int len = 3; /* ok\000 is minimum */
1552 /* clear the temporary flags before converting to string */
1553 sf &= SF_NONVOLATILE_FLAGS;
1556 return strdup("ok");
1559 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1560 if (sf & pkg_state_flag_map[i].value) {
1561 len += strlen(pkg_state_flag_map[i].str) + 1;
1565 if ( str == NULL ) {
1566 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1570 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1571 if (sf & pkg_state_flag_map[i].value) {
1572 strcat(str, pkg_state_flag_map[i].str);
1577 str[len-1] = 0; /* squash last comma */
1582 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1587 if (strcmp(str, "ok") == 0) {
1590 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1591 const char *sfname = pkg_state_flag_map[i].str;
1592 int sfname_len = strlen(sfname);
1593 if (strncmp(str, sfname, sfname_len) == 0) {
1594 sf |= pkg_state_flag_map[i].value;
1596 if (str[0] == ',') {
1607 char *pkg_state_status_to_str(pkg_state_status_t ss)
1611 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1612 if (pkg_state_status_map[i].value == ss) {
1613 return strdup(pkg_state_status_map[i].str);
1617 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1619 return strdup("<STATE_STATUS_UNKNOWN>");
1622 pkg_state_status_t pkg_state_status_from_str(const char *str)
1626 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1627 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1628 return pkg_state_status_map[i].value;
1632 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1634 return SS_NOT_INSTALLED;
1637 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1639 nv_pair_list_elt_t *l;
1641 if (!pkg->architecture)
1644 l = conf->arch_list.head;
1647 nv_pair_t *nv = l->data;
1648 if (strcmp(nv->name, pkg->architecture) == 0) {
1649 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1655 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1659 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1661 nv_pair_list_elt_t *l;
1663 l = conf->arch_list.head;
1666 nv_pair_t *nv = l->data;
1667 if (strcmp(nv->name, archname) == 0) {
1668 int priority = strtol(nv->value, NULL, 0);
1676 int pkg_info_preinstall_check(opkg_conf_t *conf)
1679 hash_table_t *pkg_hash = &conf->pkg_hash;
1680 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1681 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1683 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1684 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1685 /* update arch_priority for each package */
1686 for (i = 0; i < available_pkgs->len; i++) {
1687 pkg_t *pkg = available_pkgs->pkgs[i];
1688 int arch_priority = 1;
1691 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1692 if (pkg->architecture)
1693 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1695 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1696 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1697 pkg->arch_priority = arch_priority;
1700 for (i = 0; i < available_pkgs->len; i++) {
1701 pkg_t *pkg = available_pkgs->pkgs[i];
1702 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1703 /* clear flags and want for any uninstallable package */
1704 opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1705 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1706 pkg->state_want = SW_UNKNOWN;
1707 pkg->state_flag = 0;
1710 pkg_vec_free(available_pkgs);
1712 /* update the file owner data structure */
1713 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1714 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1715 for (i = 0; i < installed_pkgs->len; i++) {
1716 pkg_t *pkg = installed_pkgs->pkgs[i];
1717 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1718 str_list_elt_t *iter;
1719 if (installed_files == NULL) {
1720 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1723 for (iter = installed_files->head; iter; iter = iter->next) {
1724 char *installed_file = iter->data;
1725 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1726 file_hash_set_file_owner(conf, installed_file, pkg);
1729 pkg_vec_free(installed_pkgs);
1734 struct pkg_write_filelist_data {
1740 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1742 struct pkg_write_filelist_data *data = data_;
1743 pkg_t *entry = entry_;
1744 if (entry == data->pkg) {
1745 fprintf(data->stream, "%s\n", key);
1749 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1751 struct pkg_write_filelist_data data;
1752 char *list_file_name = NULL;
1756 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1759 opkg_message(conf, OPKG_INFO,
1760 " creating %s.list file\n", pkg->name);
1761 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1762 if (!list_file_name) {
1763 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1766 opkg_message(conf, OPKG_INFO,
1767 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1768 data.stream = fopen(list_file_name, "w");
1770 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1771 list_file_name, strerror(errno));
1776 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1777 fclose(data.stream);
1778 free(list_file_name);
1783 int pkg_write_changed_filelists(opkg_conf_t *conf)
1785 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1786 hash_table_t *pkg_hash = &conf->pkg_hash;
1792 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1793 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1794 for (i = 0; i < installed_pkgs->len; i++) {
1795 pkg_t *pkg = installed_pkgs->pkgs[i];
1796 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1797 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1798 err = pkg_write_filelist(conf, pkg);
1800 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);