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
);
562 goto UNKNOWN_FMT_FIELD
;
567 if (strcasecmp(field
, "Conffiles") == 0) {
569 conffile_list_elt_t
*iter
;
570 char confstr
[LINE_LEN
];
572 if (pkg
->conffiles
.head
== NULL
) {
577 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
578 if (iter
->data
->name
&& iter
->data
->value
) {
579 len
= len
+ (strlen(iter
->data
->name
)+strlen(iter
->data
->value
)+5);
582 temp
= (char *)realloc(temp
,len
);
584 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
588 strncpy(temp
, "Conffiles:\n", 12);
589 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
590 if (iter
->data
->name
&& iter
->data
->value
) {
591 snprintf(confstr
, LINE_LEN
, "%s %s\n", iter
->data
->name
, iter
->data
->value
);
592 strncat(temp
, confstr
, strlen(confstr
));
595 } else if (strcasecmp(field
, "Conflicts") == 0) {
598 if (pkg
->conflicts_count
) {
599 char conflictstr
[LINE_LEN
];
601 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
602 len
= len
+ (strlen(pkg
->conflicts_str
[i
])+5);
604 temp
= (char *)realloc(temp
,len
);
606 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
610 strncpy(temp
, "Conflicts:", 11);
611 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
612 snprintf(conflictstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->conflicts_str
[i
]);
613 strncat(temp
, conflictstr
, strlen(conflictstr
));
615 strncat(temp
, "\n", strlen("\n"));
618 goto UNKNOWN_FMT_FIELD
;
623 if (strcasecmp(field
, "Depends") == 0) {
627 if (pkg
->depends_count
) {
628 char depstr
[LINE_LEN
];
630 for(i
= 0; i
< pkg
->depends_count
; i
++) {
631 len
= len
+ (strlen(pkg
->depends_str
[i
])+4);
633 temp
= (char *)realloc(temp
,len
);
635 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
639 strncpy(temp
, "Depends:", 10);
640 for(i
= 0; i
< pkg
->depends_count
; i
++) {
641 snprintf(depstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->depends_str
[i
]);
642 strncat(temp
, depstr
, strlen(depstr
));
644 strncat(temp
, "\n", strlen("\n"));
646 } else if (strcasecmp(field
, "Description") == 0) {
648 if (pkg
->description
) {
649 temp
= (char *)realloc(temp
,strlen(pkg
->description
)+16);
651 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
655 snprintf(temp
, (strlen(pkg
->description
)+16), "Description: %s\n", pkg
->description
);
658 goto UNKNOWN_FMT_FIELD
;
664 if (pkg
->essential
) {
665 temp
= (char *)realloc(temp
,16);
667 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
671 snprintf(temp
, (16), "Essential: yes\n");
679 temp
= (char *)realloc(temp
,strlen(pkg
->filename
)+12);
681 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
685 snprintf(temp
, (strlen(pkg
->filename
)+12), "Filename: %s\n", pkg
->filename
);
691 if (strcasecmp(field
, "Installed-Size") == 0) {
693 temp
= (char *)realloc(temp
,strlen(pkg
->installed_size
)+17);
695 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
699 snprintf(temp
, (strlen(pkg
->installed_size
)+17), "Installed-Size: %s\n", pkg
->installed_size
);
700 } else if (strcasecmp(field
, "Installed-Time") == 0 && pkg
->installed_time
) {
701 temp
= (char *)realloc(temp
,29);
703 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
707 snprintf(temp
, 29, "Installed-Time: %lu\n", pkg
->installed_time
);
713 /* Maintainer | MD5sum */
714 if (strcasecmp(field
, "Maintainer") == 0) {
716 if (pkg
->maintainer
) {
717 temp
= (char *)realloc(temp
,strlen(pkg
->maintainer
)+14);
719 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
723 snprintf(temp
, (strlen(pkg
->maintainer
)+14), "maintainer: %s\n", pkg
->maintainer
);
725 } else if (strcasecmp(field
, "MD5sum") == 0) {
728 temp
= (char *)realloc(temp
,strlen(pkg
->md5sum
)+11);
730 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
734 snprintf(temp
, (strlen(pkg
->md5sum
)+11), "MD5Sum: %s\n", pkg
->md5sum
);
737 goto UNKNOWN_FMT_FIELD
;
743 if (strcasecmp(field
, "Package") == 0) {
745 temp
= (char *)realloc(temp
,strlen(pkg
->name
)+11);
747 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
751 snprintf(temp
, (strlen(pkg
->name
)+11), "Package: %s\n", pkg
->name
);
752 } else if (strcasecmp(field
, "Priority") == 0) {
754 temp
= (char *)realloc(temp
,strlen(pkg
->priority
)+12);
756 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
760 snprintf(temp
, (strlen(pkg
->priority
)+12), "Priority: %s\n", pkg
->priority
);
761 } else if (strcasecmp(field
, "Provides") == 0) {
765 if (pkg
->provides_count
) {
766 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
767 for ( i
=0; i
< pkg
->provides_count
; i
++ ){
768 if (strstr(pkg
->provides_str
[i
],"opkg_internal_use_only")!=NULL
) {
769 memset (pkg
->provides_str
[i
],'\x0',strlen(pkg
->provides_str
[i
])); /* Pigi clear my trick flag, just in case */
770 flag_provide_false
= 1;
773 if ( !flag_provide_false
|| /* Pigi there is not my trick flag */
774 ((flag_provide_false
) && (pkg
->provides_count
> 1))){ /* Pigi There is, but we also have others Provides */
775 char provstr
[LINE_LEN
];
777 for(i
= 0; i
< pkg
->provides_count
; i
++) {
778 len
= len
+ (strlen(pkg
->provides_str
[i
])+5);
780 temp
= (char *)realloc(temp
,len
);
782 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
786 strncpy(temp
, "Provides:", 12);
787 for(i
= 0; i
< pkg
->provides_count
; i
++) {
788 if (strlen(pkg
->provides_str
[i
])>0){;
789 snprintf(provstr
, LINE_LEN
, "%s %s", i
== 1 ? "" : ",", pkg
->provides_str
[i
]);
790 strncat(temp
, provstr
, strlen(provstr
));
793 strncat(temp
, "\n", strlen("\n"));
797 goto UNKNOWN_FMT_FIELD
;
804 /* Replaces | Recommends*/
805 if (strcasecmp (field
, "Replaces") == 0) {
806 if (pkg
->replaces_count
) {
807 char replstr
[LINE_LEN
];
809 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
810 len
= len
+ (strlen(pkg
->replaces_str
[i
])+5);
812 temp
= (char *)realloc(temp
,len
);
814 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
818 strncpy(temp
, "Replaces:", 12);
819 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
820 snprintf(replstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->replaces_str
[i
]);
821 strncat(temp
, replstr
, strlen(replstr
));
823 strncat(temp
, "\n", strlen("\n"));
825 } else if (strcasecmp (field
, "Recommends") == 0) {
826 if (pkg
->recommends_count
) {
827 char recstr
[LINE_LEN
];
829 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
830 len
= len
+ (strlen( pkg
->recommends_str
[i
])+5);
832 temp
= (char *)realloc(temp
,len
);
834 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
838 strncpy(temp
, "Recommends:", 13);
839 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
840 snprintf(recstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->recommends_str
[i
]);
841 strncat(temp
, recstr
, strlen(recstr
));
843 strncat(temp
, "\n", strlen("\n"));
846 goto UNKNOWN_FMT_FIELD
;
852 /* Section | Size | Source | Status | Suggests */
853 if (strcasecmp(field
, "Section") == 0) {
856 temp
= (char *)realloc(temp
,strlen(pkg
->section
)+11);
858 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
862 snprintf(temp
, (strlen(pkg
->section
)+11), "Section: %s\n", pkg
->section
);
864 } else if (strcasecmp(field
, "Size") == 0) {
867 temp
= (char *)realloc(temp
,strlen(pkg
->size
)+8);
869 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
873 snprintf(temp
, (strlen(pkg
->size
)+8), "Size: %s\n", pkg
->size
);
875 } else if (strcasecmp(field
, "Source") == 0) {
878 temp
= (char *)realloc(temp
,strlen(pkg
->source
)+10);
880 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
884 snprintf(temp
, (strlen(pkg
->source
)+10), "Source: %s\n", pkg
->source
);
886 } else if (strcasecmp(field
, "Status") == 0) {
888 /* Benjamin Pineau note: we should avoid direct usage of
889 * strlen(arg) without keeping "arg" for later free()
891 char *pflag
=pkg_state_flag_to_str(pkg
->state_flag
);
892 char *pstat
=pkg_state_status_to_str(pkg
->state_status
);
893 char *pwant
=pkg_state_want_to_str(pkg
->state_want
);
895 size_t sum_of_sizes
= (size_t) ( strlen(pwant
)+ strlen(pflag
)+ strlen(pstat
) + 12 );
896 temp
= (char *)realloc(temp
,sum_of_sizes
);
898 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
902 snprintf(temp
, sum_of_sizes
, "Status: %s %s %s\n", pwant
, pflag
, pstat
);
905 if(pstat
) /* pfstat can be NULL if ENOMEM */
907 } else if (strcasecmp(field
, "Suggests") == 0) {
908 if (pkg
->suggests_count
) {
910 char sugstr
[LINE_LEN
];
912 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
913 len
= len
+ (strlen(pkg
->suggests_str
[i
])+5);
915 temp
= (char *)realloc(temp
,len
);
917 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
921 strncpy(temp
, "Suggests:", 10);
922 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
923 snprintf(sugstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->suggests_str
[i
]);
924 strncat(temp
, sugstr
, strlen(sugstr
));
926 strncat(temp
, "\n", strlen("\n"));
929 goto UNKNOWN_FMT_FIELD
;
936 char *version
= pkg_version_str_alloc(pkg
);
937 temp
= (char *)realloc(temp
,strlen(version
)+14);
939 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
943 snprintf(temp
, (strlen(version
)+12), "Version: %s\n", version
);
948 goto UNKNOWN_FMT_FIELD
;
951 if ( strlen(temp
)<2 ) {
957 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__
, field
);
958 if ( strlen(temp
)<2 ) {
965 void pkg_print_info(pkg_t
*pkg
, FILE *file
)
972 buff
= pkg_formatted_info(pkg
);
976 fwrite(buff
, 1, strlen(buff
), file
);
981 void pkg_print_status(pkg_t
* pkg
, FILE * file
)
987 /* XXX: QUESTION: Do we actually want more fields here? The
988 original idea was to save space by installing only what was
989 needed for actual computation, (package, version, status,
990 essential, conffiles). The assumption is that all other fields
991 can be found in th available file.
993 But, someone proposed the idea to make it possible to
994 reconstruct a .ipk from an installed package, (ie. for beaming
995 from one handheld to another). So, maybe we actually want a few
996 more fields here, (depends, suggests, etc.), so that that would
997 be guaranteed to work even in the absence of more information
998 from the available file.
1000 28-MAR-03: kergoth and I discussed this yesterday. We think
1001 the essential info needs to be here for all installed packages
1002 because they may not appear in the Packages files on various
1003 feeds. Furthermore, one should be able to install from URL or
1004 local storage without requiring a Packages file from any feed.
1007 pkg_print_field(pkg
, file
, "Package");
1008 pkg_print_field(pkg
, file
, "Version");
1009 pkg_print_field(pkg
, file
, "Depends");
1010 pkg_print_field(pkg
, file
, "Recommends");
1011 pkg_print_field(pkg
, file
, "Suggests");
1012 pkg_print_field(pkg
, file
, "Provides");
1013 pkg_print_field(pkg
, file
, "Replaces");
1014 pkg_print_field(pkg
, file
, "Conflicts");
1015 pkg_print_field(pkg
, file
, "Status");
1016 pkg_print_field(pkg
, file
, "Essential"); /* @@@@ should be removed in future release. */
1017 pkg_print_field(pkg
, file
, "Architecture");
1018 pkg_print_field(pkg
, file
, "Conffiles");
1019 pkg_print_field(pkg
, file
, "Installed-Time");
1023 void pkg_print_field(pkg_t
*pkg
, FILE *file
, const char *field
)
1026 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
1027 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n",
1028 __FUNCTION__
, field
);
1030 buff
= pkg_formatted_field(pkg
, field
);
1031 if (strlen(buff
)>2) {
1032 fprintf(file
, "%s", buff
);
1040 * libdpkg - Debian packaging suite library routines
1041 * vercmp.c - comparison of version numbers
1043 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1045 int pkg_compare_versions(const pkg_t
*pkg
, const pkg_t
*ref_pkg
)
1049 if (pkg
->epoch
> ref_pkg
->epoch
) {
1053 if (pkg
->epoch
< ref_pkg
->epoch
) {
1057 r
= verrevcmp(pkg
->version
, ref_pkg
->version
);
1062 #ifdef USE_DEBVERSION
1063 r
= verrevcmp(pkg
->revision
, ref_pkg
->revision
);
1068 r
= verrevcmp(pkg
->familiar_revision
, ref_pkg
->familiar_revision
);
1074 int verrevcmp(const char *val
, const char *ref
)
1078 const char *vp
, *rp
;
1079 const char *vsep
, *rsep
;
1084 vp
= val
; while (*vp
&& !isdigit(*vp
)) vp
++;
1085 rp
= ref
; while (*rp
&& !isdigit(*rp
)) rp
++;
1087 vc
= (val
== vp
) ? 0 : *val
++;
1088 rc
= (ref
== rp
) ? 0 : *ref
++;
1089 if (!rc
&& !vc
) break;
1090 if (vc
&& !isalpha(vc
)) vc
+= 256; /* assumes ASCII character set */
1091 if (rc
&& !isalpha(rc
)) rc
+= 256;
1092 if (vc
!= rc
) return vc
- rc
;
1096 vl
=0; if (isdigit(*vp
)) vl
= strtol(val
,(char**)&val
,10);
1097 rl
=0; if (isdigit(*rp
)) rl
= strtol(ref
,(char**)&ref
,10);
1098 if (vl
!= rl
) return vl
- rl
;
1102 vsep
= strchr(".-", vc
);
1103 rsep
= strchr(".-", rc
);
1104 if (vsep
&& !rsep
) return -1;
1105 if (!vsep
&& rsep
) return +1;
1107 if (!*val
&& !*ref
) return 0;
1108 if (!*val
) return -1;
1109 if (!*ref
) return +1;
1113 int pkg_version_satisfied(pkg_t
*it
, pkg_t
*ref
, const char *op
)
1117 r
= pkg_compare_versions(it
, ref
);
1119 if (strcmp(op
, "<=") == 0 || strcmp(op
, "<") == 0) {
1123 if (strcmp(op
, ">=") == 0 || strcmp(op
, ">") == 0) {
1127 if (strcmp(op
, "<<") == 0) {
1131 if (strcmp(op
, ">>") == 0) {
1135 if (strcmp(op
, "=") == 0) {
1139 fprintf(stderr
, "unknown operator: %s", op
);
1143 int pkg_name_version_and_architecture_compare(void *p1
, void *p2
)
1145 const pkg_t
*a
= *(const pkg_t
**)p1
;
1146 const pkg_t
*b
= *(const pkg_t
**)p2
;
1149 if (!a
->name
|| !b
->name
) {
1150 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1151 a
, a
->name
, b
, b
->name
);
1155 namecmp
= strcmp(a
->name
, b
->name
);
1158 vercmp
= pkg_compare_versions(a
, b
);
1161 if (!a
->arch_priority
|| !b
->arch_priority
) {
1162 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1163 a
, a
->arch_priority
, b
, b
->arch_priority
);
1166 if (a
->arch_priority
> b
->arch_priority
)
1168 if (a
->arch_priority
< b
->arch_priority
)
1173 int abstract_pkg_name_compare(void *p1
, void *p2
)
1175 const abstract_pkg_t
*a
= *(const abstract_pkg_t
**)p1
;
1176 const abstract_pkg_t
*b
= *(const abstract_pkg_t
**)p2
;
1177 if (!a
->name
|| !b
->name
) {
1178 fprintf(stderr
, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1179 a
, a
->name
, b
, b
->name
);
1182 return strcmp(a
->name
, b
->name
);
1186 char *pkg_version_str_alloc(pkg_t
*pkg
)
1188 char *complete_version
;
1190 #ifdef USE_DEBVERSION
1192 char *familiar_revision_str
;
1196 sprintf_alloc(&epoch_str
, "%d:", pkg
->epoch
);
1198 epoch_str
= strdup("");
1201 #ifdef USE_DEBVERSION
1202 if (pkg
->revision
&& strlen(pkg
->revision
)) {
1203 sprintf_alloc(&revision_str
, "-%s", pkg
->revision
);
1205 revision_str
= strdup("");
1208 if (pkg
->familiar_revision
&& strlen(pkg
->familiar_revision
)) {
1209 sprintf_alloc(&familiar_revision_str
, "-fam%s", pkg
->familiar_revision
);
1211 familiar_revision_str
= strdup("");
1215 #ifdef USE_DEBVERSION
1216 sprintf_alloc(&complete_version
, "%s%s%s%s",
1217 epoch_str
, pkg
->version
, revision_str
, familiar_revision_str
);
1219 sprintf_alloc(&complete_version
, "%s%s",
1220 epoch_str
, pkg
->version
);
1224 #ifdef USE_DEBVERSION
1226 free(familiar_revision_str
);
1229 return complete_version
;
1232 str_list_t
*pkg_get_installed_files(pkg_t
*pkg
)
1235 char *list_file_name
= NULL
;
1236 FILE *list_file
= NULL
;
1238 char *installed_file_name
;
1241 pkg
->installed_files_ref_cnt
++;
1243 if (pkg
->installed_files
) {
1244 return pkg
->installed_files
;
1247 pkg
->installed_files
= str_list_alloc();
1248 if (pkg
->installed_files
== NULL
) {
1249 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1253 /* For uninstalled packages, get the file list firectly from the package.
1254 For installed packages, look at the package.list file in the database.
1256 if (pkg
->state_status
== SS_NOT_INSTALLED
|| pkg
->dest
== NULL
) {
1257 if (pkg
->local_filename
== NULL
) {
1258 return pkg
->installed_files
;
1260 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1261 file. In other words, change deb_extract so that it can
1262 simply return the file list as a char *[] rather than
1263 insisting on writing in to a FILE * as it does now. */
1264 list_file
= tmpfile();
1265 err
= pkg_extract_data_file_names_to_stream(pkg
, list_file
);
1268 fprintf(stderr
, "%s: Error extracting file list from %s: %s\n",
1269 __FUNCTION__
, pkg
->local_filename
, strerror(err
));
1270 return pkg
->installed_files
;
1274 sprintf_alloc(&list_file_name
, "%s/%s.list",
1275 pkg
->dest
->info_dir
, pkg
->name
);
1276 if (! file_exists(list_file_name
)) {
1277 free(list_file_name
);
1278 return pkg
->installed_files
;
1281 list_file
= fopen(list_file_name
, "r");
1282 if (list_file
== NULL
) {
1283 fprintf(stderr
, "WARNING: Cannot open %s: %s\n",
1284 list_file_name
, strerror(errno
));
1285 free(list_file_name
);
1286 return pkg
->installed_files
;
1288 free(list_file_name
);
1291 rootdirlen
= strlen( pkg
->dest
->root_dir
);
1295 line
= file_read_line_alloc(list_file
);
1302 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1303 if( strncmp( pkg
->dest
->root_dir
,
1306 if (*file_name
== '.') {
1309 if (*file_name
== '/') {
1313 /* Freed in pkg_free_installed_files */
1314 sprintf_alloc(&installed_file_name
, "%s%s", pkg
->dest
->root_dir
, file_name
);
1316 // already contains root_dir as header -> ABSOLUTE
1317 sprintf_alloc(&installed_file_name
, "%s", file_name
);
1319 str_list_append(pkg
->installed_files
, installed_file_name
);
1325 return pkg
->installed_files
;
1328 /* XXX: CLEANUP: This function and it's counterpart,
1329 (pkg_get_installed_files), do not match our init/deinit naming
1330 convention. Nor the alloc/free convention. But, then again, neither
1331 of these conventions currrently fit the way these two functions
1333 int pkg_free_installed_files(pkg_t
*pkg
)
1335 str_list_elt_t
*iter
;
1337 pkg
->installed_files_ref_cnt
--;
1338 if (pkg
->installed_files_ref_cnt
> 0) {
1342 if (pkg
->installed_files
) {
1344 for (iter
= pkg
->installed_files
->head
; iter
; iter
= iter
->next
) {
1345 /* malloced in pkg_get_installed_files */
1350 str_list_deinit(pkg
->installed_files
);
1353 pkg
->installed_files
= NULL
;
1358 int pkg_remove_installed_files_list(opkg_conf_t
*conf
, pkg_t
*pkg
)
1361 char *list_file_name
;
1363 //I don't think pkg_free_installed_files should be called here. Jamey
1364 //pkg_free_installed_files(pkg);
1366 sprintf_alloc(&list_file_name
, "%s/%s.list",
1367 pkg
->dest
->info_dir
, pkg
->name
);
1368 if (!conf
->noaction
) {
1369 err
= unlink(list_file_name
);
1370 free(list_file_name
);
1379 conffile_t
*pkg_get_conffile(pkg_t
*pkg
, const char *file_name
)
1381 conffile_list_elt_t
*iter
;
1382 conffile_t
*conffile
;
1388 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
1389 conffile
= iter
->data
;
1391 if (strcmp(conffile
->name
, file_name
) == 0) {
1399 int pkg_run_script(opkg_conf_t
*conf
, pkg_t
*pkg
,
1400 const char *script
, const char *args
)
1406 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1407 maintainer script within a chroot environment. */
1409 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1410 have scripts in pkg->tmp_unpack_dir. */
1411 if (pkg
->state_status
== SS_INSTALLED
|| pkg
->state_status
== SS_UNPACKED
) {
1412 if (pkg
->dest
== NULL
) {
1413 fprintf(stderr
, "%s: ERROR: installed package %s has a NULL dest\n",
1414 __FUNCTION__
, pkg
->name
);
1417 sprintf_alloc(&path
, "%s/%s.%s", pkg
->dest
->info_dir
, pkg
->name
, script
);
1419 if (pkg
->tmp_unpack_dir
== NULL
) {
1420 fprintf(stderr
, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1421 __FUNCTION__
, pkg
->name
);
1424 sprintf_alloc(&path
, "%s/%s", pkg
->tmp_unpack_dir
, script
);
1427 opkg_message(conf
, OPKG_INFO
, "Running script %s\n", path
);
1428 if (conf
->noaction
) return 0;
1430 /* XXX: CLEANUP: There must be a better way to handle maintainer
1431 scripts when running with offline_root mode and/or a dest other
1432 than '/'. I've been playing around with some clever chroot
1433 tricks and I might come up with something workable. */
1434 if (conf
->offline_root
) {
1435 setenv("OPKG_OFFLINE_ROOT", conf
->offline_root
, 1);
1439 pkg
->dest
? pkg
->dest
->root_dir
: conf
->default_dest
->root_dir
, 1);
1441 if (! file_exists(path
)) {
1446 if (conf
->offline_root
) {
1447 fprintf(stderr
, "(offline root mode: not running %s.%s)\n", pkg
->name
, script
);
1452 sprintf_alloc(&cmd
, "%s %s", path
, args
);
1459 fprintf(stderr
, "%s script returned status %d\n", script
, err
);
1466 char *pkg_state_want_to_str(pkg_state_want_t sw
)
1470 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1471 if (pkg_state_want_map
[i
].value
== sw
) {
1472 return strdup(pkg_state_want_map
[i
].str
);
1476 fprintf(stderr
, "%s: ERROR: Illegal value for state_want: %d\n",
1478 return strdup("<STATE_WANT_UNKNOWN>");
1481 pkg_state_want_t
pkg_state_want_from_str(char *str
)
1485 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1486 if (strcmp(str
, pkg_state_want_map
[i
].str
) == 0) {
1487 return pkg_state_want_map
[i
].value
;
1491 fprintf(stderr
, "%s: ERROR: Illegal value for state_want string: %s\n",
1496 char *pkg_state_flag_to_str(pkg_state_flag_t sf
)
1499 int len
= 3; /* ok\000 is minimum */
1502 /* clear the temporary flags before converting to string */
1503 sf
&= SF_NONVOLATILE_FLAGS
;
1506 return strdup("ok");
1509 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1510 if (sf
& pkg_state_flag_map
[i
].value
) {
1511 len
+= strlen(pkg_state_flag_map
[i
].str
) + 1;
1515 if ( str
== NULL
) {
1516 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1520 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1521 if (sf
& pkg_state_flag_map
[i
].value
) {
1522 strcat(str
, pkg_state_flag_map
[i
].str
);
1527 str
[len
-1] = 0; /* squash last comma */
1532 pkg_state_flag_t
pkg_state_flag_from_str(char *str
)
1537 if (strcmp(str
, "ok") == 0) {
1540 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1541 const char *sfname
= pkg_state_flag_map
[i
].str
;
1542 int sfname_len
= strlen(sfname
);
1543 if (strncmp(str
, sfname
, sfname_len
) == 0) {
1544 sf
|= pkg_state_flag_map
[i
].value
;
1546 if (str
[0] == ',') {
1557 char *pkg_state_status_to_str(pkg_state_status_t ss
)
1561 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1562 if (pkg_state_status_map
[i
].value
== ss
) {
1563 return strdup(pkg_state_status_map
[i
].str
);
1567 fprintf(stderr
, "%s: ERROR: Illegal value for state_status: %d\n",
1569 return strdup("<STATE_STATUS_UNKNOWN>");
1572 pkg_state_status_t
pkg_state_status_from_str(char *str
)
1576 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1577 if (strcmp(str
, pkg_state_status_map
[i
].str
) == 0) {
1578 return pkg_state_status_map
[i
].value
;
1582 fprintf(stderr
, "%s: ERROR: Illegal value for state_status string: %s\n",
1584 return SS_NOT_INSTALLED
;
1587 int pkg_arch_supported(opkg_conf_t
*conf
, pkg_t
*pkg
)
1589 nv_pair_list_elt_t
*l
;
1591 if (!pkg
->architecture
)
1594 l
= conf
->arch_list
.head
;
1597 nv_pair_t
*nv
= l
->data
;
1598 if (strcmp(nv
->name
, pkg
->architecture
) == 0) {
1599 opkg_message(conf
, OPKG_DEBUG
, "arch %s (priority %s) supported for pkg %s\n", nv
->name
, nv
->value
, pkg
->name
);
1605 opkg_message(conf
, OPKG_DEBUG
, "arch %s unsupported for pkg %s\n", pkg
->architecture
, pkg
->name
);
1609 int pkg_get_arch_priority(opkg_conf_t
*conf
, const char *archname
)
1611 nv_pair_list_elt_t
*l
;
1613 l
= conf
->arch_list
.head
;
1616 nv_pair_t
*nv
= l
->data
;
1617 if (strcmp(nv
->name
, archname
) == 0) {
1618 int priority
= strtol(nv
->value
, NULL
, 0);
1626 int pkg_info_preinstall_check(opkg_conf_t
*conf
)
1629 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1630 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1631 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1633 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: updating arch priority for each package\n");
1634 pkg_hash_fetch_available(pkg_hash
, available_pkgs
);
1635 /* update arch_priority for each package */
1636 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1637 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1638 int arch_priority
= 1;
1641 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1642 if (pkg
->architecture
)
1643 arch_priority
= pkg_get_arch_priority(conf
, pkg
->architecture
);
1645 opkg_message(conf
, OPKG_ERROR
, "pkg_info_preinstall_check: no architecture for package %s\n", pkg
->name
);
1646 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1647 pkg
->arch_priority
= arch_priority
;
1650 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1651 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1652 if (!pkg
->arch_priority
&& (pkg
->state_flag
|| (pkg
->state_want
!= SW_UNKNOWN
))) {
1653 /* clear flags and want for any uninstallable package */
1654 opkg_message(conf
, OPKG_NOTICE
, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1655 pkg
->name
, pkg
->arch_priority
, pkg
->state_flag
, pkg
->state_want
);
1656 pkg
->state_want
= SW_UNKNOWN
;
1657 pkg
->state_flag
= 0;
1660 pkg_vec_free(available_pkgs
);
1662 /* update the file owner data structure */
1663 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: update file owner list\n");
1664 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1665 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1666 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1667 str_list_t
*installed_files
= pkg_get_installed_files(pkg
); /* this causes installed_files to be cached */
1668 str_list_elt_t
*iter
;
1669 if (installed_files
== NULL
) {
1670 opkg_message(conf
, OPKG_ERROR
, "No installed files for pkg %s\n", pkg
->name
);
1673 for (iter
= installed_files
->head
; iter
; iter
= iter
->next
) {
1674 char *installed_file
= iter
->data
;
1675 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1676 file_hash_set_file_owner(conf
, installed_file
, pkg
);
1679 pkg_vec_free(installed_pkgs
);
1684 struct pkg_write_filelist_data
{
1690 void pkg_write_filelist_helper(const char *key
, void *entry_
, void *data_
)
1692 struct pkg_write_filelist_data
*data
= data_
;
1693 pkg_t
*entry
= entry_
;
1694 if (entry
== data
->pkg
) {
1695 fprintf(data
->stream
, "%s\n", key
);
1699 int pkg_write_filelist(opkg_conf_t
*conf
, pkg_t
*pkg
)
1701 struct pkg_write_filelist_data data
;
1702 char *list_file_name
= NULL
;
1706 opkg_message(conf
, OPKG_ERROR
, "Null pkg\n");
1709 opkg_message(conf
, OPKG_INFO
,
1710 " creating %s.list file\n", pkg
->name
);
1711 sprintf_alloc(&list_file_name
, "%s/%s.list", pkg
->dest
->info_dir
, pkg
->name
);
1712 if (!list_file_name
) {
1713 opkg_message(conf
, OPKG_ERROR
, "Failed to alloc list_file_name\n");
1716 opkg_message(conf
, OPKG_INFO
,
1717 " creating %s file for pkg %s\n", list_file_name
, pkg
->name
);
1718 data
.stream
= fopen(list_file_name
, "w");
1720 opkg_message(conf
, OPKG_ERROR
, "Could not open %s for writing: %s\n",
1721 list_file_name
, strerror(errno
));
1726 hash_table_foreach(&conf
->file_hash
, pkg_write_filelist_helper
, &data
);
1727 fclose(data
.stream
);
1728 free(list_file_name
);
1733 int pkg_write_changed_filelists(opkg_conf_t
*conf
)
1735 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1736 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1742 opkg_message(conf
, OPKG_INFO
, "%s: saving changed filelists\n", __FUNCTION__
);
1743 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1744 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1745 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1746 if (pkg
->state_flag
& SF_FILELIST_CHANGED
) {
1747 opkg_message(conf
, OPKG_DEBUG
, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg
->name
, __FUNCTION__
);
1748 err
= pkg_write_filelist(conf
, pkg
);
1750 opkg_message(conf
, OPKG_NOTICE
, "pkg_write_filelist pkg=%s returned %d\n", pkg
->name
, err
);