1 /* pkg.c - the itsy package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
25 #include "pkg_parse.h"
26 #include "pkg_extract.h"
27 #include "opkg_message.h"
28 #include "opkg_utils.h"
30 #include "sprintf_alloc.h"
31 #include "file_util.h"
34 #include "opkg_conf.h"
36 typedef struct enum_map enum_map_t
;
43 static const enum_map_t pkg_state_want_map
[] = {
44 { SW_UNKNOWN
, "unknown"},
45 { SW_INSTALL
, "install"},
46 { SW_DEINSTALL
, "deinstall"},
50 static const enum_map_t pkg_state_flag_map
[] = {
52 { SF_REINSTREQ
, "reinstreq"},
54 { SF_REPLACE
, "replace"},
55 { SF_NOPRUNE
, "noprune"},
56 { SF_PREFER
, "prefer"},
57 { SF_OBSOLETE
, "obsolete"},
61 static const enum_map_t pkg_state_status_map
[] = {
62 { SS_NOT_INSTALLED
, "not-installed" },
63 { SS_UNPACKED
, "unpacked" },
64 { SS_HALF_CONFIGURED
, "half-configured" },
65 { SS_INSTALLED
, "installed" },
66 { SS_HALF_INSTALLED
, "half-installed" },
67 { SS_CONFIG_FILES
, "config-files" },
68 { SS_POST_INST_FAILED
, "post-inst-failed" },
69 { SS_REMOVAL_FAILED
, "removal-failed" }
72 static int verrevcmp(const char *val
, const char *ref
);
79 pkg
= malloc(sizeof(pkg_t
));
81 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
90 int pkg_init(pkg_t
*pkg
)
92 memset(pkg
, 0, sizeof(pkg_t
));
97 pkg
->familiar_revision
= NULL
;
100 pkg
->architecture
= NULL
;
101 pkg
->maintainer
= NULL
;
103 pkg
->description
= NULL
;
104 pkg
->state_want
= SW_UNKNOWN
;
105 pkg
->state_flag
= SF_OK
;
106 pkg
->state_status
= SS_NOT_INSTALLED
;
107 pkg
->depends_str
= NULL
;
108 pkg
->provides_str
= NULL
;
109 pkg
->depends_count
= 0;
111 pkg
->suggests_str
= NULL
;
112 pkg
->recommends_str
= NULL
;
113 pkg
->suggests_count
= 0;
114 pkg
->recommends_count
= 0;
116 /* Abhaya: added init for conflicts fields */
117 pkg
->conflicts
= NULL
;
118 pkg
->conflicts_count
= 0;
120 /* added for replaces. Jamey 7/23/2002 */
121 pkg
->replaces
= NULL
;
122 pkg
->replaces_count
= 0;
124 pkg
->pre_depends_count
= 0;
125 pkg
->pre_depends_str
= NULL
;
126 pkg
->provides_count
= 0;
127 pkg
->provides
= NULL
;
128 pkg
->filename
= NULL
;
129 pkg
->local_filename
= NULL
;
130 pkg
->tmp_unpack_dir
= NULL
;
133 pkg
->installed_size
= NULL
;
134 pkg
->priority
= NULL
;
136 conffile_list_init(&pkg
->conffiles
);
137 pkg
->installed_files
= NULL
;
138 pkg
->installed_files_ref_cnt
= 0;
140 pkg
->provided_by_hand
= 0;
145 void pkg_deinit(pkg_t
*pkg
)
152 /* revision and familiar_revision share storage with version, so
154 pkg
->revision
= NULL
;
155 pkg
->familiar_revision
= NULL
;
156 /* owned by opkg_conf_t */
158 /* owned by opkg_conf_t */
160 free(pkg
->architecture
);
161 pkg
->architecture
= NULL
;
162 free(pkg
->maintainer
);
163 pkg
->maintainer
= NULL
;
166 free(pkg
->description
);
167 pkg
->description
= NULL
;
168 pkg
->state_want
= SW_UNKNOWN
;
169 pkg
->state_flag
= SF_OK
;
170 pkg
->state_status
= SS_NOT_INSTALLED
;
171 free(pkg
->depends_str
);
172 pkg
->depends_str
= NULL
;
173 free(pkg
->provides_str
);
174 pkg
->provides_str
= NULL
;
175 pkg
->depends_count
= 0;
176 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */
177 pkg
->pre_depends_count
= 0;
178 free(pkg
->pre_depends_str
);
179 pkg
->pre_depends_str
= NULL
;
180 pkg
->provides_count
= 0;
181 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */
182 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */
184 pkg
->filename
= NULL
;
185 free(pkg
->local_filename
);
186 pkg
->local_filename
= NULL
;
187 /* CLEANUP: It'd be nice to pullin the cleanup function from
188 opkg_install.c here. See comment in
189 opkg_install.c:cleanup_temporary_files */
190 free(pkg
->tmp_unpack_dir
);
191 pkg
->tmp_unpack_dir
= NULL
;
196 free(pkg
->installed_size
);
197 pkg
->installed_size
= NULL
;
199 pkg
->priority
= NULL
;
202 conffile_list_deinit(&pkg
->conffiles
);
203 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
204 since if they are calling deinit, they should know. Maybe do an
205 assertion here instead? */
206 pkg
->installed_files_ref_cnt
= 1;
207 pkg_free_installed_files(pkg
);
211 int pkg_init_from_file(pkg_t
*pkg
, const char *filename
)
218 if (err
) { return err
; }
220 pkg
->local_filename
= strdup(filename
);
222 control_file
= tmpfile();
223 err
= pkg_extract_control_file_to_stream(pkg
, control_file
);
224 if (err
) { return err
; }
226 rewind(control_file
);
227 raw
= read_raw_pkgs_from_stream(control_file
);
228 pkg_parse_raw(pkg
, &raw
, NULL
, NULL
);
230 fclose(control_file
);
235 /* Merge any new information in newpkg into oldpkg */
236 /* XXX: CLEANUP: This function shouldn't actually modify anything in
237 newpkg, but should leave it usable. This rework is so that
238 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
240 * uh, i thought that i had originally written this so that it took
241 * two pkgs and returned a new one? we can do that again... -sma
243 int pkg_merge(pkg_t
*oldpkg
, pkg_t
*newpkg
, int set_status
)
245 if (oldpkg
== newpkg
) {
250 oldpkg
->src
= newpkg
->src
;
252 oldpkg
->dest
= newpkg
->dest
;
253 if (!oldpkg
->architecture
)
254 oldpkg
->architecture
= str_dup_safe(newpkg
->architecture
);
255 if (!oldpkg
->arch_priority
)
256 oldpkg
->arch_priority
= newpkg
->arch_priority
;
257 if (!oldpkg
->section
)
258 oldpkg
->section
= str_dup_safe(newpkg
->section
);
259 if(!oldpkg
->maintainer
)
260 oldpkg
->maintainer
= str_dup_safe(newpkg
->maintainer
);
261 if(!oldpkg
->description
)
262 oldpkg
->description
= str_dup_safe(newpkg
->description
);
264 /* merge the state_flags from the new package */
265 oldpkg
->state_want
= newpkg
->state_want
;
266 oldpkg
->state_status
= newpkg
->state_status
;
267 oldpkg
->state_flag
= newpkg
->state_flag
;
269 if (oldpkg
->state_want
== SW_UNKNOWN
)
270 oldpkg
->state_want
= newpkg
->state_want
;
271 if (oldpkg
->state_status
== SS_NOT_INSTALLED
)
272 oldpkg
->state_status
= newpkg
->state_status
;
273 oldpkg
->state_flag
|= newpkg
->state_flag
;
276 if (!oldpkg
->depends_str
&& !oldpkg
->pre_depends_str
&& !oldpkg
->recommends_str
&& !oldpkg
->suggests_str
) {
277 oldpkg
->depends_str
= newpkg
->depends_str
;
278 newpkg
->depends_str
= NULL
;
279 oldpkg
->depends_count
= newpkg
->depends_count
;
280 newpkg
->depends_count
= 0;
282 oldpkg
->depends
= newpkg
->depends
;
283 newpkg
->depends
= NULL
;
285 oldpkg
->pre_depends_str
= newpkg
->pre_depends_str
;
286 newpkg
->pre_depends_str
= NULL
;
287 oldpkg
->pre_depends_count
= newpkg
->pre_depends_count
;
288 newpkg
->pre_depends_count
= 0;
290 oldpkg
->recommends_str
= newpkg
->recommends_str
;
291 newpkg
->recommends_str
= NULL
;
292 oldpkg
->recommends_count
= newpkg
->recommends_count
;
293 newpkg
->recommends_count
= 0;
295 oldpkg
->suggests_str
= newpkg
->suggests_str
;
296 newpkg
->suggests_str
= NULL
;
297 oldpkg
->suggests_count
= newpkg
->suggests_count
;
298 newpkg
->suggests_count
= 0;
301 if (!oldpkg
->provides_str
) {
302 oldpkg
->provides_str
= newpkg
->provides_str
;
303 newpkg
->provides_str
= NULL
;
304 oldpkg
->provides_count
= newpkg
->provides_count
;
305 newpkg
->provides_count
= 0;
307 oldpkg
->provides
= newpkg
->provides
;
308 newpkg
->provides
= NULL
;
311 if (!oldpkg
->conflicts_str
) {
312 oldpkg
->conflicts_str
= newpkg
->conflicts_str
;
313 newpkg
->conflicts_str
= NULL
;
314 oldpkg
->conflicts_count
= newpkg
->conflicts_count
;
315 newpkg
->conflicts_count
= 0;
317 oldpkg
->conflicts
= newpkg
->conflicts
;
318 newpkg
->conflicts
= NULL
;
321 if (!oldpkg
->replaces_str
) {
322 oldpkg
->replaces_str
= newpkg
->replaces_str
;
323 newpkg
->replaces_str
= NULL
;
324 oldpkg
->replaces_count
= newpkg
->replaces_count
;
325 newpkg
->replaces_count
= 0;
327 oldpkg
->replaces
= newpkg
->replaces
;
328 newpkg
->replaces
= NULL
;
331 if (!oldpkg
->filename
)
332 oldpkg
->filename
= str_dup_safe(newpkg
->filename
);
334 fprintf(stdout
, "pkg=%s old local_filename=%s new local_filename=%s\n",
335 oldpkg
->name
, oldpkg
->local_filename
, newpkg
->local_filename
);
336 if (!oldpkg
->local_filename
)
337 oldpkg
->local_filename
= str_dup_safe(newpkg
->local_filename
);
338 if (!oldpkg
->tmp_unpack_dir
)
339 oldpkg
->tmp_unpack_dir
= str_dup_safe(newpkg
->tmp_unpack_dir
);
341 oldpkg
->md5sum
= str_dup_safe(newpkg
->md5sum
);
343 oldpkg
->size
= str_dup_safe(newpkg
->size
);
344 if (!oldpkg
->installed_size
)
345 oldpkg
->installed_size
= str_dup_safe(newpkg
->installed_size
);
346 if (!oldpkg
->priority
)
347 oldpkg
->priority
= str_dup_safe(newpkg
->priority
);
349 oldpkg
->source
= str_dup_safe(newpkg
->source
);
350 if (oldpkg
->conffiles
.head
== NULL
){
351 oldpkg
->conffiles
= newpkg
->conffiles
;
352 conffile_list_init(&newpkg
->conffiles
);
354 if (!oldpkg
->installed_files
){
355 oldpkg
->installed_files
= newpkg
->installed_files
;
356 oldpkg
->installed_files_ref_cnt
= newpkg
->installed_files_ref_cnt
;
357 newpkg
->installed_files
= NULL
;
359 if (!oldpkg
->essential
)
360 oldpkg
->essential
= newpkg
->essential
;
365 abstract_pkg_t
*abstract_pkg_new(void)
367 abstract_pkg_t
* ab_pkg
;
369 ab_pkg
= malloc(sizeof(abstract_pkg_t
));
371 if (ab_pkg
== NULL
) {
372 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
376 if ( abstract_pkg_init(ab_pkg
) < 0 )
382 int abstract_pkg_init(abstract_pkg_t
*ab_pkg
)
384 memset(ab_pkg
, 0, sizeof(abstract_pkg_t
));
386 ab_pkg
->provided_by
= abstract_pkg_vec_alloc();
387 if (ab_pkg
->provided_by
==NULL
){
390 ab_pkg
->dependencies_checked
= 0;
391 ab_pkg
->state_status
= SS_NOT_INSTALLED
;
396 void set_flags_from_control(opkg_conf_t
*conf
, pkg_t
*pkg
){
399 char **raw_start
=NULL
;
401 temp_str
= (char *) malloc (strlen(pkg
->dest
->info_dir
)+strlen(pkg
->name
)+12);
402 if (temp_str
== NULL
){
403 opkg_message(conf
, OPKG_INFO
, "Out of memory in %s\n", __FUNCTION__
);
406 sprintf( temp_str
,"%s/%s.control",pkg
->dest
->info_dir
,pkg
->name
);
408 raw
= raw_start
= read_raw_pkgs_from_file(temp_str
);
410 opkg_message(conf
, OPKG_ERROR
, "Unable to open the control file in %s\n", __FUNCTION__
);
415 if (!pkg_valorize_other_field(pkg
, &raw
) == 0) {
416 opkg_message(conf
, OPKG_DEBUG
, "unable to read control file for %s. May be empty\n", pkg
->name
);
432 char * pkg_formatted_info(pkg_t
*pkg
)
439 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
445 line
= pkg_formatted_field(pkg
, "Package");
446 strncat(buff
,line
, strlen(line
));
449 line
= pkg_formatted_field(pkg
, "Version");
450 strncat(buff
,line
, strlen(line
));
453 line
= pkg_formatted_field(pkg
, "Depends");
454 strncat(buff
,line
, strlen(line
));
457 line
= pkg_formatted_field(pkg
, "Recommends");
458 strncat(buff
,line
, strlen(line
));
461 line
= pkg_formatted_field(pkg
, "Suggests");
462 strncat(buff
,line
, strlen(line
));
465 line
= pkg_formatted_field(pkg
, "Provides");
466 strncat(buff
,line
, strlen(line
));
469 line
= pkg_formatted_field(pkg
, "Replaces");
470 strncat(buff
,line
, strlen(line
));
473 line
= pkg_formatted_field(pkg
, "Conflicts");
474 strncat(buff
,line
, strlen(line
));
477 line
= pkg_formatted_field(pkg
, "Status");
478 strncat(buff
,line
, strlen(line
));
481 line
= pkg_formatted_field(pkg
, "Section");
482 strncat(buff
,line
, strlen(line
));
485 line
= pkg_formatted_field(pkg
, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
486 strncat(buff
,line
, strlen(line
));
489 line
= pkg_formatted_field(pkg
, "Architecture");
490 strncat(buff
,line
, strlen(line
));
493 line
= pkg_formatted_field(pkg
, "Maintainer");
494 strncat(buff
,line
, strlen(line
));
497 line
= pkg_formatted_field(pkg
, "MD5sum");
498 strncat(buff
,line
, strlen(line
));
501 line
= pkg_formatted_field(pkg
, "Size");
502 strncat(buff
,line
, strlen(line
));
505 line
= pkg_formatted_field(pkg
, "Filename");
506 strncat(buff
,line
, strlen(line
));
509 line
= pkg_formatted_field(pkg
, "Conffiles");
510 strncat(buff
,line
, strlen(line
));
513 line
= pkg_formatted_field(pkg
, "Source");
514 strncat(buff
,line
, strlen(line
));
517 line
= pkg_formatted_field(pkg
, "Description");
518 strncat(buff
,line
, strlen(line
));
521 line
= pkg_formatted_field(pkg
, "Installed-Time");
522 strncat(buff
,line
, strlen(line
));
528 char * pkg_formatted_field(pkg_t
*pkg
, const char *field
)
530 static size_t LINE_LEN
= 128;
531 char * temp
= (char *)malloc(1);
533 int flag_provide_false
= 0;
536 Pigi: After some discussion with Florian we decided to modify the full procedure in
537 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
540 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
541 goto UNKNOWN_FMT_FIELD
;
550 if (strcasecmp(field
, "Architecture") == 0) {
552 if (pkg
->architecture
) {
553 temp
= (char *)realloc(temp
,strlen(pkg
->architecture
)+17);
555 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
559 snprintf(temp
, (strlen(pkg
->architecture
)+17), "Architecture: %s\n", pkg
->architecture
);
561 } else if (strcasecmp(field
, "Auto-Installed") == 0) {
562 /* Auto-Installed flag */
563 if (pkg
->auto_installed
) {
564 char * s
= "Auto-Installed: yes\n";
565 temp
= (char *)realloc(temp
, strlen(s
) + 1);
569 goto UNKNOWN_FMT_FIELD
;
574 if (strcasecmp(field
, "Conffiles") == 0) {
576 conffile_list_elt_t
*iter
;
577 char confstr
[LINE_LEN
];
579 if (pkg
->conffiles
.head
== NULL
) {
584 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
585 if (iter
->data
->name
&& iter
->data
->value
) {
586 len
= len
+ (strlen(iter
->data
->name
)+strlen(iter
->data
->value
)+5);
589 temp
= (char *)realloc(temp
,len
);
591 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
595 strncpy(temp
, "Conffiles:\n", 12);
596 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
597 if (iter
->data
->name
&& iter
->data
->value
) {
598 snprintf(confstr
, LINE_LEN
, "%s %s\n", iter
->data
->name
, iter
->data
->value
);
599 strncat(temp
, confstr
, strlen(confstr
));
602 } else if (strcasecmp(field
, "Conflicts") == 0) {
605 if (pkg
->conflicts_count
) {
606 char conflictstr
[LINE_LEN
];
608 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
609 len
= len
+ (strlen(pkg
->conflicts_str
[i
])+5);
611 temp
= (char *)realloc(temp
,len
);
613 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
617 strncpy(temp
, "Conflicts:", 11);
618 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
619 snprintf(conflictstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->conflicts_str
[i
]);
620 strncat(temp
, conflictstr
, strlen(conflictstr
));
622 strncat(temp
, "\n", strlen("\n"));
625 goto UNKNOWN_FMT_FIELD
;
630 if (strcasecmp(field
, "Depends") == 0) {
634 if (pkg
->depends_count
) {
635 char depstr
[LINE_LEN
];
637 for(i
= 0; i
< pkg
->depends_count
; i
++) {
638 len
= len
+ (strlen(pkg
->depends_str
[i
])+4);
640 temp
= (char *)realloc(temp
,len
);
642 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
646 strncpy(temp
, "Depends:", 10);
647 for(i
= 0; i
< pkg
->depends_count
; i
++) {
648 snprintf(depstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->depends_str
[i
]);
649 strncat(temp
, depstr
, strlen(depstr
));
651 strncat(temp
, "\n", strlen("\n"));
653 } else if (strcasecmp(field
, "Description") == 0) {
655 if (pkg
->description
) {
656 temp
= (char *)realloc(temp
,strlen(pkg
->description
)+16);
658 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
662 snprintf(temp
, (strlen(pkg
->description
)+16), "Description: %s\n", pkg
->description
);
665 goto UNKNOWN_FMT_FIELD
;
671 if (pkg
->essential
) {
672 temp
= (char *)realloc(temp
,16);
674 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
678 snprintf(temp
, (16), "Essential: yes\n");
686 temp
= (char *)realloc(temp
,strlen(pkg
->filename
)+12);
688 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
692 snprintf(temp
, (strlen(pkg
->filename
)+12), "Filename: %s\n", pkg
->filename
);
698 if (strcasecmp(field
, "Installed-Size") == 0) {
700 temp
= (char *)realloc(temp
,strlen(pkg
->installed_size
)+17);
702 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
706 snprintf(temp
, (strlen(pkg
->installed_size
)+17), "Installed-Size: %s\n", pkg
->installed_size
);
707 } else if (strcasecmp(field
, "Installed-Time") == 0 && pkg
->installed_time
) {
708 temp
= (char *)realloc(temp
,29);
710 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
714 snprintf(temp
, 29, "Installed-Time: %lu\n", pkg
->installed_time
);
720 /* Maintainer | MD5sum */
721 if (strcasecmp(field
, "Maintainer") == 0) {
723 if (pkg
->maintainer
) {
724 temp
= (char *)realloc(temp
,strlen(pkg
->maintainer
)+14);
726 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
730 snprintf(temp
, (strlen(pkg
->maintainer
)+14), "maintainer: %s\n", pkg
->maintainer
);
732 } else if (strcasecmp(field
, "MD5sum") == 0) {
735 temp
= (char *)realloc(temp
,strlen(pkg
->md5sum
)+11);
737 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
741 snprintf(temp
, (strlen(pkg
->md5sum
)+11), "MD5Sum: %s\n", pkg
->md5sum
);
744 goto UNKNOWN_FMT_FIELD
;
750 if (strcasecmp(field
, "Package") == 0) {
752 temp
= (char *)realloc(temp
,strlen(pkg
->name
)+11);
754 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
758 snprintf(temp
, (strlen(pkg
->name
)+11), "Package: %s\n", pkg
->name
);
759 } else if (strcasecmp(field
, "Priority") == 0) {
761 temp
= (char *)realloc(temp
,strlen(pkg
->priority
)+12);
763 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
767 snprintf(temp
, (strlen(pkg
->priority
)+12), "Priority: %s\n", pkg
->priority
);
768 } else if (strcasecmp(field
, "Provides") == 0) {
772 if (pkg
->provides_count
) {
773 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
774 for ( i
=0; i
< pkg
->provides_count
; i
++ ){
775 if (strstr(pkg
->provides_str
[i
],"opkg_internal_use_only")!=NULL
) {
776 memset (pkg
->provides_str
[i
],'\x0',strlen(pkg
->provides_str
[i
])); /* Pigi clear my trick flag, just in case */
777 flag_provide_false
= 1;
780 if ( !flag_provide_false
|| /* Pigi there is not my trick flag */
781 ((flag_provide_false
) && (pkg
->provides_count
> 1))){ /* Pigi There is, but we also have others Provides */
782 char provstr
[LINE_LEN
];
784 for(i
= 0; i
< pkg
->provides_count
; i
++) {
785 len
= len
+ (strlen(pkg
->provides_str
[i
])+5);
787 temp
= (char *)realloc(temp
,len
);
789 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
793 strncpy(temp
, "Provides:", 12);
794 for(i
= 0; i
< pkg
->provides_count
; i
++) {
795 if (strlen(pkg
->provides_str
[i
])>0){;
796 snprintf(provstr
, LINE_LEN
, "%s %s", i
== 1 ? "" : ",", pkg
->provides_str
[i
]);
797 strncat(temp
, provstr
, strlen(provstr
));
800 strncat(temp
, "\n", strlen("\n"));
804 goto UNKNOWN_FMT_FIELD
;
811 /* Replaces | Recommends*/
812 if (strcasecmp (field
, "Replaces") == 0) {
813 if (pkg
->replaces_count
) {
814 char replstr
[LINE_LEN
];
816 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
817 len
= len
+ (strlen(pkg
->replaces_str
[i
])+5);
819 temp
= (char *)realloc(temp
,len
);
821 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
825 strncpy(temp
, "Replaces:", 12);
826 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
827 snprintf(replstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->replaces_str
[i
]);
828 strncat(temp
, replstr
, strlen(replstr
));
830 strncat(temp
, "\n", strlen("\n"));
832 } else if (strcasecmp (field
, "Recommends") == 0) {
833 if (pkg
->recommends_count
) {
834 char recstr
[LINE_LEN
];
836 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
837 len
= len
+ (strlen( pkg
->recommends_str
[i
])+5);
839 temp
= (char *)realloc(temp
,len
);
841 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
845 strncpy(temp
, "Recommends:", 13);
846 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
847 snprintf(recstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->recommends_str
[i
]);
848 strncat(temp
, recstr
, strlen(recstr
));
850 strncat(temp
, "\n", strlen("\n"));
853 goto UNKNOWN_FMT_FIELD
;
859 /* Section | Size | Source | Status | Suggests */
860 if (strcasecmp(field
, "Section") == 0) {
863 temp
= (char *)realloc(temp
,strlen(pkg
->section
)+11);
865 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
869 snprintf(temp
, (strlen(pkg
->section
)+11), "Section: %s\n", pkg
->section
);
871 } else if (strcasecmp(field
, "Size") == 0) {
874 temp
= (char *)realloc(temp
,strlen(pkg
->size
)+8);
876 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
880 snprintf(temp
, (strlen(pkg
->size
)+8), "Size: %s\n", pkg
->size
);
882 } else if (strcasecmp(field
, "Source") == 0) {
885 temp
= (char *)realloc(temp
,strlen(pkg
->source
)+10);
887 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
891 snprintf(temp
, (strlen(pkg
->source
)+10), "Source: %s\n", pkg
->source
);
893 } else if (strcasecmp(field
, "Status") == 0) {
895 /* Benjamin Pineau note: we should avoid direct usage of
896 * strlen(arg) without keeping "arg" for later free()
898 char *pflag
=pkg_state_flag_to_str(pkg
->state_flag
);
899 char *pstat
=pkg_state_status_to_str(pkg
->state_status
);
900 char *pwant
=pkg_state_want_to_str(pkg
->state_want
);
902 size_t sum_of_sizes
= (size_t) ( strlen(pwant
)+ strlen(pflag
)+ strlen(pstat
) + 12 );
903 temp
= (char *)realloc(temp
,sum_of_sizes
);
905 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
909 snprintf(temp
, sum_of_sizes
, "Status: %s %s %s\n", pwant
, pflag
, pstat
);
912 if(pstat
) /* pfstat can be NULL if ENOMEM */
914 } else if (strcasecmp(field
, "Suggests") == 0) {
915 if (pkg
->suggests_count
) {
917 char sugstr
[LINE_LEN
];
919 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
920 len
= len
+ (strlen(pkg
->suggests_str
[i
])+5);
922 temp
= (char *)realloc(temp
,len
);
924 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
928 strncpy(temp
, "Suggests:", 10);
929 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
930 snprintf(sugstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->suggests_str
[i
]);
931 strncat(temp
, sugstr
, strlen(sugstr
));
933 strncat(temp
, "\n", strlen("\n"));
936 goto UNKNOWN_FMT_FIELD
;
943 char *version
= pkg_version_str_alloc(pkg
);
944 temp
= (char *)realloc(temp
,strlen(version
)+14);
946 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
950 snprintf(temp
, (strlen(version
)+12), "Version: %s\n", version
);
955 goto UNKNOWN_FMT_FIELD
;
958 if ( strlen(temp
)<2 ) {
964 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__
, field
);
965 if ( strlen(temp
)<2 ) {
972 void pkg_print_info(pkg_t
*pkg
, FILE *file
)
979 buff
= pkg_formatted_info(pkg
);
983 fwrite(buff
, 1, strlen(buff
), file
);
988 void pkg_print_status(pkg_t
* pkg
, FILE * file
)
994 /* XXX: QUESTION: Do we actually want more fields here? The
995 original idea was to save space by installing only what was
996 needed for actual computation, (package, version, status,
997 essential, conffiles). The assumption is that all other fields
998 can be found in th available file.
1000 But, someone proposed the idea to make it possible to
1001 reconstruct a .ipk from an installed package, (ie. for beaming
1002 from one handheld to another). So, maybe we actually want a few
1003 more fields here, (depends, suggests, etc.), so that that would
1004 be guaranteed to work even in the absence of more information
1005 from the available file.
1007 28-MAR-03: kergoth and I discussed this yesterday. We think
1008 the essential info needs to be here for all installed packages
1009 because they may not appear in the Packages files on various
1010 feeds. Furthermore, one should be able to install from URL or
1011 local storage without requiring a Packages file from any feed.
1014 pkg_print_field(pkg
, file
, "Package");
1015 pkg_print_field(pkg
, file
, "Version");
1016 pkg_print_field(pkg
, file
, "Depends");
1017 pkg_print_field(pkg
, file
, "Recommends");
1018 pkg_print_field(pkg
, file
, "Suggests");
1019 pkg_print_field(pkg
, file
, "Provides");
1020 pkg_print_field(pkg
, file
, "Replaces");
1021 pkg_print_field(pkg
, file
, "Conflicts");
1022 pkg_print_field(pkg
, file
, "Status");
1023 pkg_print_field(pkg
, file
, "Essential"); /* @@@@ should be removed in future release. */
1024 pkg_print_field(pkg
, file
, "Architecture");
1025 pkg_print_field(pkg
, file
, "Conffiles");
1026 pkg_print_field(pkg
, file
, "Installed-Time");
1027 pkg_print_field(pkg
, file
, "Auto-Installed");
1031 void pkg_print_field(pkg_t
*pkg
, FILE *file
, const char *field
)
1034 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
1035 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n",
1036 __FUNCTION__
, field
);
1038 buff
= pkg_formatted_field(pkg
, field
);
1039 if (strlen(buff
)>2) {
1040 fprintf(file
, "%s", buff
);
1048 * libdpkg - Debian packaging suite library routines
1049 * vercmp.c - comparison of version numbers
1051 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1053 int pkg_compare_versions(const pkg_t
*pkg
, const pkg_t
*ref_pkg
)
1057 if (pkg
->epoch
> ref_pkg
->epoch
) {
1061 if (pkg
->epoch
< ref_pkg
->epoch
) {
1065 r
= verrevcmp(pkg
->version
, ref_pkg
->version
);
1070 #ifdef USE_DEBVERSION
1071 r
= verrevcmp(pkg
->revision
, ref_pkg
->revision
);
1076 r
= verrevcmp(pkg
->familiar_revision
, ref_pkg
->familiar_revision
);
1082 int verrevcmp(const char *val
, const char *ref
)
1086 const char *vp
, *rp
;
1087 const char *vsep
, *rsep
;
1092 vp
= val
; while (*vp
&& !isdigit(*vp
)) vp
++;
1093 rp
= ref
; while (*rp
&& !isdigit(*rp
)) rp
++;
1095 vc
= (val
== vp
) ? 0 : *val
++;
1096 rc
= (ref
== rp
) ? 0 : *ref
++;
1097 if (!rc
&& !vc
) break;
1098 if (vc
&& !isalpha(vc
)) vc
+= 256; /* assumes ASCII character set */
1099 if (rc
&& !isalpha(rc
)) rc
+= 256;
1100 if (vc
!= rc
) return vc
- rc
;
1104 vl
=0; if (isdigit(*vp
)) vl
= strtol(val
,(char**)&val
,10);
1105 rl
=0; if (isdigit(*rp
)) rl
= strtol(ref
,(char**)&ref
,10);
1106 if (vl
!= rl
) return vl
- rl
;
1110 vsep
= strchr(".-", vc
);
1111 rsep
= strchr(".-", rc
);
1112 if (vsep
&& !rsep
) return -1;
1113 if (!vsep
&& rsep
) return +1;
1115 if (!*val
&& !*ref
) return 0;
1116 if (!*val
) return -1;
1117 if (!*ref
) return +1;
1121 int pkg_version_satisfied(pkg_t
*it
, pkg_t
*ref
, const char *op
)
1125 r
= pkg_compare_versions(it
, ref
);
1127 if (strcmp(op
, "<=") == 0 || strcmp(op
, "<") == 0) {
1131 if (strcmp(op
, ">=") == 0 || strcmp(op
, ">") == 0) {
1135 if (strcmp(op
, "<<") == 0) {
1139 if (strcmp(op
, ">>") == 0) {
1143 if (strcmp(op
, "=") == 0) {
1147 fprintf(stderr
, "unknown operator: %s", op
);
1151 int pkg_name_version_and_architecture_compare(void *p1
, void *p2
)
1153 const pkg_t
*a
= *(const pkg_t
**)p1
;
1154 const pkg_t
*b
= *(const pkg_t
**)p2
;
1157 if (!a
->name
|| !b
->name
) {
1158 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1159 a
, a
->name
, b
, b
->name
);
1163 namecmp
= strcmp(a
->name
, b
->name
);
1166 vercmp
= pkg_compare_versions(a
, b
);
1169 if (!a
->arch_priority
|| !b
->arch_priority
) {
1170 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1171 a
, a
->arch_priority
, b
, b
->arch_priority
);
1174 if (a
->arch_priority
> b
->arch_priority
)
1176 if (a
->arch_priority
< b
->arch_priority
)
1181 int abstract_pkg_name_compare(void *p1
, void *p2
)
1183 const abstract_pkg_t
*a
= *(const abstract_pkg_t
**)p1
;
1184 const abstract_pkg_t
*b
= *(const abstract_pkg_t
**)p2
;
1185 if (!a
->name
|| !b
->name
) {
1186 fprintf(stderr
, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1187 a
, a
->name
, b
, b
->name
);
1190 return strcmp(a
->name
, b
->name
);
1194 char *pkg_version_str_alloc(pkg_t
*pkg
)
1196 char *complete_version
;
1198 #ifdef USE_DEBVERSION
1200 char *familiar_revision_str
;
1204 sprintf_alloc(&epoch_str
, "%d:", pkg
->epoch
);
1206 epoch_str
= strdup("");
1209 #ifdef USE_DEBVERSION
1210 if (pkg
->revision
&& strlen(pkg
->revision
)) {
1211 sprintf_alloc(&revision_str
, "-%s", pkg
->revision
);
1213 revision_str
= strdup("");
1216 if (pkg
->familiar_revision
&& strlen(pkg
->familiar_revision
)) {
1217 sprintf_alloc(&familiar_revision_str
, "-fam%s", pkg
->familiar_revision
);
1219 familiar_revision_str
= strdup("");
1223 #ifdef USE_DEBVERSION
1224 sprintf_alloc(&complete_version
, "%s%s%s%s",
1225 epoch_str
, pkg
->version
, revision_str
, familiar_revision_str
);
1227 sprintf_alloc(&complete_version
, "%s%s",
1228 epoch_str
, pkg
->version
);
1232 #ifdef USE_DEBVERSION
1234 free(familiar_revision_str
);
1237 return complete_version
;
1240 str_list_t
*pkg_get_installed_files(pkg_t
*pkg
)
1243 char *list_file_name
= NULL
;
1244 FILE *list_file
= NULL
;
1246 char *installed_file_name
;
1249 pkg
->installed_files_ref_cnt
++;
1251 if (pkg
->installed_files
) {
1252 return pkg
->installed_files
;
1255 pkg
->installed_files
= str_list_alloc();
1256 if (pkg
->installed_files
== NULL
) {
1257 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1261 /* For uninstalled packages, get the file list firectly from the package.
1262 For installed packages, look at the package.list file in the database.
1264 if (pkg
->state_status
== SS_NOT_INSTALLED
|| pkg
->dest
== NULL
) {
1265 if (pkg
->local_filename
== NULL
) {
1266 return pkg
->installed_files
;
1268 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1269 file. In other words, change deb_extract so that it can
1270 simply return the file list as a char *[] rather than
1271 insisting on writing in to a FILE * as it does now. */
1272 list_file
= tmpfile();
1273 err
= pkg_extract_data_file_names_to_stream(pkg
, list_file
);
1276 fprintf(stderr
, "%s: Error extracting file list from %s: %s\n",
1277 __FUNCTION__
, pkg
->local_filename
, strerror(err
));
1278 return pkg
->installed_files
;
1282 sprintf_alloc(&list_file_name
, "%s/%s.list",
1283 pkg
->dest
->info_dir
, pkg
->name
);
1284 if (! file_exists(list_file_name
)) {
1285 free(list_file_name
);
1286 return pkg
->installed_files
;
1289 list_file
= fopen(list_file_name
, "r");
1290 if (list_file
== NULL
) {
1291 fprintf(stderr
, "WARNING: Cannot open %s: %s\n",
1292 list_file_name
, strerror(errno
));
1293 free(list_file_name
);
1294 return pkg
->installed_files
;
1296 free(list_file_name
);
1299 rootdirlen
= strlen( pkg
->dest
->root_dir
);
1303 line
= file_read_line_alloc(list_file
);
1310 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1311 if( strncmp( pkg
->dest
->root_dir
,
1314 if (*file_name
== '.') {
1317 if (*file_name
== '/') {
1321 /* Freed in pkg_free_installed_files */
1322 sprintf_alloc(&installed_file_name
, "%s%s", pkg
->dest
->root_dir
, file_name
);
1324 // already contains root_dir as header -> ABSOLUTE
1325 sprintf_alloc(&installed_file_name
, "%s", file_name
);
1327 str_list_append(pkg
->installed_files
, installed_file_name
);
1333 return pkg
->installed_files
;
1336 /* XXX: CLEANUP: This function and it's counterpart,
1337 (pkg_get_installed_files), do not match our init/deinit naming
1338 convention. Nor the alloc/free convention. But, then again, neither
1339 of these conventions currrently fit the way these two functions
1341 int pkg_free_installed_files(pkg_t
*pkg
)
1343 str_list_elt_t
*iter
;
1345 pkg
->installed_files_ref_cnt
--;
1346 if (pkg
->installed_files_ref_cnt
> 0) {
1350 if (pkg
->installed_files
) {
1352 for (iter
= pkg
->installed_files
->head
; iter
; iter
= iter
->next
) {
1353 /* malloced in pkg_get_installed_files */
1358 str_list_deinit(pkg
->installed_files
);
1361 pkg
->installed_files
= NULL
;
1366 int pkg_remove_installed_files_list(opkg_conf_t
*conf
, pkg_t
*pkg
)
1369 char *list_file_name
;
1371 //I don't think pkg_free_installed_files should be called here. Jamey
1372 //pkg_free_installed_files(pkg);
1374 sprintf_alloc(&list_file_name
, "%s/%s.list",
1375 pkg
->dest
->info_dir
, pkg
->name
);
1376 if (!conf
->noaction
) {
1377 err
= unlink(list_file_name
);
1378 free(list_file_name
);
1387 conffile_t
*pkg_get_conffile(pkg_t
*pkg
, const char *file_name
)
1389 conffile_list_elt_t
*iter
;
1390 conffile_t
*conffile
;
1396 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
1397 conffile
= iter
->data
;
1399 if (strcmp(conffile
->name
, file_name
) == 0) {
1407 int pkg_run_script(opkg_conf_t
*conf
, pkg_t
*pkg
,
1408 const char *script
, const char *args
)
1414 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1415 maintainer script within a chroot environment. */
1417 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1418 have scripts in pkg->tmp_unpack_dir. */
1419 if (pkg
->state_status
== SS_INSTALLED
|| pkg
->state_status
== SS_UNPACKED
) {
1420 if (pkg
->dest
== NULL
) {
1421 fprintf(stderr
, "%s: ERROR: installed package %s has a NULL dest\n",
1422 __FUNCTION__
, pkg
->name
);
1425 sprintf_alloc(&path
, "%s/%s.%s", pkg
->dest
->info_dir
, pkg
->name
, script
);
1427 if (pkg
->tmp_unpack_dir
== NULL
) {
1428 fprintf(stderr
, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1429 __FUNCTION__
, pkg
->name
);
1432 sprintf_alloc(&path
, "%s/%s", pkg
->tmp_unpack_dir
, script
);
1435 opkg_message(conf
, OPKG_INFO
, "Running script %s\n", path
);
1436 if (conf
->noaction
) return 0;
1438 /* XXX: CLEANUP: There must be a better way to handle maintainer
1439 scripts when running with offline_root mode and/or a dest other
1440 than '/'. I've been playing around with some clever chroot
1441 tricks and I might come up with something workable. */
1442 if (conf
->offline_root
) {
1443 setenv("OPKG_OFFLINE_ROOT", conf
->offline_root
, 1);
1447 pkg
->dest
? pkg
->dest
->root_dir
: conf
->default_dest
->root_dir
, 1);
1449 if (! file_exists(path
)) {
1454 if (conf
->offline_root
) {
1455 fprintf(stderr
, "(offline root mode: not running %s.%s)\n", pkg
->name
, script
);
1460 sprintf_alloc(&cmd
, "%s %s", path
, args
);
1467 fprintf(stderr
, "%s script returned status %d\n", script
, err
);
1474 char *pkg_state_want_to_str(pkg_state_want_t sw
)
1478 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1479 if (pkg_state_want_map
[i
].value
== sw
) {
1480 return strdup(pkg_state_want_map
[i
].str
);
1484 fprintf(stderr
, "%s: ERROR: Illegal value for state_want: %d\n",
1486 return strdup("<STATE_WANT_UNKNOWN>");
1489 pkg_state_want_t
pkg_state_want_from_str(char *str
)
1493 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1494 if (strcmp(str
, pkg_state_want_map
[i
].str
) == 0) {
1495 return pkg_state_want_map
[i
].value
;
1499 fprintf(stderr
, "%s: ERROR: Illegal value for state_want string: %s\n",
1504 char *pkg_state_flag_to_str(pkg_state_flag_t sf
)
1507 int len
= 3; /* ok\000 is minimum */
1510 /* clear the temporary flags before converting to string */
1511 sf
&= SF_NONVOLATILE_FLAGS
;
1514 return strdup("ok");
1517 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1518 if (sf
& pkg_state_flag_map
[i
].value
) {
1519 len
+= strlen(pkg_state_flag_map
[i
].str
) + 1;
1523 if ( str
== NULL
) {
1524 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1528 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1529 if (sf
& pkg_state_flag_map
[i
].value
) {
1530 strcat(str
, pkg_state_flag_map
[i
].str
);
1535 str
[len
-1] = 0; /* squash last comma */
1540 pkg_state_flag_t
pkg_state_flag_from_str(const char *str
)
1545 if (strcmp(str
, "ok") == 0) {
1548 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1549 const char *sfname
= pkg_state_flag_map
[i
].str
;
1550 int sfname_len
= strlen(sfname
);
1551 if (strncmp(str
, sfname
, sfname_len
) == 0) {
1552 sf
|= pkg_state_flag_map
[i
].value
;
1554 if (str
[0] == ',') {
1565 char *pkg_state_status_to_str(pkg_state_status_t ss
)
1569 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1570 if (pkg_state_status_map
[i
].value
== ss
) {
1571 return strdup(pkg_state_status_map
[i
].str
);
1575 fprintf(stderr
, "%s: ERROR: Illegal value for state_status: %d\n",
1577 return strdup("<STATE_STATUS_UNKNOWN>");
1580 pkg_state_status_t
pkg_state_status_from_str(const char *str
)
1584 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1585 if (strcmp(str
, pkg_state_status_map
[i
].str
) == 0) {
1586 return pkg_state_status_map
[i
].value
;
1590 fprintf(stderr
, "%s: ERROR: Illegal value for state_status string: %s\n",
1592 return SS_NOT_INSTALLED
;
1595 int pkg_arch_supported(opkg_conf_t
*conf
, pkg_t
*pkg
)
1597 nv_pair_list_elt_t
*l
;
1599 if (!pkg
->architecture
)
1602 l
= conf
->arch_list
.head
;
1605 nv_pair_t
*nv
= l
->data
;
1606 if (strcmp(nv
->name
, pkg
->architecture
) == 0) {
1607 opkg_message(conf
, OPKG_DEBUG
, "arch %s (priority %s) supported for pkg %s\n", nv
->name
, nv
->value
, pkg
->name
);
1613 opkg_message(conf
, OPKG_DEBUG
, "arch %s unsupported for pkg %s\n", pkg
->architecture
, pkg
->name
);
1617 int pkg_get_arch_priority(opkg_conf_t
*conf
, const char *archname
)
1619 nv_pair_list_elt_t
*l
;
1621 l
= conf
->arch_list
.head
;
1624 nv_pair_t
*nv
= l
->data
;
1625 if (strcmp(nv
->name
, archname
) == 0) {
1626 int priority
= strtol(nv
->value
, NULL
, 0);
1634 int pkg_info_preinstall_check(opkg_conf_t
*conf
)
1637 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1638 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1639 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1641 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: updating arch priority for each package\n");
1642 pkg_hash_fetch_available(pkg_hash
, available_pkgs
);
1643 /* update arch_priority for each package */
1644 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1645 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1646 int arch_priority
= 1;
1649 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1650 if (pkg
->architecture
)
1651 arch_priority
= pkg_get_arch_priority(conf
, pkg
->architecture
);
1653 opkg_message(conf
, OPKG_ERROR
, "pkg_info_preinstall_check: no architecture for package %s\n", pkg
->name
);
1654 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1655 pkg
->arch_priority
= arch_priority
;
1658 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1659 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1660 if (!pkg
->arch_priority
&& (pkg
->state_flag
|| (pkg
->state_want
!= SW_UNKNOWN
))) {
1661 /* clear flags and want for any uninstallable package */
1662 opkg_message(conf
, OPKG_NOTICE
, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1663 pkg
->name
, pkg
->arch_priority
, pkg
->state_flag
, pkg
->state_want
);
1664 pkg
->state_want
= SW_UNKNOWN
;
1665 pkg
->state_flag
= 0;
1668 pkg_vec_free(available_pkgs
);
1670 /* update the file owner data structure */
1671 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: update file owner list\n");
1672 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1673 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1674 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1675 str_list_t
*installed_files
= pkg_get_installed_files(pkg
); /* this causes installed_files to be cached */
1676 str_list_elt_t
*iter
;
1677 if (installed_files
== NULL
) {
1678 opkg_message(conf
, OPKG_ERROR
, "No installed files for pkg %s\n", pkg
->name
);
1681 for (iter
= installed_files
->head
; iter
; iter
= iter
->next
) {
1682 char *installed_file
= iter
->data
;
1683 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1684 file_hash_set_file_owner(conf
, installed_file
, pkg
);
1687 pkg_vec_free(installed_pkgs
);
1692 struct pkg_write_filelist_data
{
1698 void pkg_write_filelist_helper(const char *key
, void *entry_
, void *data_
)
1700 struct pkg_write_filelist_data
*data
= data_
;
1701 pkg_t
*entry
= entry_
;
1702 if (entry
== data
->pkg
) {
1703 fprintf(data
->stream
, "%s\n", key
);
1707 int pkg_write_filelist(opkg_conf_t
*conf
, pkg_t
*pkg
)
1709 struct pkg_write_filelist_data data
;
1710 char *list_file_name
= NULL
;
1714 opkg_message(conf
, OPKG_ERROR
, "Null pkg\n");
1717 opkg_message(conf
, OPKG_INFO
,
1718 " creating %s.list file\n", pkg
->name
);
1719 sprintf_alloc(&list_file_name
, "%s/%s.list", pkg
->dest
->info_dir
, pkg
->name
);
1720 if (!list_file_name
) {
1721 opkg_message(conf
, OPKG_ERROR
, "Failed to alloc list_file_name\n");
1724 opkg_message(conf
, OPKG_INFO
,
1725 " creating %s file for pkg %s\n", list_file_name
, pkg
->name
);
1726 data
.stream
= fopen(list_file_name
, "w");
1728 opkg_message(conf
, OPKG_ERROR
, "Could not open %s for writing: %s\n",
1729 list_file_name
, strerror(errno
));
1734 hash_table_foreach(&conf
->file_hash
, pkg_write_filelist_helper
, &data
);
1735 fclose(data
.stream
);
1736 free(list_file_name
);
1741 int pkg_write_changed_filelists(opkg_conf_t
*conf
)
1743 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1744 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1750 opkg_message(conf
, OPKG_INFO
, "%s: saving changed filelists\n", __FUNCTION__
);
1751 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1752 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1753 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1754 if (pkg
->state_flag
& SF_FILELIST_CHANGED
) {
1755 opkg_message(conf
, OPKG_DEBUG
, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg
->name
, __FUNCTION__
);
1756 err
= pkg_write_filelist(conf
, pkg
);
1758 opkg_message(conf
, OPKG_NOTICE
, "pkg_write_filelist pkg=%s returned %d\n", pkg
->name
, err
);