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));
99 pkg->architecture = NULL;
100 pkg->maintainer = NULL;
102 pkg->description = NULL;
103 pkg->state_want = SW_UNKNOWN;
104 pkg->state_flag = SF_OK;
105 pkg->state_status = SS_NOT_INSTALLED;
106 pkg->depends_str = NULL;
107 pkg->provides_str = NULL;
108 pkg->depends_count = 0;
110 pkg->suggests_str = NULL;
111 pkg->recommends_str = NULL;
112 pkg->suggests_count = 0;
113 pkg->recommends_count = 0;
115 /* Abhaya: added init for conflicts fields */
116 pkg->conflicts = NULL;
117 pkg->conflicts_count = 0;
119 /* added for replaces. Jamey 7/23/2002 */
120 pkg->replaces = NULL;
121 pkg->replaces_count = 0;
123 pkg->pre_depends_count = 0;
124 pkg->pre_depends_str = NULL;
125 pkg->provides_count = 0;
126 pkg->provides = NULL;
127 pkg->filename = NULL;
128 pkg->local_filename = NULL;
129 pkg->tmp_unpack_dir = NULL;
132 pkg->installed_size = NULL;
133 pkg->priority = NULL;
135 conffile_list_init(&pkg->conffiles);
136 pkg->installed_files = NULL;
137 pkg->installed_files_ref_cnt = 0;
139 pkg->provided_by_hand = 0;
144 void compound_depend_deinit (compound_depend_t *depends)
147 for (i = 0; i < depends->possibility_count; i++)
150 d = depends->possibilities[i];
154 free (depends->possibilities);
157 void pkg_deinit(pkg_t *pkg)
166 /* revision shares storage with version, so
168 pkg->revision = NULL;
169 /* owned by opkg_conf_t */
171 /* owned by opkg_conf_t */
173 free(pkg->architecture);
174 pkg->architecture = NULL;
175 free(pkg->maintainer);
176 pkg->maintainer = NULL;
179 free(pkg->description);
180 pkg->description = NULL;
181 pkg->state_want = SW_UNKNOWN;
182 pkg->state_flag = SF_OK;
183 pkg->state_status = SS_NOT_INSTALLED;
185 //for (i = 0; i < pkg->replaces_count; i++)
186 free (pkg->replaces);
187 pkg->replaces = NULL;
189 for (i = 0; i < pkg->depends_count; i++)
190 free (pkg->depends_str[i]);
191 free(pkg->depends_str);
192 pkg->depends_str = NULL;
194 for (i = 0; i < pkg->provides_count; i++)
195 free (pkg->provides_str[i]);
196 free(pkg->provides_str);
197 pkg->provides_str = NULL;
199 for (i = 0; i < pkg->conflicts_count; i++)
200 free (pkg->conflicts_str[i]);
201 free(pkg->conflicts_str);
202 pkg->conflicts_str = NULL;
204 for (i = 0; i < pkg->replaces_count; i++)
205 free (pkg->replaces_str[i]);
206 free(pkg->replaces_str);
207 pkg->replaces_str = NULL;
209 for (i = 0; i < pkg->recommends_count; i++)
210 free (pkg->recommends_str[i]);
211 free(pkg->recommends_str);
212 pkg->recommends_str = NULL;
214 for (i = 0; i < pkg->suggests_count; i++)
215 free (pkg->suggests_str[i]);
216 free(pkg->suggests_str);
217 pkg->suggests_str = NULL;
221 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
224 for (x = 0; x < count; x++)
225 compound_depend_deinit (&pkg->depends[x]);
232 for (x = 0; x < pkg->conflicts_count; x++)
233 compound_depend_deinit (&pkg->conflicts[x]);
234 free (pkg->conflicts);
237 free (pkg->provides);
239 pkg->pre_depends_count = 0;
240 free(pkg->pre_depends_str);
241 pkg->pre_depends_str = NULL;
242 pkg->provides_count = 0;
244 pkg->filename = NULL;
245 free(pkg->local_filename);
246 pkg->local_filename = NULL;
247 /* CLEANUP: It'd be nice to pullin the cleanup function from
248 opkg_install.c here. See comment in
249 opkg_install.c:cleanup_temporary_files */
250 free(pkg->tmp_unpack_dir);
251 pkg->tmp_unpack_dir = NULL;
256 free(pkg->installed_size);
257 pkg->installed_size = NULL;
259 pkg->priority = NULL;
262 conffile_list_deinit(&pkg->conffiles);
263 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
264 since if they are calling deinit, they should know. Maybe do an
265 assertion here instead? */
266 pkg->installed_files_ref_cnt = 1;
267 pkg_free_installed_files(pkg);
273 int pkg_init_from_file(pkg_t *pkg, const char *filename)
280 if (err) { return err; }
282 pkg->local_filename = strdup(filename);
284 control_file = tmpfile();
285 err = pkg_extract_control_file_to_stream(pkg, control_file);
286 if (err) { return err; }
288 rewind(control_file);
289 raw = read_raw_pkgs_from_stream(control_file);
290 pkg_parse_raw(pkg, &raw, NULL, NULL);
292 fclose(control_file);
297 /* Merge any new information in newpkg into oldpkg */
298 /* XXX: CLEANUP: This function shouldn't actually modify anything in
299 newpkg, but should leave it usable. This rework is so that
300 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
302 * uh, i thought that i had originally written this so that it took
303 * two pkgs and returned a new one? we can do that again... -sma
305 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
307 if (oldpkg == newpkg) {
312 oldpkg->src = newpkg->src;
314 oldpkg->dest = newpkg->dest;
315 if (!oldpkg->architecture)
316 oldpkg->architecture = str_dup_safe(newpkg->architecture);
317 if (!oldpkg->arch_priority)
318 oldpkg->arch_priority = newpkg->arch_priority;
319 if (!oldpkg->section)
320 oldpkg->section = str_dup_safe(newpkg->section);
321 if(!oldpkg->maintainer)
322 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
323 if(!oldpkg->description)
324 oldpkg->description = str_dup_safe(newpkg->description);
326 /* merge the state_flags from the new package */
327 oldpkg->state_want = newpkg->state_want;
328 oldpkg->state_status = newpkg->state_status;
329 oldpkg->state_flag = newpkg->state_flag;
331 if (oldpkg->state_want == SW_UNKNOWN)
332 oldpkg->state_want = newpkg->state_want;
333 if (oldpkg->state_status == SS_NOT_INSTALLED)
334 oldpkg->state_status = newpkg->state_status;
335 oldpkg->state_flag |= newpkg->state_flag;
338 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
339 oldpkg->depends_str = newpkg->depends_str;
340 newpkg->depends_str = NULL;
341 oldpkg->depends_count = newpkg->depends_count;
342 newpkg->depends_count = 0;
344 oldpkg->depends = newpkg->depends;
345 newpkg->depends = NULL;
347 oldpkg->pre_depends_str = newpkg->pre_depends_str;
348 newpkg->pre_depends_str = NULL;
349 oldpkg->pre_depends_count = newpkg->pre_depends_count;
350 newpkg->pre_depends_count = 0;
352 oldpkg->recommends_str = newpkg->recommends_str;
353 newpkg->recommends_str = NULL;
354 oldpkg->recommends_count = newpkg->recommends_count;
355 newpkg->recommends_count = 0;
357 oldpkg->suggests_str = newpkg->suggests_str;
358 newpkg->suggests_str = NULL;
359 oldpkg->suggests_count = newpkg->suggests_count;
360 newpkg->suggests_count = 0;
363 if (!oldpkg->provides_str) {
364 oldpkg->provides_str = newpkg->provides_str;
365 newpkg->provides_str = NULL;
366 oldpkg->provides_count = newpkg->provides_count;
367 newpkg->provides_count = 0;
369 oldpkg->provides = newpkg->provides;
370 newpkg->provides = NULL;
373 if (!oldpkg->conflicts_str) {
374 oldpkg->conflicts_str = newpkg->conflicts_str;
375 newpkg->conflicts_str = NULL;
376 oldpkg->conflicts_count = newpkg->conflicts_count;
377 newpkg->conflicts_count = 0;
379 oldpkg->conflicts = newpkg->conflicts;
380 newpkg->conflicts = NULL;
383 if (!oldpkg->replaces_str) {
384 oldpkg->replaces_str = newpkg->replaces_str;
385 newpkg->replaces_str = NULL;
386 oldpkg->replaces_count = newpkg->replaces_count;
387 newpkg->replaces_count = 0;
389 oldpkg->replaces = newpkg->replaces;
390 newpkg->replaces = NULL;
393 if (!oldpkg->filename)
394 oldpkg->filename = str_dup_safe(newpkg->filename);
396 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
397 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
398 if (!oldpkg->local_filename)
399 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
400 if (!oldpkg->tmp_unpack_dir)
401 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
403 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
405 oldpkg->size = str_dup_safe(newpkg->size);
406 if (!oldpkg->installed_size)
407 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
408 if (!oldpkg->priority)
409 oldpkg->priority = str_dup_safe(newpkg->priority);
411 oldpkg->source = str_dup_safe(newpkg->source);
412 if (oldpkg->conffiles.head == NULL){
413 oldpkg->conffiles = newpkg->conffiles;
414 conffile_list_init(&newpkg->conffiles);
416 if (!oldpkg->installed_files){
417 oldpkg->installed_files = newpkg->installed_files;
418 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
419 newpkg->installed_files = NULL;
421 if (!oldpkg->essential)
422 oldpkg->essential = newpkg->essential;
427 abstract_pkg_t *abstract_pkg_new(void)
429 abstract_pkg_t * ab_pkg;
431 ab_pkg = malloc(sizeof(abstract_pkg_t));
433 if (ab_pkg == NULL) {
434 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
438 if ( abstract_pkg_init(ab_pkg) < 0 )
444 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
446 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
448 ab_pkg->provided_by = abstract_pkg_vec_alloc();
449 if (ab_pkg->provided_by==NULL){
452 ab_pkg->dependencies_checked = 0;
453 ab_pkg->state_status = SS_NOT_INSTALLED;
458 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
461 char **raw_start=NULL;
463 temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
464 if (temp_str == NULL ){
465 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
468 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
470 raw = raw_start = read_raw_pkgs_from_file(temp_str);
472 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
477 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
478 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
494 char * pkg_formatted_info(pkg_t *pkg )
501 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
507 line = pkg_formatted_field(pkg, "Package");
508 strncat(buff ,line, strlen(line));
511 line = pkg_formatted_field(pkg, "Version");
512 strncat(buff ,line, strlen(line));
515 line = pkg_formatted_field(pkg, "Depends");
516 strncat(buff ,line, strlen(line));
519 line = pkg_formatted_field(pkg, "Recommends");
520 strncat(buff ,line, strlen(line));
523 line = pkg_formatted_field(pkg, "Suggests");
524 strncat(buff ,line, strlen(line));
527 line = pkg_formatted_field(pkg, "Provides");
528 strncat(buff ,line, strlen(line));
531 line = pkg_formatted_field(pkg, "Replaces");
532 strncat(buff ,line, strlen(line));
535 line = pkg_formatted_field(pkg, "Conflicts");
536 strncat(buff ,line, strlen(line));
539 line = pkg_formatted_field(pkg, "Status");
540 strncat(buff ,line, strlen(line));
543 line = pkg_formatted_field(pkg, "Section");
544 strncat(buff ,line, strlen(line));
547 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
548 strncat(buff ,line, strlen(line));
551 line = pkg_formatted_field(pkg, "Architecture");
552 strncat(buff ,line, strlen(line));
555 line = pkg_formatted_field(pkg, "Maintainer");
556 strncat(buff ,line, strlen(line));
559 line = pkg_formatted_field(pkg, "MD5sum");
560 strncat(buff ,line, strlen(line));
563 line = pkg_formatted_field(pkg, "Size");
564 strncat(buff ,line, strlen(line));
567 line = pkg_formatted_field(pkg, "Filename");
568 strncat(buff ,line, strlen(line));
571 line = pkg_formatted_field(pkg, "Conffiles");
572 strncat(buff ,line, strlen(line));
575 line = pkg_formatted_field(pkg, "Source");
576 strncat(buff ,line, strlen(line));
579 line = pkg_formatted_field(pkg, "Description");
580 strncat(buff ,line, strlen(line));
583 line = pkg_formatted_field(pkg, "Installed-Time");
584 strncat(buff ,line, strlen(line));
587 line = pkg_formatted_field(pkg, "Tags");
588 strncat(buff ,line, strlen(line));
594 char * pkg_formatted_field(pkg_t *pkg, const char *field )
596 static size_t LINE_LEN = 128;
597 char * temp = (char *)malloc(1);
599 int flag_provide_false = 0;
602 Pigi: After some discussion with Florian we decided to modify the full procedure in
603 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
606 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
607 goto UNKNOWN_FMT_FIELD;
616 if (strcasecmp(field, "Architecture") == 0) {
618 if (pkg->architecture) {
619 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
621 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
625 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
627 } else if (strcasecmp(field, "Auto-Installed") == 0) {
628 /* Auto-Installed flag */
629 if (pkg->auto_installed) {
630 char * s = "Auto-Installed: yes\n";
631 temp = (char *)realloc(temp, strlen(s) + 1);
635 goto UNKNOWN_FMT_FIELD;
640 if (strcasecmp(field, "Conffiles") == 0) {
642 conffile_list_elt_t *iter;
643 char confstr[LINE_LEN];
645 if (pkg->conffiles.head == NULL) {
650 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
651 if (iter->data->name && iter->data->value) {
652 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
655 temp = (char *)realloc(temp,len);
657 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
661 strncpy(temp, "Conffiles:\n", 12);
662 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
663 if (iter->data->name && iter->data->value) {
664 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
665 strncat(temp, confstr, strlen(confstr));
668 } else if (strcasecmp(field, "Conflicts") == 0) {
671 if (pkg->conflicts_count) {
672 char conflictstr[LINE_LEN];
674 for(i = 0; i < pkg->conflicts_count; i++) {
675 len = len + (strlen(pkg->conflicts_str[i])+5);
677 temp = (char *)realloc(temp,len);
679 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
683 strncpy(temp, "Conflicts:", 11);
684 for(i = 0; i < pkg->conflicts_count; i++) {
685 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
686 strncat(temp, conflictstr, strlen(conflictstr));
688 strncat(temp, "\n", strlen("\n"));
691 goto UNKNOWN_FMT_FIELD;
696 if (strcasecmp(field, "Depends") == 0) {
700 if (pkg->depends_count) {
701 char depstr[LINE_LEN];
703 for(i = 0; i < pkg->depends_count; i++) {
704 len = len + (strlen(pkg->depends_str[i])+4);
706 temp = (char *)realloc(temp,len);
708 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
712 strncpy(temp, "Depends:", 10);
713 for(i = 0; i < pkg->depends_count; i++) {
714 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
715 strncat(temp, depstr, strlen(depstr));
717 strncat(temp, "\n", strlen("\n"));
719 } else if (strcasecmp(field, "Description") == 0) {
721 if (pkg->description) {
722 temp = (char *)realloc(temp,strlen(pkg->description)+16);
724 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
728 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
731 goto UNKNOWN_FMT_FIELD;
737 if (pkg->essential) {
738 temp = (char *)realloc(temp,16);
740 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
744 snprintf(temp, (16), "Essential: yes\n");
752 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
754 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
758 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
764 if (strcasecmp(field, "Installed-Size") == 0) {
766 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
768 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
772 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
773 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
774 temp = (char *)realloc(temp,29);
776 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
780 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
786 /* Maintainer | MD5sum */
787 if (strcasecmp(field, "Maintainer") == 0) {
789 if (pkg->maintainer) {
790 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
792 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
796 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
798 } else if (strcasecmp(field, "MD5sum") == 0) {
801 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
803 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
807 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
810 goto UNKNOWN_FMT_FIELD;
816 if (strcasecmp(field, "Package") == 0) {
818 temp = (char *)realloc(temp,strlen(pkg->name)+11);
820 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
824 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
825 } else if (strcasecmp(field, "Priority") == 0) {
827 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
829 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
833 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
834 } else if (strcasecmp(field, "Provides") == 0) {
838 if (pkg->provides_count) {
839 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
840 for ( i=0; i < pkg->provides_count; i++ ){
841 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
842 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
843 flag_provide_false = 1;
846 if ( !flag_provide_false || /* Pigi there is not my trick flag */
847 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
848 char provstr[LINE_LEN];
850 for(i = 0; i < pkg->provides_count; i++) {
851 len = len + (strlen(pkg->provides_str[i])+5);
853 temp = (char *)realloc(temp,len);
855 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
859 strncpy(temp, "Provides:", 12);
860 for(i = 0; i < pkg->provides_count; i++) {
861 if (strlen(pkg->provides_str[i])>0){;
862 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
863 strncat(temp, provstr, strlen(provstr));
866 strncat(temp, "\n", strlen("\n"));
870 goto UNKNOWN_FMT_FIELD;
877 /* Replaces | Recommends*/
878 if (strcasecmp (field, "Replaces") == 0) {
879 if (pkg->replaces_count) {
880 char replstr[LINE_LEN];
882 for (i = 0; i < pkg->replaces_count; i++) {
883 len = len + (strlen(pkg->replaces_str[i])+5);
885 temp = (char *)realloc(temp,len);
887 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
891 strncpy(temp, "Replaces:", 12);
892 for (i = 0; i < pkg->replaces_count; i++) {
893 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
894 strncat(temp, replstr, strlen(replstr));
896 strncat(temp, "\n", strlen("\n"));
898 } else if (strcasecmp (field, "Recommends") == 0) {
899 if (pkg->recommends_count) {
900 char recstr[LINE_LEN];
902 for(i = 0; i < pkg->recommends_count; i++) {
903 len = len + (strlen( pkg->recommends_str[i])+5);
905 temp = (char *)realloc(temp,len);
907 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
911 strncpy(temp, "Recommends:", 13);
912 for(i = 0; i < pkg->recommends_count; i++) {
913 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
914 strncat(temp, recstr, strlen(recstr));
916 strncat(temp, "\n", strlen("\n"));
919 goto UNKNOWN_FMT_FIELD;
925 /* Section | Size | Source | Status | Suggests */
926 if (strcasecmp(field, "Section") == 0) {
929 temp = (char *)realloc(temp,strlen(pkg->section)+11);
931 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
935 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
937 } else if (strcasecmp(field, "Size") == 0) {
940 temp = (char *)realloc(temp,strlen(pkg->size)+8);
942 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
946 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
948 } else if (strcasecmp(field, "Source") == 0) {
951 temp = (char *)realloc(temp,strlen(pkg->source)+10);
953 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
957 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
959 } else if (strcasecmp(field, "Status") == 0) {
961 /* Benjamin Pineau note: we should avoid direct usage of
962 * strlen(arg) without keeping "arg" for later free()
964 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
965 char *pstat=pkg_state_status_to_str(pkg->state_status);
966 char *pwant=pkg_state_want_to_str(pkg->state_want);
968 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
969 temp = (char *)realloc(temp,sum_of_sizes);
971 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
975 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
978 if(pstat) /* pfstat can be NULL if ENOMEM */
980 } else if (strcasecmp(field, "Suggests") == 0) {
981 if (pkg->suggests_count) {
983 char sugstr[LINE_LEN];
985 for(i = 0; i < pkg->suggests_count; i++) {
986 len = len + (strlen(pkg->suggests_str[i])+5);
988 temp = (char *)realloc(temp,len);
990 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
994 strncpy(temp, "Suggests:", 10);
995 for(i = 0; i < pkg->suggests_count; i++) {
996 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
997 strncat(temp, sugstr, strlen(sugstr));
999 strncat(temp, "\n", strlen("\n"));
1002 goto UNKNOWN_FMT_FIELD;
1008 if (strcasecmp(field, "Tags") == 0) {
1011 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1012 if ( temp == NULL ){
1013 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1017 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1024 char *version = pkg_version_str_alloc(pkg);
1025 temp = (char *)realloc(temp,strlen(version)+14);
1026 if ( temp == NULL ){
1027 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1031 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1036 goto UNKNOWN_FMT_FIELD;
1039 if ( strlen(temp)<2 ) {
1045 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1046 if ( strlen(temp)<2 ) {
1053 void pkg_print_info(pkg_t *pkg, FILE *file)
1060 buff = pkg_formatted_info(pkg);
1063 if (strlen(buff)>2){
1064 fwrite(buff, 1, strlen(buff), file);
1069 void pkg_print_status(pkg_t * pkg, FILE * file)
1075 /* XXX: QUESTION: Do we actually want more fields here? The
1076 original idea was to save space by installing only what was
1077 needed for actual computation, (package, version, status,
1078 essential, conffiles). The assumption is that all other fields
1079 can be found in th available file.
1081 But, someone proposed the idea to make it possible to
1082 reconstruct a .ipk from an installed package, (ie. for beaming
1083 from one handheld to another). So, maybe we actually want a few
1084 more fields here, (depends, suggests, etc.), so that that would
1085 be guaranteed to work even in the absence of more information
1086 from the available file.
1088 28-MAR-03: kergoth and I discussed this yesterday. We think
1089 the essential info needs to be here for all installed packages
1090 because they may not appear in the Packages files on various
1091 feeds. Furthermore, one should be able to install from URL or
1092 local storage without requiring a Packages file from any feed.
1095 pkg_print_field(pkg, file, "Package");
1096 pkg_print_field(pkg, file, "Version");
1097 pkg_print_field(pkg, file, "Depends");
1098 pkg_print_field(pkg, file, "Recommends");
1099 pkg_print_field(pkg, file, "Suggests");
1100 pkg_print_field(pkg, file, "Provides");
1101 pkg_print_field(pkg, file, "Replaces");
1102 pkg_print_field(pkg, file, "Conflicts");
1103 pkg_print_field(pkg, file, "Status");
1104 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1105 pkg_print_field(pkg, file, "Architecture");
1106 pkg_print_field(pkg, file, "Conffiles");
1107 pkg_print_field(pkg, file, "Installed-Time");
1108 pkg_print_field(pkg, file, "Auto-Installed");
1112 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1115 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1116 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1117 __FUNCTION__, field);
1119 buff = pkg_formatted_field(pkg, field);
1120 if (strlen(buff)>2) {
1121 fprintf(file, "%s", buff);
1129 * libdpkg - Debian packaging suite library routines
1130 * vercmp.c - comparison of version numbers
1132 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1134 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1138 if (pkg->epoch > ref_pkg->epoch) {
1142 if (pkg->epoch < ref_pkg->epoch) {
1146 r = verrevcmp(pkg->version, ref_pkg->version);
1151 r = verrevcmp(pkg->revision, ref_pkg->revision);
1159 /* assume ascii; warning: evaluates x multiple times! */
1160 #define order(x) ((x) == '~' ? -1 \
1161 : isdigit((x)) ? 0 \
1163 : isalpha((x)) ? (x) \
1166 static int verrevcmp(const char *val, const char *ref) {
1170 while (*val || *ref) {
1173 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1174 int vc= order(*val), rc= order(*ref);
1175 if (vc != rc) return vc - rc;
1179 while ( *val == '0' ) val++;
1180 while ( *ref == '0' ) ref++;
1181 while (isdigit(*val) && isdigit(*ref)) {
1182 if (!first_diff) first_diff= *val - *ref;
1185 if (isdigit(*val)) return 1;
1186 if (isdigit(*ref)) return -1;
1187 if (first_diff) return first_diff;
1192 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1196 r = pkg_compare_versions(it, ref);
1198 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1202 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1206 if (strcmp(op, "<<") == 0) {
1210 if (strcmp(op, ">>") == 0) {
1214 if (strcmp(op, "=") == 0) {
1218 fprintf(stderr, "unknown operator: %s", op);
1222 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1224 const pkg_t *a = *(const pkg_t**) p1;
1225 const pkg_t *b = *(const pkg_t**) p2;
1228 if (!a->name || !b->name) {
1229 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1230 a, a->name, b, b->name);
1234 namecmp = strcmp(a->name, b->name);
1237 vercmp = pkg_compare_versions(a, b);
1240 if (!a->arch_priority || !b->arch_priority) {
1241 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1242 a, a->arch_priority, b, b->arch_priority);
1245 if (a->arch_priority > b->arch_priority)
1247 if (a->arch_priority < b->arch_priority)
1252 int abstract_pkg_name_compare(const void *p1, const void *p2)
1254 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1255 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1256 if (!a->name || !b->name) {
1257 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1258 a, a->name, b, b->name);
1261 return strcmp(a->name, b->name);
1265 char *pkg_version_str_alloc(pkg_t *pkg)
1267 char *complete_version;
1272 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1274 epoch_str = strdup("");
1277 if (pkg->revision && strlen(pkg->revision)) {
1278 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1280 revision_str = strdup("");
1284 sprintf_alloc(&complete_version, "%s%s%s",
1285 epoch_str, pkg->version, revision_str);
1290 return complete_version;
1293 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1296 char *list_file_name = NULL;
1297 FILE *list_file = NULL;
1299 char *installed_file_name;
1302 pkg->installed_files_ref_cnt++;
1304 if (pkg->installed_files) {
1305 return pkg->installed_files;
1308 pkg->installed_files = str_list_alloc();
1309 if (pkg->installed_files == NULL) {
1310 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1314 /* For uninstalled packages, get the file list firectly from the package.
1315 For installed packages, look at the package.list file in the database.
1317 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1318 if (pkg->local_filename == NULL) {
1319 return pkg->installed_files;
1321 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1322 file. In other words, change deb_extract so that it can
1323 simply return the file list as a char *[] rather than
1324 insisting on writing in to a FILE * as it does now. */
1325 list_file = tmpfile();
1326 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1329 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1330 __FUNCTION__, pkg->local_filename, strerror(err));
1331 return pkg->installed_files;
1335 sprintf_alloc(&list_file_name, "%s/%s.list",
1336 pkg->dest->info_dir, pkg->name);
1337 if (! file_exists(list_file_name)) {
1338 free(list_file_name);
1339 return pkg->installed_files;
1342 list_file = fopen(list_file_name, "r");
1343 if (list_file == NULL) {
1344 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1345 list_file_name, strerror(errno));
1346 free(list_file_name);
1347 return pkg->installed_files;
1349 free(list_file_name);
1352 rootdirlen = strlen( pkg->dest->root_dir );
1356 line = file_read_line_alloc(list_file);
1363 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1364 if( strncmp( pkg->dest->root_dir,
1367 if (*file_name == '.') {
1370 if (*file_name == '/') {
1374 /* Freed in pkg_free_installed_files */
1375 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1377 // already contains root_dir as header -> ABSOLUTE
1378 sprintf_alloc(&installed_file_name, "%s", file_name);
1380 str_list_append(pkg->installed_files, installed_file_name);
1386 return pkg->installed_files;
1389 /* XXX: CLEANUP: This function and it's counterpart,
1390 (pkg_get_installed_files), do not match our init/deinit naming
1391 convention. Nor the alloc/free convention. But, then again, neither
1392 of these conventions currrently fit the way these two functions
1394 int pkg_free_installed_files(pkg_t *pkg)
1396 str_list_elt_t *iter;
1398 pkg->installed_files_ref_cnt--;
1399 if (pkg->installed_files_ref_cnt > 0) {
1403 if (pkg->installed_files) {
1405 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1406 /* malloced in pkg_get_installed_files */
1411 str_list_deinit(pkg->installed_files);
1412 free (pkg->installed_files);
1415 pkg->installed_files = NULL;
1420 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1423 char *list_file_name;
1425 //I don't think pkg_free_installed_files should be called here. Jamey
1426 //pkg_free_installed_files(pkg);
1428 sprintf_alloc(&list_file_name, "%s/%s.list",
1429 pkg->dest->info_dir, pkg->name);
1430 if (!conf->noaction) {
1431 err = unlink(list_file_name);
1432 free(list_file_name);
1441 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1443 conffile_list_elt_t *iter;
1444 conffile_t *conffile;
1450 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1451 conffile = iter->data;
1453 if (strcmp(conffile->name, file_name) == 0) {
1461 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1462 const char *script, const char *args)
1468 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1469 maintainer script within a chroot environment. */
1471 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1472 have scripts in pkg->tmp_unpack_dir. */
1473 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1474 if (pkg->dest == NULL) {
1475 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1476 __FUNCTION__, pkg->name);
1479 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1481 if (pkg->tmp_unpack_dir == NULL) {
1482 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1483 __FUNCTION__, pkg->name);
1486 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1489 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1490 if (conf->noaction) return 0;
1492 /* XXX: CLEANUP: There must be a better way to handle maintainer
1493 scripts when running with offline_root mode and/or a dest other
1494 than '/'. I've been playing around with some clever chroot
1495 tricks and I might come up with something workable. */
1496 if (conf->offline_root) {
1497 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1501 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1503 if (! file_exists(path)) {
1508 if (conf->offline_root) {
1509 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1514 sprintf_alloc(&cmd, "%s %s", path, args);
1521 fprintf(stderr, "%s script returned status %d\n", script, err);
1528 char *pkg_state_want_to_str(pkg_state_want_t sw)
1532 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1533 if (pkg_state_want_map[i].value == sw) {
1534 return strdup(pkg_state_want_map[i].str);
1538 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1540 return strdup("<STATE_WANT_UNKNOWN>");
1543 pkg_state_want_t pkg_state_want_from_str(char *str)
1547 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1548 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1549 return pkg_state_want_map[i].value;
1553 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1558 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1561 int len = 3; /* ok\000 is minimum */
1564 /* clear the temporary flags before converting to string */
1565 sf &= SF_NONVOLATILE_FLAGS;
1568 return strdup("ok");
1571 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1572 if (sf & pkg_state_flag_map[i].value) {
1573 len += strlen(pkg_state_flag_map[i].str) + 1;
1577 if ( str == NULL ) {
1578 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1582 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1583 if (sf & pkg_state_flag_map[i].value) {
1584 strcat(str, pkg_state_flag_map[i].str);
1589 str[len-1] = 0; /* squash last comma */
1594 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1599 if (strcmp(str, "ok") == 0) {
1602 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1603 const char *sfname = pkg_state_flag_map[i].str;
1604 int sfname_len = strlen(sfname);
1605 if (strncmp(str, sfname, sfname_len) == 0) {
1606 sf |= pkg_state_flag_map[i].value;
1608 if (str[0] == ',') {
1619 char *pkg_state_status_to_str(pkg_state_status_t ss)
1623 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1624 if (pkg_state_status_map[i].value == ss) {
1625 return strdup(pkg_state_status_map[i].str);
1629 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1631 return strdup("<STATE_STATUS_UNKNOWN>");
1634 pkg_state_status_t pkg_state_status_from_str(const char *str)
1638 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1639 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1640 return pkg_state_status_map[i].value;
1644 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1646 return SS_NOT_INSTALLED;
1649 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1651 nv_pair_list_elt_t *l;
1653 if (!pkg->architecture)
1656 l = conf->arch_list.head;
1659 nv_pair_t *nv = l->data;
1660 if (strcmp(nv->name, pkg->architecture) == 0) {
1661 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1667 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1671 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1673 nv_pair_list_elt_t *l;
1675 l = conf->arch_list.head;
1678 nv_pair_t *nv = l->data;
1679 if (strcmp(nv->name, archname) == 0) {
1680 int priority = strtol(nv->value, NULL, 0);
1688 int pkg_info_preinstall_check(opkg_conf_t *conf)
1691 hash_table_t *pkg_hash = &conf->pkg_hash;
1692 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1693 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1695 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1696 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1697 /* update arch_priority for each package */
1698 for (i = 0; i < available_pkgs->len; i++) {
1699 pkg_t *pkg = available_pkgs->pkgs[i];
1700 int arch_priority = 1;
1703 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1704 if (pkg->architecture)
1705 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1707 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1708 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1709 pkg->arch_priority = arch_priority;
1712 for (i = 0; i < available_pkgs->len; i++) {
1713 pkg_t *pkg = available_pkgs->pkgs[i];
1714 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1715 /* clear flags and want for any uninstallable package */
1716 opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1717 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1718 pkg->state_want = SW_UNKNOWN;
1719 pkg->state_flag = 0;
1722 pkg_vec_free(available_pkgs);
1724 /* update the file owner data structure */
1725 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1726 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1727 for (i = 0; i < installed_pkgs->len; i++) {
1728 pkg_t *pkg = installed_pkgs->pkgs[i];
1729 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1730 str_list_elt_t *iter;
1731 if (installed_files == NULL) {
1732 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1735 for (iter = installed_files->head; iter; iter = iter->next) {
1736 char *installed_file = iter->data;
1737 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1738 file_hash_set_file_owner(conf, installed_file, pkg);
1741 pkg_vec_free(installed_pkgs);
1746 struct pkg_write_filelist_data {
1752 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1754 struct pkg_write_filelist_data *data = data_;
1755 pkg_t *entry = entry_;
1756 if (entry == data->pkg) {
1757 fprintf(data->stream, "%s\n", key);
1761 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1763 struct pkg_write_filelist_data data;
1764 char *list_file_name = NULL;
1768 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1771 opkg_message(conf, OPKG_INFO,
1772 " creating %s.list file\n", pkg->name);
1773 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1774 if (!list_file_name) {
1775 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1778 opkg_message(conf, OPKG_INFO,
1779 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1780 data.stream = fopen(list_file_name, "w");
1782 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1783 list_file_name, strerror(errno));
1788 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1789 fclose(data.stream);
1790 free(list_file_name);
1795 int pkg_write_changed_filelists(opkg_conf_t *conf)
1797 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1798 hash_table_t *pkg_hash = &conf->pkg_hash;
1804 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1805 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1806 for (i = 0; i < installed_pkgs->len; i++) {
1807 pkg_t *pkg = installed_pkgs->pkgs[i];
1808 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1809 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1810 err = pkg_write_filelist(conf, pkg);
1812 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1815 pkg_vec_free (installed_pkgs);