1 /* pkg.c - the itsy 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)
152 /* revision and familiar_revision share storage with version, so
154 pkg->revision = NULL;
155 pkg->familiar_revision = NULL;
156 /* owned by opkg_conf_t */
158 /* owned by opkg_conf_t */
160 free(pkg->architecture);
161 pkg->architecture = NULL;
162 free(pkg->maintainer);
163 pkg->maintainer = NULL;
166 free(pkg->description);
167 pkg->description = NULL;
168 pkg->state_want = SW_UNKNOWN;
169 pkg->state_flag = SF_OK;
170 pkg->state_status = SS_NOT_INSTALLED;
171 free(pkg->depends_str);
172 pkg->depends_str = NULL;
173 free(pkg->provides_str);
174 pkg->provides_str = NULL;
175 pkg->depends_count = 0;
176 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */
177 pkg->pre_depends_count = 0;
178 free(pkg->pre_depends_str);
179 pkg->pre_depends_str = NULL;
180 pkg->provides_count = 0;
181 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */
182 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */
184 pkg->filename = NULL;
185 free(pkg->local_filename);
186 pkg->local_filename = NULL;
187 /* CLEANUP: It'd be nice to pullin the cleanup function from
188 opkg_install.c here. See comment in
189 opkg_install.c:cleanup_temporary_files */
190 free(pkg->tmp_unpack_dir);
191 pkg->tmp_unpack_dir = NULL;
196 free(pkg->installed_size);
197 pkg->installed_size = NULL;
199 pkg->priority = NULL;
202 conffile_list_deinit(&pkg->conffiles);
203 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
204 since if they are calling deinit, they should know. Maybe do an
205 assertion here instead? */
206 pkg->installed_files_ref_cnt = 1;
207 pkg_free_installed_files(pkg);
211 int pkg_init_from_file(pkg_t *pkg, const char *filename)
218 if (err) { return err; }
220 pkg->local_filename = strdup(filename);
222 control_file = tmpfile();
223 err = pkg_extract_control_file_to_stream(pkg, control_file);
224 if (err) { return err; }
226 rewind(control_file);
227 raw = read_raw_pkgs_from_stream(control_file);
228 pkg_parse_raw(pkg, &raw, NULL, NULL);
230 fclose(control_file);
235 /* Merge any new information in newpkg into oldpkg */
236 /* XXX: CLEANUP: This function shouldn't actually modify anything in
237 newpkg, but should leave it usable. This rework is so that
238 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
240 * uh, i thought that i had originally written this so that it took
241 * two pkgs and returned a new one? we can do that again... -sma
243 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
245 if (oldpkg == newpkg) {
250 oldpkg->src = newpkg->src;
252 oldpkg->dest = newpkg->dest;
253 if (!oldpkg->architecture)
254 oldpkg->architecture = str_dup_safe(newpkg->architecture);
255 if (!oldpkg->arch_priority)
256 oldpkg->arch_priority = newpkg->arch_priority;
257 if (!oldpkg->section)
258 oldpkg->section = str_dup_safe(newpkg->section);
259 if(!oldpkg->maintainer)
260 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
261 if(!oldpkg->description)
262 oldpkg->description = str_dup_safe(newpkg->description);
264 /* merge the state_flags from the new package */
265 oldpkg->state_want = newpkg->state_want;
266 oldpkg->state_status = newpkg->state_status;
267 oldpkg->state_flag = newpkg->state_flag;
269 if (oldpkg->state_want == SW_UNKNOWN)
270 oldpkg->state_want = newpkg->state_want;
271 if (oldpkg->state_status == SS_NOT_INSTALLED)
272 oldpkg->state_status = newpkg->state_status;
273 oldpkg->state_flag |= newpkg->state_flag;
276 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
277 oldpkg->depends_str = newpkg->depends_str;
278 newpkg->depends_str = NULL;
279 oldpkg->depends_count = newpkg->depends_count;
280 newpkg->depends_count = 0;
282 oldpkg->depends = newpkg->depends;
283 newpkg->depends = NULL;
285 oldpkg->pre_depends_str = newpkg->pre_depends_str;
286 newpkg->pre_depends_str = NULL;
287 oldpkg->pre_depends_count = newpkg->pre_depends_count;
288 newpkg->pre_depends_count = 0;
290 oldpkg->recommends_str = newpkg->recommends_str;
291 newpkg->recommends_str = NULL;
292 oldpkg->recommends_count = newpkg->recommends_count;
293 newpkg->recommends_count = 0;
295 oldpkg->suggests_str = newpkg->suggests_str;
296 newpkg->suggests_str = NULL;
297 oldpkg->suggests_count = newpkg->suggests_count;
298 newpkg->suggests_count = 0;
301 if (!oldpkg->provides_str) {
302 oldpkg->provides_str = newpkg->provides_str;
303 newpkg->provides_str = NULL;
304 oldpkg->provides_count = newpkg->provides_count;
305 newpkg->provides_count = 0;
307 oldpkg->provides = newpkg->provides;
308 newpkg->provides = NULL;
311 if (!oldpkg->conflicts_str) {
312 oldpkg->conflicts_str = newpkg->conflicts_str;
313 newpkg->conflicts_str = NULL;
314 oldpkg->conflicts_count = newpkg->conflicts_count;
315 newpkg->conflicts_count = 0;
317 oldpkg->conflicts = newpkg->conflicts;
318 newpkg->conflicts = NULL;
321 if (!oldpkg->replaces_str) {
322 oldpkg->replaces_str = newpkg->replaces_str;
323 newpkg->replaces_str = NULL;
324 oldpkg->replaces_count = newpkg->replaces_count;
325 newpkg->replaces_count = 0;
327 oldpkg->replaces = newpkg->replaces;
328 newpkg->replaces = NULL;
331 if (!oldpkg->filename)
332 oldpkg->filename = str_dup_safe(newpkg->filename);
334 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
335 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
336 if (!oldpkg->local_filename)
337 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
338 if (!oldpkg->tmp_unpack_dir)
339 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
341 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
343 oldpkg->size = str_dup_safe(newpkg->size);
344 if (!oldpkg->installed_size)
345 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
346 if (!oldpkg->priority)
347 oldpkg->priority = str_dup_safe(newpkg->priority);
349 oldpkg->source = str_dup_safe(newpkg->source);
350 if (oldpkg->conffiles.head == NULL){
351 oldpkg->conffiles = newpkg->conffiles;
352 conffile_list_init(&newpkg->conffiles);
354 if (!oldpkg->installed_files){
355 oldpkg->installed_files = newpkg->installed_files;
356 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
357 newpkg->installed_files = NULL;
359 if (!oldpkg->essential)
360 oldpkg->essential = newpkg->essential;
365 abstract_pkg_t *abstract_pkg_new(void)
367 abstract_pkg_t * ab_pkg;
369 ab_pkg = malloc(sizeof(abstract_pkg_t));
371 if (ab_pkg == NULL) {
372 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
376 if ( abstract_pkg_init(ab_pkg) < 0 )
382 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
384 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
386 ab_pkg->provided_by = abstract_pkg_vec_alloc();
387 if (ab_pkg->provided_by==NULL){
390 ab_pkg->dependencies_checked = 0;
391 ab_pkg->state_status = SS_NOT_INSTALLED;
396 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
399 char **raw_start=NULL;
401 temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
402 if (temp_str == NULL ){
403 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
406 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
408 raw = raw_start = read_raw_pkgs_from_file(temp_str);
410 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
415 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
416 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
432 char * pkg_formatted_info(pkg_t *pkg )
439 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
445 line = pkg_formatted_field(pkg, "Package");
446 strncat(buff ,line, strlen(line));
449 line = pkg_formatted_field(pkg, "Version");
450 strncat(buff ,line, strlen(line));
453 line = pkg_formatted_field(pkg, "Depends");
454 strncat(buff ,line, strlen(line));
457 line = pkg_formatted_field(pkg, "Recommends");
458 strncat(buff ,line, strlen(line));
461 line = pkg_formatted_field(pkg, "Suggests");
462 strncat(buff ,line, strlen(line));
465 line = pkg_formatted_field(pkg, "Provides");
466 strncat(buff ,line, strlen(line));
469 line = pkg_formatted_field(pkg, "Replaces");
470 strncat(buff ,line, strlen(line));
473 line = pkg_formatted_field(pkg, "Conflicts");
474 strncat(buff ,line, strlen(line));
477 line = pkg_formatted_field(pkg, "Status");
478 strncat(buff ,line, strlen(line));
481 line = pkg_formatted_field(pkg, "Section");
482 strncat(buff ,line, strlen(line));
485 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
486 strncat(buff ,line, strlen(line));
489 line = pkg_formatted_field(pkg, "Architecture");
490 strncat(buff ,line, strlen(line));
493 line = pkg_formatted_field(pkg, "Maintainer");
494 strncat(buff ,line, strlen(line));
497 line = pkg_formatted_field(pkg, "MD5sum");
498 strncat(buff ,line, strlen(line));
501 line = pkg_formatted_field(pkg, "Size");
502 strncat(buff ,line, strlen(line));
505 line = pkg_formatted_field(pkg, "Filename");
506 strncat(buff ,line, strlen(line));
509 line = pkg_formatted_field(pkg, "Conffiles");
510 strncat(buff ,line, strlen(line));
513 line = pkg_formatted_field(pkg, "Source");
514 strncat(buff ,line, strlen(line));
517 line = pkg_formatted_field(pkg, "Description");
518 strncat(buff ,line, strlen(line));
521 line = pkg_formatted_field(pkg, "Installed-Time");
522 strncat(buff ,line, strlen(line));
528 char * pkg_formatted_field(pkg_t *pkg, const char *field )
530 static size_t LINE_LEN = 128;
531 char * temp = (char *)malloc(1);
533 int flag_provide_false = 0;
536 Pigi: After some discussion with Florian we decided to modify the full procedure in
537 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
540 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
541 goto UNKNOWN_FMT_FIELD;
550 if (strcasecmp(field, "Architecture") == 0) {
552 if (pkg->architecture) {
553 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
555 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
559 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
561 } else if (strcasecmp(field, "Auto-Installed") == 0) {
562 /* Auto-Installed flag */
563 if (pkg->auto_installed) {
564 char * s = "Auto-Installed: yes\n";
565 temp = (char *)realloc(temp, strlen(s) + 1);
569 goto UNKNOWN_FMT_FIELD;
574 if (strcasecmp(field, "Conffiles") == 0) {
576 conffile_list_elt_t *iter;
577 char confstr[LINE_LEN];
579 if (pkg->conffiles.head == NULL) {
584 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
585 if (iter->data->name && iter->data->value) {
586 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
589 temp = (char *)realloc(temp,len);
591 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
595 strncpy(temp, "Conffiles:\n", 12);
596 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
597 if (iter->data->name && iter->data->value) {
598 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
599 strncat(temp, confstr, strlen(confstr));
602 } else if (strcasecmp(field, "Conflicts") == 0) {
605 if (pkg->conflicts_count) {
606 char conflictstr[LINE_LEN];
608 for(i = 0; i < pkg->conflicts_count; i++) {
609 len = len + (strlen(pkg->conflicts_str[i])+5);
611 temp = (char *)realloc(temp,len);
613 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
617 strncpy(temp, "Conflicts:", 11);
618 for(i = 0; i < pkg->conflicts_count; i++) {
619 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
620 strncat(temp, conflictstr, strlen(conflictstr));
622 strncat(temp, "\n", strlen("\n"));
625 goto UNKNOWN_FMT_FIELD;
630 if (strcasecmp(field, "Depends") == 0) {
634 if (pkg->depends_count) {
635 char depstr[LINE_LEN];
637 for(i = 0; i < pkg->depends_count; i++) {
638 len = len + (strlen(pkg->depends_str[i])+4);
640 temp = (char *)realloc(temp,len);
642 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
646 strncpy(temp, "Depends:", 10);
647 for(i = 0; i < pkg->depends_count; i++) {
648 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
649 strncat(temp, depstr, strlen(depstr));
651 strncat(temp, "\n", strlen("\n"));
653 } else if (strcasecmp(field, "Description") == 0) {
655 if (pkg->description) {
656 temp = (char *)realloc(temp,strlen(pkg->description)+16);
658 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
662 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
665 goto UNKNOWN_FMT_FIELD;
671 if (pkg->essential) {
672 temp = (char *)realloc(temp,16);
674 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
678 snprintf(temp, (16), "Essential: yes\n");
686 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
688 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
692 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
698 if (strcasecmp(field, "Installed-Size") == 0) {
700 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
702 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
706 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
707 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
708 temp = (char *)realloc(temp,29);
710 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
714 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
720 /* Maintainer | MD5sum */
721 if (strcasecmp(field, "Maintainer") == 0) {
723 if (pkg->maintainer) {
724 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
726 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
730 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
732 } else if (strcasecmp(field, "MD5sum") == 0) {
735 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
737 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
741 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
744 goto UNKNOWN_FMT_FIELD;
750 if (strcasecmp(field, "Package") == 0) {
752 temp = (char *)realloc(temp,strlen(pkg->name)+11);
754 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
758 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
759 } else if (strcasecmp(field, "Priority") == 0) {
761 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
763 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
767 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
768 } else if (strcasecmp(field, "Provides") == 0) {
772 if (pkg->provides_count) {
773 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
774 for ( i=0; i < pkg->provides_count; i++ ){
775 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
776 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
777 flag_provide_false = 1;
780 if ( !flag_provide_false || /* Pigi there is not my trick flag */
781 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
782 char provstr[LINE_LEN];
784 for(i = 0; i < pkg->provides_count; i++) {
785 len = len + (strlen(pkg->provides_str[i])+5);
787 temp = (char *)realloc(temp,len);
789 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
793 strncpy(temp, "Provides:", 12);
794 for(i = 0; i < pkg->provides_count; i++) {
795 if (strlen(pkg->provides_str[i])>0){;
796 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
797 strncat(temp, provstr, strlen(provstr));
800 strncat(temp, "\n", strlen("\n"));
804 goto UNKNOWN_FMT_FIELD;
811 /* Replaces | Recommends*/
812 if (strcasecmp (field, "Replaces") == 0) {
813 if (pkg->replaces_count) {
814 char replstr[LINE_LEN];
816 for (i = 0; i < pkg->replaces_count; i++) {
817 len = len + (strlen(pkg->replaces_str[i])+5);
819 temp = (char *)realloc(temp,len);
821 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
825 strncpy(temp, "Replaces:", 12);
826 for (i = 0; i < pkg->replaces_count; i++) {
827 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
828 strncat(temp, replstr, strlen(replstr));
830 strncat(temp, "\n", strlen("\n"));
832 } else if (strcasecmp (field, "Recommends") == 0) {
833 if (pkg->recommends_count) {
834 char recstr[LINE_LEN];
836 for(i = 0; i < pkg->recommends_count; i++) {
837 len = len + (strlen( pkg->recommends_str[i])+5);
839 temp = (char *)realloc(temp,len);
841 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
845 strncpy(temp, "Recommends:", 13);
846 for(i = 0; i < pkg->recommends_count; i++) {
847 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
848 strncat(temp, recstr, strlen(recstr));
850 strncat(temp, "\n", strlen("\n"));
853 goto UNKNOWN_FMT_FIELD;
859 /* Section | Size | Source | Status | Suggests */
860 if (strcasecmp(field, "Section") == 0) {
863 temp = (char *)realloc(temp,strlen(pkg->section)+11);
865 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
869 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
871 } else if (strcasecmp(field, "Size") == 0) {
874 temp = (char *)realloc(temp,strlen(pkg->size)+8);
876 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
880 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
882 } else if (strcasecmp(field, "Source") == 0) {
885 temp = (char *)realloc(temp,strlen(pkg->source)+10);
887 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
891 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
893 } else if (strcasecmp(field, "Status") == 0) {
895 /* Benjamin Pineau note: we should avoid direct usage of
896 * strlen(arg) without keeping "arg" for later free()
898 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
899 char *pstat=pkg_state_status_to_str(pkg->state_status);
900 char *pwant=pkg_state_want_to_str(pkg->state_want);
902 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
903 temp = (char *)realloc(temp,sum_of_sizes);
905 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
909 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
912 if(pstat) /* pfstat can be NULL if ENOMEM */
914 } else if (strcasecmp(field, "Suggests") == 0) {
915 if (pkg->suggests_count) {
917 char sugstr[LINE_LEN];
919 for(i = 0; i < pkg->suggests_count; i++) {
920 len = len + (strlen(pkg->suggests_str[i])+5);
922 temp = (char *)realloc(temp,len);
924 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
928 strncpy(temp, "Suggests:", 10);
929 for(i = 0; i < pkg->suggests_count; i++) {
930 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
931 strncat(temp, sugstr, strlen(sugstr));
933 strncat(temp, "\n", strlen("\n"));
936 goto UNKNOWN_FMT_FIELD;
943 char *version = pkg_version_str_alloc(pkg);
944 temp = (char *)realloc(temp,strlen(version)+14);
946 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
950 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
955 goto UNKNOWN_FMT_FIELD;
958 if ( strlen(temp)<2 ) {
964 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
965 if ( strlen(temp)<2 ) {
972 void pkg_print_info(pkg_t *pkg, FILE *file)
979 buff = pkg_formatted_info(pkg);
983 fwrite(buff, 1, strlen(buff), file);
988 void pkg_print_status(pkg_t * pkg, FILE * file)
994 /* XXX: QUESTION: Do we actually want more fields here? The
995 original idea was to save space by installing only what was
996 needed for actual computation, (package, version, status,
997 essential, conffiles). The assumption is that all other fields
998 can be found in th available file.
1000 But, someone proposed the idea to make it possible to
1001 reconstruct a .ipk from an installed package, (ie. for beaming
1002 from one handheld to another). So, maybe we actually want a few
1003 more fields here, (depends, suggests, etc.), so that that would
1004 be guaranteed to work even in the absence of more information
1005 from the available file.
1007 28-MAR-03: kergoth and I discussed this yesterday. We think
1008 the essential info needs to be here for all installed packages
1009 because they may not appear in the Packages files on various
1010 feeds. Furthermore, one should be able to install from URL or
1011 local storage without requiring a Packages file from any feed.
1014 pkg_print_field(pkg, file, "Package");
1015 pkg_print_field(pkg, file, "Version");
1016 pkg_print_field(pkg, file, "Depends");
1017 pkg_print_field(pkg, file, "Recommends");
1018 pkg_print_field(pkg, file, "Suggests");
1019 pkg_print_field(pkg, file, "Provides");
1020 pkg_print_field(pkg, file, "Replaces");
1021 pkg_print_field(pkg, file, "Conflicts");
1022 pkg_print_field(pkg, file, "Status");
1023 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1024 pkg_print_field(pkg, file, "Architecture");
1025 pkg_print_field(pkg, file, "Conffiles");
1026 pkg_print_field(pkg, file, "Installed-Time");
1027 pkg_print_field(pkg, file, "Auto-Installed");
1031 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1034 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1035 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1036 __FUNCTION__, field);
1038 buff = pkg_formatted_field(pkg, field);
1039 if (strlen(buff)>2) {
1040 fprintf(file, "%s", buff);
1048 * libdpkg - Debian packaging suite library routines
1049 * vercmp.c - comparison of version numbers
1051 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1053 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1057 if (pkg->epoch > ref_pkg->epoch) {
1061 if (pkg->epoch < ref_pkg->epoch) {
1065 r = verrevcmp(pkg->version, ref_pkg->version);
1070 #ifdef USE_DEBVERSION
1071 r = verrevcmp(pkg->revision, ref_pkg->revision);
1076 r = verrevcmp(pkg->familiar_revision, ref_pkg->familiar_revision);
1082 /* assume ascii; warning: evaluates x multiple times! */
1083 #define order(x) ((x) == '~' ? -1 \
1084 : isdigit((x)) ? 0 \
1086 : isalpha((x)) ? (x) \
1089 static int verrevcmp(const char *val, const char *ref) {
1093 while (*val || *ref) {
1096 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1097 int vc= order(*val), rc= order(*ref);
1098 if (vc != rc) return vc - rc;
1102 while ( *val == '0' ) val++;
1103 while ( *ref == '0' ) ref++;
1104 while (isdigit(*val) && isdigit(*ref)) {
1105 if (!first_diff) first_diff= *val - *ref;
1108 if (isdigit(*val)) return 1;
1109 if (isdigit(*ref)) return -1;
1110 if (first_diff) return first_diff;
1115 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1119 r = pkg_compare_versions(it, ref);
1121 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1125 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1129 if (strcmp(op, "<<") == 0) {
1133 if (strcmp(op, ">>") == 0) {
1137 if (strcmp(op, "=") == 0) {
1141 fprintf(stderr, "unknown operator: %s", op);
1145 int pkg_name_version_and_architecture_compare(void *p1, void *p2)
1147 const pkg_t *a = *(const pkg_t **)p1;
1148 const pkg_t *b = *(const pkg_t **)p2;
1151 if (!a->name || !b->name) {
1152 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1153 a, a->name, b, b->name);
1157 namecmp = strcmp(a->name, b->name);
1160 vercmp = pkg_compare_versions(a, b);
1163 if (!a->arch_priority || !b->arch_priority) {
1164 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1165 a, a->arch_priority, b, b->arch_priority);
1168 if (a->arch_priority > b->arch_priority)
1170 if (a->arch_priority < b->arch_priority)
1175 int abstract_pkg_name_compare(void *p1, void *p2)
1177 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1178 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1179 if (!a->name || !b->name) {
1180 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1181 a, a->name, b, b->name);
1184 return strcmp(a->name, b->name);
1188 char *pkg_version_str_alloc(pkg_t *pkg)
1190 char *complete_version;
1192 #ifdef USE_DEBVERSION
1194 char *familiar_revision_str;
1198 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1200 epoch_str = strdup("");
1203 #ifdef USE_DEBVERSION
1204 if (pkg->revision && strlen(pkg->revision)) {
1205 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1207 revision_str = strdup("");
1210 if (pkg->familiar_revision && strlen(pkg->familiar_revision)) {
1211 sprintf_alloc(&familiar_revision_str, "-fam%s", pkg->familiar_revision);
1213 familiar_revision_str = strdup("");
1217 #ifdef USE_DEBVERSION
1218 sprintf_alloc(&complete_version, "%s%s%s%s",
1219 epoch_str, pkg->version, revision_str, familiar_revision_str);
1221 sprintf_alloc(&complete_version, "%s%s",
1222 epoch_str, pkg->version);
1226 #ifdef USE_DEBVERSION
1228 free(familiar_revision_str);
1231 return complete_version;
1234 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1237 char *list_file_name = NULL;
1238 FILE *list_file = NULL;
1240 char *installed_file_name;
1243 pkg->installed_files_ref_cnt++;
1245 if (pkg->installed_files) {
1246 return pkg->installed_files;
1249 pkg->installed_files = str_list_alloc();
1250 if (pkg->installed_files == NULL) {
1251 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1255 /* For uninstalled packages, get the file list firectly from the package.
1256 For installed packages, look at the package.list file in the database.
1258 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1259 if (pkg->local_filename == NULL) {
1260 return pkg->installed_files;
1262 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1263 file. In other words, change deb_extract so that it can
1264 simply return the file list as a char *[] rather than
1265 insisting on writing in to a FILE * as it does now. */
1266 list_file = tmpfile();
1267 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1270 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1271 __FUNCTION__, pkg->local_filename, strerror(err));
1272 return pkg->installed_files;
1276 sprintf_alloc(&list_file_name, "%s/%s.list",
1277 pkg->dest->info_dir, pkg->name);
1278 if (! file_exists(list_file_name)) {
1279 free(list_file_name);
1280 return pkg->installed_files;
1283 list_file = fopen(list_file_name, "r");
1284 if (list_file == NULL) {
1285 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1286 list_file_name, strerror(errno));
1287 free(list_file_name);
1288 return pkg->installed_files;
1290 free(list_file_name);
1293 rootdirlen = strlen( pkg->dest->root_dir );
1297 line = file_read_line_alloc(list_file);
1304 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1305 if( strncmp( pkg->dest->root_dir,
1308 if (*file_name == '.') {
1311 if (*file_name == '/') {
1315 /* Freed in pkg_free_installed_files */
1316 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1318 // already contains root_dir as header -> ABSOLUTE
1319 sprintf_alloc(&installed_file_name, "%s", file_name);
1321 str_list_append(pkg->installed_files, installed_file_name);
1327 return pkg->installed_files;
1330 /* XXX: CLEANUP: This function and it's counterpart,
1331 (pkg_get_installed_files), do not match our init/deinit naming
1332 convention. Nor the alloc/free convention. But, then again, neither
1333 of these conventions currrently fit the way these two functions
1335 int pkg_free_installed_files(pkg_t *pkg)
1337 str_list_elt_t *iter;
1339 pkg->installed_files_ref_cnt--;
1340 if (pkg->installed_files_ref_cnt > 0) {
1344 if (pkg->installed_files) {
1346 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1347 /* malloced in pkg_get_installed_files */
1352 str_list_deinit(pkg->installed_files);
1355 pkg->installed_files = NULL;
1360 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1363 char *list_file_name;
1365 //I don't think pkg_free_installed_files should be called here. Jamey
1366 //pkg_free_installed_files(pkg);
1368 sprintf_alloc(&list_file_name, "%s/%s.list",
1369 pkg->dest->info_dir, pkg->name);
1370 if (!conf->noaction) {
1371 err = unlink(list_file_name);
1372 free(list_file_name);
1381 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1383 conffile_list_elt_t *iter;
1384 conffile_t *conffile;
1390 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1391 conffile = iter->data;
1393 if (strcmp(conffile->name, file_name) == 0) {
1401 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1402 const char *script, const char *args)
1408 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1409 maintainer script within a chroot environment. */
1411 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1412 have scripts in pkg->tmp_unpack_dir. */
1413 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1414 if (pkg->dest == NULL) {
1415 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1416 __FUNCTION__, pkg->name);
1419 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1421 if (pkg->tmp_unpack_dir == NULL) {
1422 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1423 __FUNCTION__, pkg->name);
1426 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1429 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1430 if (conf->noaction) return 0;
1432 /* XXX: CLEANUP: There must be a better way to handle maintainer
1433 scripts when running with offline_root mode and/or a dest other
1434 than '/'. I've been playing around with some clever chroot
1435 tricks and I might come up with something workable. */
1436 if (conf->offline_root) {
1437 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1441 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1443 if (! file_exists(path)) {
1448 if (conf->offline_root) {
1449 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1454 sprintf_alloc(&cmd, "%s %s", path, args);
1461 fprintf(stderr, "%s script returned status %d\n", script, err);
1468 char *pkg_state_want_to_str(pkg_state_want_t sw)
1472 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1473 if (pkg_state_want_map[i].value == sw) {
1474 return strdup(pkg_state_want_map[i].str);
1478 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1480 return strdup("<STATE_WANT_UNKNOWN>");
1483 pkg_state_want_t pkg_state_want_from_str(char *str)
1487 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1488 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1489 return pkg_state_want_map[i].value;
1493 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1498 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1501 int len = 3; /* ok\000 is minimum */
1504 /* clear the temporary flags before converting to string */
1505 sf &= SF_NONVOLATILE_FLAGS;
1508 return strdup("ok");
1511 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1512 if (sf & pkg_state_flag_map[i].value) {
1513 len += strlen(pkg_state_flag_map[i].str) + 1;
1517 if ( str == NULL ) {
1518 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1522 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1523 if (sf & pkg_state_flag_map[i].value) {
1524 strcat(str, pkg_state_flag_map[i].str);
1529 str[len-1] = 0; /* squash last comma */
1534 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1539 if (strcmp(str, "ok") == 0) {
1542 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1543 const char *sfname = pkg_state_flag_map[i].str;
1544 int sfname_len = strlen(sfname);
1545 if (strncmp(str, sfname, sfname_len) == 0) {
1546 sf |= pkg_state_flag_map[i].value;
1548 if (str[0] == ',') {
1559 char *pkg_state_status_to_str(pkg_state_status_t ss)
1563 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1564 if (pkg_state_status_map[i].value == ss) {
1565 return strdup(pkg_state_status_map[i].str);
1569 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1571 return strdup("<STATE_STATUS_UNKNOWN>");
1574 pkg_state_status_t pkg_state_status_from_str(const char *str)
1578 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1579 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1580 return pkg_state_status_map[i].value;
1584 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1586 return SS_NOT_INSTALLED;
1589 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1591 nv_pair_list_elt_t *l;
1593 if (!pkg->architecture)
1596 l = conf->arch_list.head;
1599 nv_pair_t *nv = l->data;
1600 if (strcmp(nv->name, pkg->architecture) == 0) {
1601 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1607 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1611 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1613 nv_pair_list_elt_t *l;
1615 l = conf->arch_list.head;
1618 nv_pair_t *nv = l->data;
1619 if (strcmp(nv->name, archname) == 0) {
1620 int priority = strtol(nv->value, NULL, 0);
1628 int pkg_info_preinstall_check(opkg_conf_t *conf)
1631 hash_table_t *pkg_hash = &conf->pkg_hash;
1632 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1633 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1635 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1636 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1637 /* update arch_priority for each package */
1638 for (i = 0; i < available_pkgs->len; i++) {
1639 pkg_t *pkg = available_pkgs->pkgs[i];
1640 int arch_priority = 1;
1643 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1644 if (pkg->architecture)
1645 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1647 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1648 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1649 pkg->arch_priority = arch_priority;
1652 for (i = 0; i < available_pkgs->len; i++) {
1653 pkg_t *pkg = available_pkgs->pkgs[i];
1654 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1655 /* clear flags and want for any uninstallable package */
1656 opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1657 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1658 pkg->state_want = SW_UNKNOWN;
1659 pkg->state_flag = 0;
1662 pkg_vec_free(available_pkgs);
1664 /* update the file owner data structure */
1665 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1666 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1667 for (i = 0; i < installed_pkgs->len; i++) {
1668 pkg_t *pkg = installed_pkgs->pkgs[i];
1669 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1670 str_list_elt_t *iter;
1671 if (installed_files == NULL) {
1672 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1675 for (iter = installed_files->head; iter; iter = iter->next) {
1676 char *installed_file = iter->data;
1677 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1678 file_hash_set_file_owner(conf, installed_file, pkg);
1681 pkg_vec_free(installed_pkgs);
1686 struct pkg_write_filelist_data {
1692 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1694 struct pkg_write_filelist_data *data = data_;
1695 pkg_t *entry = entry_;
1696 if (entry == data->pkg) {
1697 fprintf(data->stream, "%s\n", key);
1701 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1703 struct pkg_write_filelist_data data;
1704 char *list_file_name = NULL;
1708 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1711 opkg_message(conf, OPKG_INFO,
1712 " creating %s.list file\n", pkg->name);
1713 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1714 if (!list_file_name) {
1715 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1718 opkg_message(conf, OPKG_INFO,
1719 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1720 data.stream = fopen(list_file_name, "w");
1722 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1723 list_file_name, strerror(errno));
1728 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1729 fclose(data.stream);
1730 free(list_file_name);
1735 int pkg_write_changed_filelists(opkg_conf_t *conf)
1737 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1738 hash_table_t *pkg_hash = &conf->pkg_hash;
1744 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1745 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1746 for (i = 0; i < installed_pkgs->len; i++) {
1747 pkg_t *pkg = installed_pkgs->pkgs[i];
1748 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1749 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1750 err = pkg_write_filelist(conf, pkg);
1752 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);