1 /* pkg.c - the opkg package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
26 #include "pkg_parse.h"
27 #include "pkg_extract.h"
28 #include "opkg_message.h"
29 #include "opkg_utils.h"
31 #include "sprintf_alloc.h"
32 #include "file_util.h"
35 #include "opkg_conf.h"
37 typedef struct enum_map enum_map_t;
44 static const enum_map_t pkg_state_want_map[] = {
45 { SW_UNKNOWN, "unknown"},
46 { SW_INSTALL, "install"},
47 { SW_DEINSTALL, "deinstall"},
51 static const enum_map_t pkg_state_flag_map[] = {
53 { SF_REINSTREQ, "reinstreq"},
55 { SF_REPLACE, "replace"},
56 { SF_NOPRUNE, "noprune"},
57 { SF_PREFER, "prefer"},
58 { SF_OBSOLETE, "obsolete"},
62 static const enum_map_t pkg_state_status_map[] = {
63 { SS_NOT_INSTALLED, "not-installed" },
64 { SS_UNPACKED, "unpacked" },
65 { SS_HALF_CONFIGURED, "half-configured" },
66 { SS_INSTALLED, "installed" },
67 { SS_HALF_INSTALLED, "half-installed" },
68 { SS_CONFIG_FILES, "config-files" },
69 { SS_POST_INST_FAILED, "post-inst-failed" },
70 { SS_REMOVAL_FAILED, "removal-failed" }
73 static int verrevcmp(const char *val, const char *ref);
80 pkg = calloc(1, sizeof(pkg_t));
82 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
91 int pkg_init(pkg_t *pkg)
93 memset(pkg, 0, sizeof(pkg_t));
100 pkg->architecture = NULL;
101 pkg->maintainer = NULL;
103 pkg->description = NULL;
104 pkg->state_want = SW_UNKNOWN;
105 pkg->state_flag = SF_OK;
106 pkg->state_status = SS_NOT_INSTALLED;
107 pkg->depends_str = NULL;
108 pkg->provides_str = NULL;
109 pkg->depends_count = 0;
111 pkg->suggests_str = NULL;
112 pkg->recommends_str = NULL;
113 pkg->suggests_count = 0;
114 pkg->recommends_count = 0;
116 /* Abhaya: added init for conflicts fields */
117 pkg->conflicts = NULL;
118 pkg->conflicts_count = 0;
120 /* added for replaces. Jamey 7/23/2002 */
121 pkg->replaces = NULL;
122 pkg->replaces_count = 0;
124 pkg->pre_depends_count = 0;
125 pkg->pre_depends_str = NULL;
126 pkg->provides_count = 0;
127 pkg->provides = NULL;
128 pkg->filename = NULL;
129 pkg->local_filename = NULL;
130 pkg->tmp_unpack_dir = NULL;
133 pkg->installed_size = NULL;
134 pkg->priority = NULL;
136 conffile_list_init(&pkg->conffiles);
137 pkg->installed_files = NULL;
138 pkg->installed_files_ref_cnt = 0;
140 pkg->provided_by_hand = 0;
145 void compound_depend_deinit (compound_depend_t *depends)
148 for (i = 0; i < depends->possibility_count; i++)
151 d = depends->possibilities[i];
155 free (depends->possibilities);
158 void pkg_deinit(pkg_t *pkg)
167 /* revision shares storage with version, so
169 pkg->revision = NULL;
170 /* owned by opkg_conf_t */
172 /* owned by opkg_conf_t */
174 free(pkg->architecture);
175 pkg->architecture = NULL;
176 free(pkg->maintainer);
177 pkg->maintainer = NULL;
180 free(pkg->description);
181 pkg->description = NULL;
182 pkg->state_want = SW_UNKNOWN;
183 pkg->state_flag = SF_OK;
184 pkg->state_status = SS_NOT_INSTALLED;
186 //for (i = 0; i < pkg->replaces_count; i++)
187 free (pkg->replaces);
188 pkg->replaces = NULL;
190 for (i = 0; i < pkg->depends_count; i++)
191 free (pkg->depends_str[i]);
192 free(pkg->depends_str);
193 pkg->depends_str = NULL;
195 for (i = 0; i < pkg->provides_count; i++)
196 free (pkg->provides_str[i]);
197 free(pkg->provides_str);
198 pkg->provides_str = NULL;
200 for (i = 0; i < pkg->conflicts_count; i++)
201 free (pkg->conflicts_str[i]);
202 free(pkg->conflicts_str);
203 pkg->conflicts_str = NULL;
205 for (i = 0; i < pkg->replaces_count; i++)
206 free (pkg->replaces_str[i]);
207 free(pkg->replaces_str);
208 pkg->replaces_str = NULL;
210 for (i = 0; i < pkg->recommends_count; i++)
211 free (pkg->recommends_str[i]);
212 free(pkg->recommends_str);
213 pkg->recommends_str = NULL;
215 for (i = 0; i < pkg->suggests_count; i++)
216 free (pkg->suggests_str[i]);
217 free(pkg->suggests_str);
218 pkg->suggests_str = NULL;
222 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
225 for (x = 0; x < count; x++)
226 compound_depend_deinit (&pkg->depends[x]);
233 for (x = 0; x < pkg->conflicts_count; x++)
234 compound_depend_deinit (&pkg->conflicts[x]);
235 free (pkg->conflicts);
238 free (pkg->provides);
240 pkg->pre_depends_count = 0;
241 free(pkg->pre_depends_str);
242 pkg->pre_depends_str = NULL;
243 pkg->provides_count = 0;
245 pkg->filename = NULL;
246 free(pkg->local_filename);
247 pkg->local_filename = NULL;
248 /* CLEANUP: It'd be nice to pullin the cleanup function from
249 opkg_install.c here. See comment in
250 opkg_install.c:cleanup_temporary_files */
251 free(pkg->tmp_unpack_dir);
252 pkg->tmp_unpack_dir = NULL;
257 free(pkg->installed_size);
258 pkg->installed_size = NULL;
260 pkg->priority = NULL;
263 conffile_list_deinit(&pkg->conffiles);
264 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
265 since if they are calling deinit, they should know. Maybe do an
266 assertion here instead? */
267 pkg->installed_files_ref_cnt = 1;
268 pkg_free_installed_files(pkg);
274 int pkg_init_from_file(pkg_t *pkg, const char *filename)
281 if (err) { return err; }
283 pkg->local_filename = strdup(filename);
285 control_file = tmpfile();
286 err = pkg_extract_control_file_to_stream(pkg, control_file);
287 if (err) { return err; }
289 rewind(control_file);
290 raw = read_raw_pkgs_from_stream(control_file);
291 pkg_parse_raw(pkg, &raw, NULL, NULL);
293 fclose(control_file);
298 /* Merge any new information in newpkg into oldpkg */
299 /* XXX: CLEANUP: This function shouldn't actually modify anything in
300 newpkg, but should leave it usable. This rework is so that
301 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
303 * uh, i thought that i had originally written this so that it took
304 * two pkgs and returned a new one? we can do that again... -sma
306 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
308 if (oldpkg == newpkg) {
313 oldpkg->src = newpkg->src;
315 oldpkg->dest = newpkg->dest;
316 if (!oldpkg->architecture)
317 oldpkg->architecture = str_dup_safe(newpkg->architecture);
318 if (!oldpkg->arch_priority)
319 oldpkg->arch_priority = newpkg->arch_priority;
320 if (!oldpkg->section)
321 oldpkg->section = str_dup_safe(newpkg->section);
322 if(!oldpkg->maintainer)
323 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
324 if(!oldpkg->description)
325 oldpkg->description = str_dup_safe(newpkg->description);
327 /* merge the state_flags from the new package */
328 oldpkg->state_want = newpkg->state_want;
329 oldpkg->state_status = newpkg->state_status;
330 oldpkg->state_flag = newpkg->state_flag;
332 if (oldpkg->state_want == SW_UNKNOWN)
333 oldpkg->state_want = newpkg->state_want;
334 if (oldpkg->state_status == SS_NOT_INSTALLED)
335 oldpkg->state_status = newpkg->state_status;
336 oldpkg->state_flag |= newpkg->state_flag;
339 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
340 oldpkg->depends_str = newpkg->depends_str;
341 newpkg->depends_str = NULL;
342 oldpkg->depends_count = newpkg->depends_count;
343 newpkg->depends_count = 0;
345 oldpkg->depends = newpkg->depends;
346 newpkg->depends = NULL;
348 oldpkg->pre_depends_str = newpkg->pre_depends_str;
349 newpkg->pre_depends_str = NULL;
350 oldpkg->pre_depends_count = newpkg->pre_depends_count;
351 newpkg->pre_depends_count = 0;
353 oldpkg->recommends_str = newpkg->recommends_str;
354 newpkg->recommends_str = NULL;
355 oldpkg->recommends_count = newpkg->recommends_count;
356 newpkg->recommends_count = 0;
358 oldpkg->suggests_str = newpkg->suggests_str;
359 newpkg->suggests_str = NULL;
360 oldpkg->suggests_count = newpkg->suggests_count;
361 newpkg->suggests_count = 0;
364 if (!oldpkg->provides_str) {
365 oldpkg->provides_str = newpkg->provides_str;
366 newpkg->provides_str = NULL;
367 oldpkg->provides_count = newpkg->provides_count;
368 newpkg->provides_count = 0;
370 oldpkg->provides = newpkg->provides;
371 newpkg->provides = NULL;
374 if (!oldpkg->conflicts_str) {
375 oldpkg->conflicts_str = newpkg->conflicts_str;
376 newpkg->conflicts_str = NULL;
377 oldpkg->conflicts_count = newpkg->conflicts_count;
378 newpkg->conflicts_count = 0;
380 oldpkg->conflicts = newpkg->conflicts;
381 newpkg->conflicts = NULL;
384 if (!oldpkg->replaces_str) {
385 oldpkg->replaces_str = newpkg->replaces_str;
386 newpkg->replaces_str = NULL;
387 oldpkg->replaces_count = newpkg->replaces_count;
388 newpkg->replaces_count = 0;
390 oldpkg->replaces = newpkg->replaces;
391 newpkg->replaces = NULL;
394 if (!oldpkg->filename)
395 oldpkg->filename = str_dup_safe(newpkg->filename);
397 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
398 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
399 if (!oldpkg->local_filename)
400 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
401 if (!oldpkg->tmp_unpack_dir)
402 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
404 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
406 oldpkg->size = str_dup_safe(newpkg->size);
407 if (!oldpkg->installed_size)
408 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
409 if (!oldpkg->priority)
410 oldpkg->priority = str_dup_safe(newpkg->priority);
412 oldpkg->source = str_dup_safe(newpkg->source);
413 if (oldpkg->conffiles.head == NULL){
414 oldpkg->conffiles = newpkg->conffiles;
415 conffile_list_init(&newpkg->conffiles);
417 if (!oldpkg->installed_files){
418 oldpkg->installed_files = newpkg->installed_files;
419 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
420 newpkg->installed_files = NULL;
422 if (!oldpkg->essential)
423 oldpkg->essential = newpkg->essential;
428 abstract_pkg_t *abstract_pkg_new(void)
430 abstract_pkg_t * ab_pkg;
432 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
434 if (ab_pkg == NULL) {
435 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
439 if ( abstract_pkg_init(ab_pkg) < 0 )
445 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
447 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
449 ab_pkg->provided_by = abstract_pkg_vec_alloc();
450 if (ab_pkg->provided_by==NULL){
453 ab_pkg->dependencies_checked = 0;
454 ab_pkg->state_status = SS_NOT_INSTALLED;
459 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
462 char **raw_start=NULL;
464 temp_str = (char *) calloc (1, strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
465 if (temp_str == NULL ){
466 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
469 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
471 raw = raw_start = read_raw_pkgs_from_file(temp_str);
473 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
478 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
479 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
495 char * pkg_formatted_info(pkg_t *pkg )
500 buff = calloc(1, 8192);
502 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
508 line = pkg_formatted_field(pkg, "Package");
509 strncat(buff ,line, strlen(line));
512 line = pkg_formatted_field(pkg, "Version");
513 strncat(buff ,line, strlen(line));
516 line = pkg_formatted_field(pkg, "Depends");
517 strncat(buff ,line, strlen(line));
520 line = pkg_formatted_field(pkg, "Recommends");
521 strncat(buff ,line, strlen(line));
524 line = pkg_formatted_field(pkg, "Suggests");
525 strncat(buff ,line, strlen(line));
528 line = pkg_formatted_field(pkg, "Provides");
529 strncat(buff ,line, strlen(line));
532 line = pkg_formatted_field(pkg, "Replaces");
533 strncat(buff ,line, strlen(line));
536 line = pkg_formatted_field(pkg, "Conflicts");
537 strncat(buff ,line, strlen(line));
540 line = pkg_formatted_field(pkg, "Status");
541 strncat(buff ,line, strlen(line));
544 line = pkg_formatted_field(pkg, "Section");
545 strncat(buff ,line, strlen(line));
548 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
549 strncat(buff ,line, strlen(line));
552 line = pkg_formatted_field(pkg, "Architecture");
553 strncat(buff ,line, strlen(line));
556 line = pkg_formatted_field(pkg, "Maintainer");
557 strncat(buff ,line, strlen(line));
560 line = pkg_formatted_field(pkg, "MD5sum");
561 strncat(buff ,line, strlen(line));
564 line = pkg_formatted_field(pkg, "Size");
565 strncat(buff ,line, strlen(line));
568 line = pkg_formatted_field(pkg, "Filename");
569 strncat(buff ,line, strlen(line));
572 line = pkg_formatted_field(pkg, "Conffiles");
573 strncat(buff ,line, strlen(line));
576 line = pkg_formatted_field(pkg, "Source");
577 strncat(buff ,line, strlen(line));
580 line = pkg_formatted_field(pkg, "Description");
581 strncat(buff ,line, strlen(line));
584 line = pkg_formatted_field(pkg, "Installed-Time");
585 strncat(buff ,line, strlen(line));
588 line = pkg_formatted_field(pkg, "Tags");
589 strncat(buff ,line, strlen(line));
595 char * pkg_formatted_field(pkg_t *pkg, const char *field )
597 static size_t LINE_LEN = 128;
598 char * temp = (char *)malloc(1);
600 int flag_provide_false = 0;
603 Pigi: After some discussion with Florian we decided to modify the full procedure in
604 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
607 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
608 goto UNKNOWN_FMT_FIELD;
617 if (strcasecmp(field, "Architecture") == 0) {
619 if (pkg->architecture) {
620 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
622 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
626 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
628 } else if (strcasecmp(field, "Auto-Installed") == 0) {
629 /* Auto-Installed flag */
630 if (pkg->auto_installed) {
631 char * s = "Auto-Installed: yes\n";
632 temp = (char *)realloc(temp, strlen(s) + 1);
636 goto UNKNOWN_FMT_FIELD;
641 if (strcasecmp(field, "Conffiles") == 0) {
643 conffile_list_elt_t *iter;
644 char confstr[LINE_LEN];
646 if (pkg->conffiles.head == NULL) {
651 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
652 if (iter->data->name && iter->data->value) {
653 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
656 temp = (char *)realloc(temp,len);
658 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
662 strncpy(temp, "Conffiles:\n", 12);
663 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
664 if (iter->data->name && iter->data->value) {
665 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
666 strncat(temp, confstr, strlen(confstr));
669 } else if (strcasecmp(field, "Conflicts") == 0) {
672 if (pkg->conflicts_count) {
673 char conflictstr[LINE_LEN];
675 for(i = 0; i < pkg->conflicts_count; i++) {
676 len = len + (strlen(pkg->conflicts_str[i])+5);
678 temp = (char *)realloc(temp,len);
680 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
684 strncpy(temp, "Conflicts:", 11);
685 for(i = 0; i < pkg->conflicts_count; i++) {
686 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
687 strncat(temp, conflictstr, strlen(conflictstr));
689 strncat(temp, "\n", strlen("\n"));
692 goto UNKNOWN_FMT_FIELD;
697 if (strcasecmp(field, "Depends") == 0) {
701 if (pkg->depends_count) {
702 char depstr[LINE_LEN];
704 for(i = 0; i < pkg->depends_count; i++) {
705 len = len + (strlen(pkg->depends_str[i])+4);
707 temp = (char *)realloc(temp,len);
709 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
713 strncpy(temp, "Depends:", 10);
714 for(i = 0; i < pkg->depends_count; i++) {
715 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
716 strncat(temp, depstr, strlen(depstr));
718 strncat(temp, "\n", strlen("\n"));
720 } else if (strcasecmp(field, "Description") == 0) {
722 if (pkg->description) {
723 temp = (char *)realloc(temp,strlen(pkg->description)+16);
725 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
729 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
732 goto UNKNOWN_FMT_FIELD;
738 if (pkg->essential) {
739 temp = (char *)realloc(temp,16);
741 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
745 snprintf(temp, (16), "Essential: yes\n");
753 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
755 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
759 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
765 if (strcasecmp(field, "Installed-Size") == 0) {
767 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
769 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
773 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
774 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
775 temp = (char *)realloc(temp,29);
777 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
781 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
787 /* Maintainer | MD5sum */
788 if (strcasecmp(field, "Maintainer") == 0) {
790 if (pkg->maintainer) {
791 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
793 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
797 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
799 } else if (strcasecmp(field, "MD5sum") == 0) {
802 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
804 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
808 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
811 goto UNKNOWN_FMT_FIELD;
817 if (strcasecmp(field, "Package") == 0) {
819 temp = (char *)realloc(temp,strlen(pkg->name)+11);
821 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
825 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
826 } else if (strcasecmp(field, "Priority") == 0) {
828 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
830 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
834 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
835 } else if (strcasecmp(field, "Provides") == 0) {
839 if (pkg->provides_count) {
840 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
841 for ( i=0; i < pkg->provides_count; i++ ){
842 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
843 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
844 flag_provide_false = 1;
847 if ( !flag_provide_false || /* Pigi there is not my trick flag */
848 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
849 char provstr[LINE_LEN];
851 for(i = 0; i < pkg->provides_count; i++) {
852 len = len + (strlen(pkg->provides_str[i])+5);
854 temp = (char *)realloc(temp,len);
856 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
860 strncpy(temp, "Provides:", 12);
861 for(i = 0; i < pkg->provides_count; i++) {
862 if (strlen(pkg->provides_str[i])>0){;
863 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
864 strncat(temp, provstr, strlen(provstr));
867 strncat(temp, "\n", strlen("\n"));
871 goto UNKNOWN_FMT_FIELD;
878 /* Replaces | Recommends*/
879 if (strcasecmp (field, "Replaces") == 0) {
880 if (pkg->replaces_count) {
881 char replstr[LINE_LEN];
883 for (i = 0; i < pkg->replaces_count; i++) {
884 len = len + (strlen(pkg->replaces_str[i])+5);
886 temp = (char *)realloc(temp,len);
888 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
892 strncpy(temp, "Replaces:", 12);
893 for (i = 0; i < pkg->replaces_count; i++) {
894 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
895 strncat(temp, replstr, strlen(replstr));
897 strncat(temp, "\n", strlen("\n"));
899 } else if (strcasecmp (field, "Recommends") == 0) {
900 if (pkg->recommends_count) {
901 char recstr[LINE_LEN];
903 for(i = 0; i < pkg->recommends_count; i++) {
904 len = len + (strlen( pkg->recommends_str[i])+5);
906 temp = (char *)realloc(temp,len);
908 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
912 strncpy(temp, "Recommends:", 13);
913 for(i = 0; i < pkg->recommends_count; i++) {
914 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
915 strncat(temp, recstr, strlen(recstr));
917 strncat(temp, "\n", strlen("\n"));
920 goto UNKNOWN_FMT_FIELD;
926 /* Section | Size | Source | Status | Suggests */
927 if (strcasecmp(field, "Section") == 0) {
930 temp = (char *)realloc(temp,strlen(pkg->section)+11);
932 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
936 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
938 } else if (strcasecmp(field, "Size") == 0) {
941 temp = (char *)realloc(temp,strlen(pkg->size)+8);
943 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
947 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
949 } else if (strcasecmp(field, "Source") == 0) {
952 temp = (char *)realloc(temp,strlen(pkg->source)+10);
954 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
958 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
960 } else if (strcasecmp(field, "Status") == 0) {
962 /* Benjamin Pineau note: we should avoid direct usage of
963 * strlen(arg) without keeping "arg" for later free()
965 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
966 char *pstat=pkg_state_status_to_str(pkg->state_status);
967 char *pwant=pkg_state_want_to_str(pkg->state_want);
969 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
970 temp = (char *)realloc(temp,sum_of_sizes);
972 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
976 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
979 if(pstat) /* pfstat can be NULL if ENOMEM */
981 } else if (strcasecmp(field, "Suggests") == 0) {
982 if (pkg->suggests_count) {
984 char sugstr[LINE_LEN];
986 for(i = 0; i < pkg->suggests_count; i++) {
987 len = len + (strlen(pkg->suggests_str[i])+5);
989 temp = (char *)realloc(temp,len);
991 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
995 strncpy(temp, "Suggests:", 10);
996 for(i = 0; i < pkg->suggests_count; i++) {
997 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
998 strncat(temp, sugstr, strlen(sugstr));
1000 strncat(temp, "\n", strlen("\n"));
1003 goto UNKNOWN_FMT_FIELD;
1009 if (strcasecmp(field, "Tags") == 0) {
1012 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1013 if ( temp == NULL ){
1014 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1018 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1025 char *version = pkg_version_str_alloc(pkg);
1026 temp = (char *)realloc(temp,strlen(version)+14);
1027 if ( temp == NULL ){
1028 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1032 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1037 goto UNKNOWN_FMT_FIELD;
1040 if ( strlen(temp)<2 ) {
1046 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1047 if ( strlen(temp)<2 ) {
1054 void pkg_print_info(pkg_t *pkg, FILE *file)
1062 buff = pkg_formatted_info(pkg);
1065 if (strlen(buff)>2){
1066 t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
1071 void pkg_print_status(pkg_t * pkg, FILE * file)
1077 /* XXX: QUESTION: Do we actually want more fields here? The
1078 original idea was to save space by installing only what was
1079 needed for actual computation, (package, version, status,
1080 essential, conffiles). The assumption is that all other fields
1081 can be found in th available file.
1083 But, someone proposed the idea to make it possible to
1084 reconstruct a .opk from an installed package, (ie. for beaming
1085 from one handheld to another). So, maybe we actually want a few
1086 more fields here, (depends, suggests, etc.), so that that would
1087 be guaranteed to work even in the absence of more information
1088 from the available file.
1090 28-MAR-03: kergoth and I discussed this yesterday. We think
1091 the essential info needs to be here for all installed packages
1092 because they may not appear in the Packages files on various
1093 feeds. Furthermore, one should be able to install from URL or
1094 local storage without requiring a Packages file from any feed.
1097 pkg_print_field(pkg, file, "Package");
1098 pkg_print_field(pkg, file, "Version");
1099 pkg_print_field(pkg, file, "Depends");
1100 pkg_print_field(pkg, file, "Recommends");
1101 pkg_print_field(pkg, file, "Suggests");
1102 pkg_print_field(pkg, file, "Provides");
1103 pkg_print_field(pkg, file, "Replaces");
1104 pkg_print_field(pkg, file, "Conflicts");
1105 pkg_print_field(pkg, file, "Status");
1106 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1107 pkg_print_field(pkg, file, "Architecture");
1108 pkg_print_field(pkg, file, "Conffiles");
1109 pkg_print_field(pkg, file, "Installed-Time");
1110 pkg_print_field(pkg, file, "Auto-Installed");
1114 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1117 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1118 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1119 __FUNCTION__, field);
1121 buff = pkg_formatted_field(pkg, field);
1122 if (strlen(buff)>2) {
1123 fprintf(file, "%s", buff);
1131 * libdpkg - Debian packaging suite library routines
1132 * vercmp.c - comparison of version numbers
1134 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1136 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1140 if (pkg->epoch > ref_pkg->epoch) {
1144 if (pkg->epoch < ref_pkg->epoch) {
1148 r = verrevcmp(pkg->version, ref_pkg->version);
1153 r = verrevcmp(pkg->revision, ref_pkg->revision);
1161 /* assume ascii; warning: evaluates x multiple times! */
1162 #define order(x) ((x) == '~' ? -1 \
1163 : isdigit((x)) ? 0 \
1165 : isalpha((x)) ? (x) \
1168 static int verrevcmp(const char *val, const char *ref) {
1172 while (*val || *ref) {
1175 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1176 int vc= order(*val), rc= order(*ref);
1177 if (vc != rc) return vc - rc;
1181 while ( *val == '0' ) val++;
1182 while ( *ref == '0' ) ref++;
1183 while (isdigit(*val) && isdigit(*ref)) {
1184 if (!first_diff) first_diff= *val - *ref;
1187 if (isdigit(*val)) return 1;
1188 if (isdigit(*ref)) return -1;
1189 if (first_diff) return first_diff;
1194 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1198 r = pkg_compare_versions(it, ref);
1200 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1204 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1208 if (strcmp(op, "<<") == 0) {
1212 if (strcmp(op, ">>") == 0) {
1216 if (strcmp(op, "=") == 0) {
1220 fprintf(stderr, "unknown operator: %s", op);
1224 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1226 const pkg_t *a = *(const pkg_t**) p1;
1227 const pkg_t *b = *(const pkg_t**) p2;
1230 if (!a->name || !b->name) {
1231 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1232 a, a->name, b, b->name);
1236 namecmp = strcmp(a->name, b->name);
1239 vercmp = pkg_compare_versions(a, b);
1242 if (!a->arch_priority || !b->arch_priority) {
1243 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1244 a, a->arch_priority, b, b->arch_priority);
1247 if (a->arch_priority > b->arch_priority)
1249 if (a->arch_priority < b->arch_priority)
1254 int abstract_pkg_name_compare(const void *p1, const void *p2)
1256 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1257 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1258 if (!a->name || !b->name) {
1259 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1260 a, a->name, b, b->name);
1263 return strcmp(a->name, b->name);
1267 char *pkg_version_str_alloc(pkg_t *pkg)
1269 char *complete_version;
1274 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1276 epoch_str = strdup("");
1279 if (pkg->revision && strlen(pkg->revision)) {
1280 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1282 revision_str = strdup("");
1286 sprintf_alloc(&complete_version, "%s%s%s",
1287 epoch_str, pkg->version, revision_str);
1292 return complete_version;
1295 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1298 char *list_file_name = NULL;
1299 FILE *list_file = NULL;
1301 char *installed_file_name;
1304 pkg->installed_files_ref_cnt++;
1306 if (pkg->installed_files) {
1307 return pkg->installed_files;
1310 pkg->installed_files = str_list_alloc();
1311 if (pkg->installed_files == NULL) {
1312 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1316 /* For uninstalled packages, get the file list directly from the package.
1317 For installed packages, look at the package.list file in the database.
1319 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1320 if (pkg->local_filename == NULL) {
1321 return pkg->installed_files;
1323 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1324 file. In other words, change deb_extract so that it can
1325 simply return the file list as a char *[] rather than
1326 insisting on writing in to a FILE * as it does now. */
1327 list_file = tmpfile();
1328 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1331 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1332 __FUNCTION__, pkg->local_filename, strerror(err));
1333 return pkg->installed_files;
1337 sprintf_alloc(&list_file_name, "%s/%s.list",
1338 pkg->dest->info_dir, pkg->name);
1339 if (! file_exists(list_file_name)) {
1340 free(list_file_name);
1341 return pkg->installed_files;
1344 list_file = fopen(list_file_name, "r");
1345 if (list_file == NULL) {
1346 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1347 list_file_name, strerror(errno));
1348 free(list_file_name);
1349 return pkg->installed_files;
1351 free(list_file_name);
1354 rootdirlen = strlen( pkg->dest->root_dir );
1358 line = file_read_line_alloc(list_file);
1365 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1366 if( strncmp( pkg->dest->root_dir,
1369 if (*file_name == '.') {
1372 if (*file_name == '/') {
1376 /* Freed in pkg_free_installed_files */
1377 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1379 // already contains root_dir as header -> ABSOLUTE
1380 sprintf_alloc(&installed_file_name, "%s", file_name);
1382 str_list_append(pkg->installed_files, installed_file_name);
1388 return pkg->installed_files;
1391 /* XXX: CLEANUP: This function and it's counterpart,
1392 (pkg_get_installed_files), do not match our init/deinit naming
1393 convention. Nor the alloc/free convention. But, then again, neither
1394 of these conventions currrently fit the way these two functions
1396 int pkg_free_installed_files(pkg_t *pkg)
1398 str_list_elt_t *iter;
1400 pkg->installed_files_ref_cnt--;
1402 if (pkg->installed_files_ref_cnt > 0)
1405 if (pkg->installed_files) {
1407 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1408 /* malloced in pkg_get_installed_files */
1413 str_list_deinit(pkg->installed_files);
1414 free (pkg->installed_files);
1417 pkg->installed_files = NULL;
1422 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1425 char *list_file_name;
1427 //I don't think pkg_free_installed_files should be called here. Jamey
1428 //pkg_free_installed_files(pkg);
1430 sprintf_alloc(&list_file_name, "%s/%s.list",
1431 pkg->dest->info_dir, pkg->name);
1432 if (!conf->noaction) {
1433 err = unlink(list_file_name);
1434 free(list_file_name);
1443 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1445 conffile_list_elt_t *iter;
1446 conffile_t *conffile;
1452 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1453 conffile = iter->data;
1455 if (strcmp(conffile->name, file_name) == 0) {
1463 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1464 const char *script, const char *args)
1470 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1471 maintainer script within a chroot environment. */
1473 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1474 have scripts in pkg->tmp_unpack_dir. */
1475 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1476 if (pkg->dest == NULL) {
1477 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1478 __FUNCTION__, pkg->name);
1481 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1483 if (pkg->tmp_unpack_dir == NULL) {
1484 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1485 __FUNCTION__, pkg->name);
1488 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1491 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1492 if (conf->noaction) return 0;
1494 /* XXX: CLEANUP: There must be a better way to handle maintainer
1495 scripts when running with offline_root mode and/or a dest other
1496 than '/'. I've been playing around with some clever chroot
1497 tricks and I might come up with something workable. */
1499 * Attempt to provide a restricted environment for offline operation
1500 * Need the following set as a minimum:
1501 * OPKG_OFFLINE_ROOT = absolute path to root dir
1502 * D = absolute path to root dir (for OE generated postinst)
1503 * PATH = something safe (a restricted set of utilities)
1506 bool AllowOfflineMode = false;
1507 if (conf->offline_root) {
1508 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1509 setenv("D", conf->offline_root, 1);
1510 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1511 setenv("PATH", "/dev/null", 1);
1513 setenv("PATH", conf->offline_root_path, 1);
1514 AllowOfflineMode = true;
1519 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1521 if (! file_exists(path)) {
1526 if (conf->offline_root && !AllowOfflineMode) {
1527 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1532 sprintf_alloc(&cmd, "%s %s", path, args);
1539 fprintf(stderr, "%s script returned status %d\n", script, err);
1546 char *pkg_state_want_to_str(pkg_state_want_t sw)
1550 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1551 if (pkg_state_want_map[i].value == sw) {
1552 return strdup(pkg_state_want_map[i].str);
1556 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1558 return strdup("<STATE_WANT_UNKNOWN>");
1561 pkg_state_want_t pkg_state_want_from_str(char *str)
1565 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1566 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1567 return pkg_state_want_map[i].value;
1571 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1576 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1579 int len = 3; /* ok\000 is minimum */
1582 /* clear the temporary flags before converting to string */
1583 sf &= SF_NONVOLATILE_FLAGS;
1586 return strdup("ok");
1589 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1590 if (sf & pkg_state_flag_map[i].value) {
1591 len += strlen(pkg_state_flag_map[i].str) + 1;
1595 if ( str == NULL ) {
1596 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1600 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1601 if (sf & pkg_state_flag_map[i].value) {
1602 strcat(str, pkg_state_flag_map[i].str);
1607 str[len-1] = 0; /* squash last comma */
1612 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1617 if (strcmp(str, "ok") == 0) {
1620 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1621 const char *sfname = pkg_state_flag_map[i].str;
1622 int sfname_len = strlen(sfname);
1623 if (strncmp(str, sfname, sfname_len) == 0) {
1624 sf |= pkg_state_flag_map[i].value;
1626 if (str[0] == ',') {
1637 char *pkg_state_status_to_str(pkg_state_status_t ss)
1641 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1642 if (pkg_state_status_map[i].value == ss) {
1643 return strdup(pkg_state_status_map[i].str);
1647 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1649 return strdup("<STATE_STATUS_UNKNOWN>");
1652 pkg_state_status_t pkg_state_status_from_str(const char *str)
1656 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1657 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1658 return pkg_state_status_map[i].value;
1662 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1664 return SS_NOT_INSTALLED;
1667 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1669 nv_pair_list_elt_t *l;
1671 if (!pkg->architecture)
1674 l = conf->arch_list.head;
1677 nv_pair_t *nv = l->data;
1678 if (strcmp(nv->name, pkg->architecture) == 0) {
1679 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1685 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1689 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1691 nv_pair_list_elt_t *l;
1693 l = conf->arch_list.head;
1696 nv_pair_t *nv = l->data;
1697 if (strcmp(nv->name, archname) == 0) {
1698 int priority = strtol(nv->value, NULL, 0);
1706 int pkg_info_preinstall_check(opkg_conf_t *conf)
1709 hash_table_t *pkg_hash = &conf->pkg_hash;
1710 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1711 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1713 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1714 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1715 /* update arch_priority for each package */
1716 for (i = 0; i < available_pkgs->len; i++) {
1717 pkg_t *pkg = available_pkgs->pkgs[i];
1718 int arch_priority = 1;
1721 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1722 if (pkg->architecture)
1723 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1725 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1726 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1727 pkg->arch_priority = arch_priority;
1730 for (i = 0; i < available_pkgs->len; i++) {
1731 pkg_t *pkg = available_pkgs->pkgs[i];
1732 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1733 /* clear flags and want for any uninstallable package */
1734 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1735 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1736 pkg->state_want = SW_UNKNOWN;
1737 pkg->state_flag = 0;
1740 pkg_vec_free(available_pkgs);
1742 /* update the file owner data structure */
1743 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1744 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1745 for (i = 0; i < installed_pkgs->len; i++) {
1746 pkg_t *pkg = installed_pkgs->pkgs[i];
1747 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1748 str_list_elt_t *iter;
1749 if (installed_files == NULL) {
1750 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1753 for (iter = installed_files->head; iter; iter = iter->next) {
1754 char *installed_file = iter->data;
1755 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1756 file_hash_set_file_owner(conf, installed_file, pkg);
1758 pkg_free_installed_files(pkg);
1760 pkg_vec_free(installed_pkgs);
1765 struct pkg_write_filelist_data {
1771 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1773 struct pkg_write_filelist_data *data = data_;
1774 pkg_t *entry = entry_;
1775 if (entry == data->pkg) {
1776 fprintf(data->stream, "%s\n", key);
1780 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1782 struct pkg_write_filelist_data data;
1783 char *list_file_name = NULL;
1787 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1790 opkg_message(conf, OPKG_INFO,
1791 " creating %s.list file\n", pkg->name);
1792 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1793 if (!list_file_name) {
1794 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1797 opkg_message(conf, OPKG_INFO,
1798 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1799 data.stream = fopen(list_file_name, "w");
1801 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1802 list_file_name, strerror(errno));
1807 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1808 fclose(data.stream);
1809 free(list_file_name);
1811 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1816 int pkg_write_changed_filelists(opkg_conf_t *conf)
1818 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1819 hash_table_t *pkg_hash = &conf->pkg_hash;
1825 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1826 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1827 for (i = 0; i < installed_pkgs->len; i++) {
1828 pkg_t *pkg = installed_pkgs->pkgs[i];
1829 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1830 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1831 err = pkg_write_filelist(conf, pkg);
1833 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1836 pkg_vec_free (installed_pkgs);