1 /* pkg.c - the opkg package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
25 #include "pkg_parse.h"
26 #include "pkg_extract.h"
27 #include "opkg_message.h"
28 #include "opkg_utils.h"
30 #include "sprintf_alloc.h"
31 #include "file_util.h"
34 #include "opkg_conf.h"
36 typedef struct enum_map enum_map_t
;
43 static const enum_map_t pkg_state_want_map
[] = {
44 { SW_UNKNOWN
, "unknown"},
45 { SW_INSTALL
, "install"},
46 { SW_DEINSTALL
, "deinstall"},
50 static const enum_map_t pkg_state_flag_map
[] = {
52 { SF_REINSTREQ
, "reinstreq"},
54 { SF_REPLACE
, "replace"},
55 { SF_NOPRUNE
, "noprune"},
56 { SF_PREFER
, "prefer"},
57 { SF_OBSOLETE
, "obsolete"},
61 static const enum_map_t pkg_state_status_map
[] = {
62 { SS_NOT_INSTALLED
, "not-installed" },
63 { SS_UNPACKED
, "unpacked" },
64 { SS_HALF_CONFIGURED
, "half-configured" },
65 { SS_INSTALLED
, "installed" },
66 { SS_HALF_INSTALLED
, "half-installed" },
67 { SS_CONFIG_FILES
, "config-files" },
68 { SS_POST_INST_FAILED
, "post-inst-failed" },
69 { SS_REMOVAL_FAILED
, "removal-failed" }
72 static int verrevcmp(const char *val
, const char *ref
);
79 pkg
= malloc(sizeof(pkg_t
));
81 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
90 int pkg_init(pkg_t
*pkg
)
92 memset(pkg
, 0, sizeof(pkg_t
));
99 pkg
->architecture
= NULL
;
100 pkg
->maintainer
= NULL
;
102 pkg
->description
= NULL
;
103 pkg
->state_want
= SW_UNKNOWN
;
104 pkg
->state_flag
= SF_OK
;
105 pkg
->state_status
= SS_NOT_INSTALLED
;
106 pkg
->depends_str
= NULL
;
107 pkg
->provides_str
= NULL
;
108 pkg
->depends_count
= 0;
110 pkg
->suggests_str
= NULL
;
111 pkg
->recommends_str
= NULL
;
112 pkg
->suggests_count
= 0;
113 pkg
->recommends_count
= 0;
115 /* Abhaya: added init for conflicts fields */
116 pkg
->conflicts
= NULL
;
117 pkg
->conflicts_count
= 0;
119 /* added for replaces. Jamey 7/23/2002 */
120 pkg
->replaces
= NULL
;
121 pkg
->replaces_count
= 0;
123 pkg
->pre_depends_count
= 0;
124 pkg
->pre_depends_str
= NULL
;
125 pkg
->provides_count
= 0;
126 pkg
->provides
= NULL
;
127 pkg
->filename
= NULL
;
128 pkg
->local_filename
= NULL
;
129 pkg
->tmp_unpack_dir
= NULL
;
132 pkg
->installed_size
= NULL
;
133 pkg
->priority
= NULL
;
135 conffile_list_init(&pkg
->conffiles
);
136 pkg
->installed_files
= NULL
;
137 pkg
->installed_files_ref_cnt
= 0;
139 pkg
->provided_by_hand
= 0;
144 void compound_depend_deinit (compound_depend_t
*depends
)
147 for (i
= 0; i
< depends
->possibility_count
; i
++)
150 d
= depends
->possibilities
[i
];
154 free (depends
->possibilities
);
157 void pkg_deinit(pkg_t
*pkg
)
166 /* revision shares storage with version, so
168 pkg
->revision
= NULL
;
169 /* owned by opkg_conf_t */
171 /* owned by opkg_conf_t */
173 free(pkg
->architecture
);
174 pkg
->architecture
= NULL
;
175 free(pkg
->maintainer
);
176 pkg
->maintainer
= NULL
;
179 free(pkg
->description
);
180 pkg
->description
= NULL
;
181 pkg
->state_want
= SW_UNKNOWN
;
182 pkg
->state_flag
= SF_OK
;
183 pkg
->state_status
= SS_NOT_INSTALLED
;
185 //for (i = 0; i < pkg->replaces_count; i++)
186 free (pkg
->replaces
);
187 pkg
->replaces
= NULL
;
189 for (i
= 0; i
< pkg
->depends_count
; i
++)
190 free (pkg
->depends_str
[i
]);
191 free(pkg
->depends_str
);
192 pkg
->depends_str
= NULL
;
194 for (i
= 0; i
< pkg
->provides_count
; i
++)
195 free (pkg
->provides_str
[i
]);
196 free(pkg
->provides_str
);
197 pkg
->provides_str
= NULL
;
199 for (i
= 0; i
< pkg
->conflicts_count
; i
++)
200 free (pkg
->conflicts_str
[i
]);
201 free(pkg
->conflicts_str
);
202 pkg
->conflicts_str
= NULL
;
204 for (i
= 0; i
< pkg
->replaces_count
; i
++)
205 free (pkg
->replaces_str
[i
]);
206 free(pkg
->replaces_str
);
207 pkg
->replaces_str
= NULL
;
209 for (i
= 0; i
< pkg
->recommends_count
; i
++)
210 free (pkg
->recommends_str
[i
]);
211 free(pkg
->recommends_str
);
212 pkg
->recommends_str
= NULL
;
214 for (i
= 0; i
< pkg
->suggests_count
; i
++)
215 free (pkg
->suggests_str
[i
]);
216 free(pkg
->suggests_str
);
217 pkg
->suggests_str
= NULL
;
221 int count
= pkg
->pre_depends_count
+ pkg
->depends_count
+ pkg
->recommends_count
+ pkg
->suggests_count
;
224 for (x
= 0; x
< count
; x
++)
225 compound_depend_deinit (&pkg
->depends
[x
]);
232 for (x
= 0; x
< pkg
->conflicts_count
; x
++)
233 compound_depend_deinit (&pkg
->conflicts
[x
]);
234 free (pkg
->conflicts
);
237 free (pkg
->provides
);
239 pkg
->pre_depends_count
= 0;
240 free(pkg
->pre_depends_str
);
241 pkg
->pre_depends_str
= NULL
;
242 pkg
->provides_count
= 0;
244 pkg
->filename
= NULL
;
245 free(pkg
->local_filename
);
246 pkg
->local_filename
= NULL
;
247 /* CLEANUP: It'd be nice to pullin the cleanup function from
248 opkg_install.c here. See comment in
249 opkg_install.c:cleanup_temporary_files */
250 free(pkg
->tmp_unpack_dir
);
251 pkg
->tmp_unpack_dir
= NULL
;
256 free(pkg
->installed_size
);
257 pkg
->installed_size
= NULL
;
259 pkg
->priority
= NULL
;
262 conffile_list_deinit(&pkg
->conffiles
);
263 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
264 since if they are calling deinit, they should know. Maybe do an
265 assertion here instead? */
266 pkg
->installed_files_ref_cnt
= 1;
267 pkg_free_installed_files(pkg
);
273 int pkg_init_from_file(pkg_t
*pkg
, const char *filename
)
280 if (err
) { return err
; }
282 pkg
->local_filename
= strdup(filename
);
284 control_file
= tmpfile();
285 err
= pkg_extract_control_file_to_stream(pkg
, control_file
);
286 if (err
) { return err
; }
288 rewind(control_file
);
289 raw
= read_raw_pkgs_from_stream(control_file
);
290 pkg_parse_raw(pkg
, &raw
, NULL
, NULL
);
292 fclose(control_file
);
297 /* Merge any new information in newpkg into oldpkg */
298 /* XXX: CLEANUP: This function shouldn't actually modify anything in
299 newpkg, but should leave it usable. This rework is so that
300 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
302 * uh, i thought that i had originally written this so that it took
303 * two pkgs and returned a new one? we can do that again... -sma
305 int pkg_merge(pkg_t
*oldpkg
, pkg_t
*newpkg
, int set_status
)
307 if (oldpkg
== newpkg
) {
312 oldpkg
->src
= newpkg
->src
;
314 oldpkg
->dest
= newpkg
->dest
;
315 if (!oldpkg
->architecture
)
316 oldpkg
->architecture
= str_dup_safe(newpkg
->architecture
);
317 if (!oldpkg
->arch_priority
)
318 oldpkg
->arch_priority
= newpkg
->arch_priority
;
319 if (!oldpkg
->section
)
320 oldpkg
->section
= str_dup_safe(newpkg
->section
);
321 if(!oldpkg
->maintainer
)
322 oldpkg
->maintainer
= str_dup_safe(newpkg
->maintainer
);
323 if(!oldpkg
->description
)
324 oldpkg
->description
= str_dup_safe(newpkg
->description
);
326 /* merge the state_flags from the new package */
327 oldpkg
->state_want
= newpkg
->state_want
;
328 oldpkg
->state_status
= newpkg
->state_status
;
329 oldpkg
->state_flag
= newpkg
->state_flag
;
331 if (oldpkg
->state_want
== SW_UNKNOWN
)
332 oldpkg
->state_want
= newpkg
->state_want
;
333 if (oldpkg
->state_status
== SS_NOT_INSTALLED
)
334 oldpkg
->state_status
= newpkg
->state_status
;
335 oldpkg
->state_flag
|= newpkg
->state_flag
;
338 if (!oldpkg
->depends_str
&& !oldpkg
->pre_depends_str
&& !oldpkg
->recommends_str
&& !oldpkg
->suggests_str
) {
339 oldpkg
->depends_str
= newpkg
->depends_str
;
340 newpkg
->depends_str
= NULL
;
341 oldpkg
->depends_count
= newpkg
->depends_count
;
342 newpkg
->depends_count
= 0;
344 oldpkg
->depends
= newpkg
->depends
;
345 newpkg
->depends
= NULL
;
347 oldpkg
->pre_depends_str
= newpkg
->pre_depends_str
;
348 newpkg
->pre_depends_str
= NULL
;
349 oldpkg
->pre_depends_count
= newpkg
->pre_depends_count
;
350 newpkg
->pre_depends_count
= 0;
352 oldpkg
->recommends_str
= newpkg
->recommends_str
;
353 newpkg
->recommends_str
= NULL
;
354 oldpkg
->recommends_count
= newpkg
->recommends_count
;
355 newpkg
->recommends_count
= 0;
357 oldpkg
->suggests_str
= newpkg
->suggests_str
;
358 newpkg
->suggests_str
= NULL
;
359 oldpkg
->suggests_count
= newpkg
->suggests_count
;
360 newpkg
->suggests_count
= 0;
363 if (!oldpkg
->provides_str
) {
364 oldpkg
->provides_str
= newpkg
->provides_str
;
365 newpkg
->provides_str
= NULL
;
366 oldpkg
->provides_count
= newpkg
->provides_count
;
367 newpkg
->provides_count
= 0;
369 oldpkg
->provides
= newpkg
->provides
;
370 newpkg
->provides
= NULL
;
373 if (!oldpkg
->conflicts_str
) {
374 oldpkg
->conflicts_str
= newpkg
->conflicts_str
;
375 newpkg
->conflicts_str
= NULL
;
376 oldpkg
->conflicts_count
= newpkg
->conflicts_count
;
377 newpkg
->conflicts_count
= 0;
379 oldpkg
->conflicts
= newpkg
->conflicts
;
380 newpkg
->conflicts
= NULL
;
383 if (!oldpkg
->replaces_str
) {
384 oldpkg
->replaces_str
= newpkg
->replaces_str
;
385 newpkg
->replaces_str
= NULL
;
386 oldpkg
->replaces_count
= newpkg
->replaces_count
;
387 newpkg
->replaces_count
= 0;
389 oldpkg
->replaces
= newpkg
->replaces
;
390 newpkg
->replaces
= NULL
;
393 if (!oldpkg
->filename
)
394 oldpkg
->filename
= str_dup_safe(newpkg
->filename
);
396 fprintf(stdout
, "pkg=%s old local_filename=%s new local_filename=%s\n",
397 oldpkg
->name
, oldpkg
->local_filename
, newpkg
->local_filename
);
398 if (!oldpkg
->local_filename
)
399 oldpkg
->local_filename
= str_dup_safe(newpkg
->local_filename
);
400 if (!oldpkg
->tmp_unpack_dir
)
401 oldpkg
->tmp_unpack_dir
= str_dup_safe(newpkg
->tmp_unpack_dir
);
403 oldpkg
->md5sum
= str_dup_safe(newpkg
->md5sum
);
405 oldpkg
->size
= str_dup_safe(newpkg
->size
);
406 if (!oldpkg
->installed_size
)
407 oldpkg
->installed_size
= str_dup_safe(newpkg
->installed_size
);
408 if (!oldpkg
->priority
)
409 oldpkg
->priority
= str_dup_safe(newpkg
->priority
);
411 oldpkg
->source
= str_dup_safe(newpkg
->source
);
412 if (oldpkg
->conffiles
.head
== NULL
){
413 oldpkg
->conffiles
= newpkg
->conffiles
;
414 conffile_list_init(&newpkg
->conffiles
);
416 if (!oldpkg
->installed_files
){
417 oldpkg
->installed_files
= newpkg
->installed_files
;
418 oldpkg
->installed_files_ref_cnt
= newpkg
->installed_files_ref_cnt
;
419 newpkg
->installed_files
= NULL
;
421 if (!oldpkg
->essential
)
422 oldpkg
->essential
= newpkg
->essential
;
427 abstract_pkg_t
*abstract_pkg_new(void)
429 abstract_pkg_t
* ab_pkg
;
431 ab_pkg
= malloc(sizeof(abstract_pkg_t
));
433 if (ab_pkg
== NULL
) {
434 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
438 if ( abstract_pkg_init(ab_pkg
) < 0 )
444 int abstract_pkg_init(abstract_pkg_t
*ab_pkg
)
446 memset(ab_pkg
, 0, sizeof(abstract_pkg_t
));
448 ab_pkg
->provided_by
= abstract_pkg_vec_alloc();
449 if (ab_pkg
->provided_by
==NULL
){
452 ab_pkg
->dependencies_checked
= 0;
453 ab_pkg
->state_status
= SS_NOT_INSTALLED
;
458 void set_flags_from_control(opkg_conf_t
*conf
, pkg_t
*pkg
){
461 char **raw_start
=NULL
;
463 temp_str
= (char *) malloc (strlen(pkg
->dest
->info_dir
)+strlen(pkg
->name
)+12);
464 if (temp_str
== NULL
){
465 opkg_message(conf
, OPKG_INFO
, "Out of memory in %s\n", __FUNCTION__
);
468 sprintf( temp_str
,"%s/%s.control",pkg
->dest
->info_dir
,pkg
->name
);
470 raw
= raw_start
= read_raw_pkgs_from_file(temp_str
);
472 opkg_message(conf
, OPKG_ERROR
, "Unable to open the control file in %s\n", __FUNCTION__
);
477 if (!pkg_valorize_other_field(pkg
, &raw
) == 0) {
478 opkg_message(conf
, OPKG_DEBUG
, "unable to read control file for %s. May be empty\n", pkg
->name
);
494 char * pkg_formatted_info(pkg_t
*pkg
)
501 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
507 line
= pkg_formatted_field(pkg
, "Package");
508 strncat(buff
,line
, strlen(line
));
511 line
= pkg_formatted_field(pkg
, "Version");
512 strncat(buff
,line
, strlen(line
));
515 line
= pkg_formatted_field(pkg
, "Depends");
516 strncat(buff
,line
, strlen(line
));
519 line
= pkg_formatted_field(pkg
, "Recommends");
520 strncat(buff
,line
, strlen(line
));
523 line
= pkg_formatted_field(pkg
, "Suggests");
524 strncat(buff
,line
, strlen(line
));
527 line
= pkg_formatted_field(pkg
, "Provides");
528 strncat(buff
,line
, strlen(line
));
531 line
= pkg_formatted_field(pkg
, "Replaces");
532 strncat(buff
,line
, strlen(line
));
535 line
= pkg_formatted_field(pkg
, "Conflicts");
536 strncat(buff
,line
, strlen(line
));
539 line
= pkg_formatted_field(pkg
, "Status");
540 strncat(buff
,line
, strlen(line
));
543 line
= pkg_formatted_field(pkg
, "Section");
544 strncat(buff
,line
, strlen(line
));
547 line
= pkg_formatted_field(pkg
, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
548 strncat(buff
,line
, strlen(line
));
551 line
= pkg_formatted_field(pkg
, "Architecture");
552 strncat(buff
,line
, strlen(line
));
555 line
= pkg_formatted_field(pkg
, "Maintainer");
556 strncat(buff
,line
, strlen(line
));
559 line
= pkg_formatted_field(pkg
, "MD5sum");
560 strncat(buff
,line
, strlen(line
));
563 line
= pkg_formatted_field(pkg
, "Size");
564 strncat(buff
,line
, strlen(line
));
567 line
= pkg_formatted_field(pkg
, "Filename");
568 strncat(buff
,line
, strlen(line
));
571 line
= pkg_formatted_field(pkg
, "Conffiles");
572 strncat(buff
,line
, strlen(line
));
575 line
= pkg_formatted_field(pkg
, "Source");
576 strncat(buff
,line
, strlen(line
));
579 line
= pkg_formatted_field(pkg
, "Description");
580 strncat(buff
,line
, strlen(line
));
583 line
= pkg_formatted_field(pkg
, "Installed-Time");
584 strncat(buff
,line
, strlen(line
));
587 line
= pkg_formatted_field(pkg
, "Tags");
588 strncat(buff
,line
, strlen(line
));
594 char * pkg_formatted_field(pkg_t
*pkg
, const char *field
)
596 static size_t LINE_LEN
= 128;
597 char * temp
= (char *)malloc(1);
599 int flag_provide_false
= 0;
602 Pigi: After some discussion with Florian we decided to modify the full procedure in
603 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
606 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
607 goto UNKNOWN_FMT_FIELD
;
616 if (strcasecmp(field
, "Architecture") == 0) {
618 if (pkg
->architecture
) {
619 temp
= (char *)realloc(temp
,strlen(pkg
->architecture
)+17);
621 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
625 snprintf(temp
, (strlen(pkg
->architecture
)+17), "Architecture: %s\n", pkg
->architecture
);
627 } else if (strcasecmp(field
, "Auto-Installed") == 0) {
628 /* Auto-Installed flag */
629 if (pkg
->auto_installed
) {
630 char * s
= "Auto-Installed: yes\n";
631 temp
= (char *)realloc(temp
, strlen(s
) + 1);
635 goto UNKNOWN_FMT_FIELD
;
640 if (strcasecmp(field
, "Conffiles") == 0) {
642 conffile_list_elt_t
*iter
;
643 char confstr
[LINE_LEN
];
645 if (pkg
->conffiles
.head
== NULL
) {
650 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
651 if (iter
->data
->name
&& iter
->data
->value
) {
652 len
= len
+ (strlen(iter
->data
->name
)+strlen(iter
->data
->value
)+5);
655 temp
= (char *)realloc(temp
,len
);
657 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
661 strncpy(temp
, "Conffiles:\n", 12);
662 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
663 if (iter
->data
->name
&& iter
->data
->value
) {
664 snprintf(confstr
, LINE_LEN
, "%s %s\n", iter
->data
->name
, iter
->data
->value
);
665 strncat(temp
, confstr
, strlen(confstr
));
668 } else if (strcasecmp(field
, "Conflicts") == 0) {
671 if (pkg
->conflicts_count
) {
672 char conflictstr
[LINE_LEN
];
674 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
675 len
= len
+ (strlen(pkg
->conflicts_str
[i
])+5);
677 temp
= (char *)realloc(temp
,len
);
679 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
683 strncpy(temp
, "Conflicts:", 11);
684 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
685 snprintf(conflictstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->conflicts_str
[i
]);
686 strncat(temp
, conflictstr
, strlen(conflictstr
));
688 strncat(temp
, "\n", strlen("\n"));
691 goto UNKNOWN_FMT_FIELD
;
696 if (strcasecmp(field
, "Depends") == 0) {
700 if (pkg
->depends_count
) {
701 char depstr
[LINE_LEN
];
703 for(i
= 0; i
< pkg
->depends_count
; i
++) {
704 len
= len
+ (strlen(pkg
->depends_str
[i
])+4);
706 temp
= (char *)realloc(temp
,len
);
708 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
712 strncpy(temp
, "Depends:", 10);
713 for(i
= 0; i
< pkg
->depends_count
; i
++) {
714 snprintf(depstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->depends_str
[i
]);
715 strncat(temp
, depstr
, strlen(depstr
));
717 strncat(temp
, "\n", strlen("\n"));
719 } else if (strcasecmp(field
, "Description") == 0) {
721 if (pkg
->description
) {
722 temp
= (char *)realloc(temp
,strlen(pkg
->description
)+16);
724 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
728 snprintf(temp
, (strlen(pkg
->description
)+16), "Description: %s\n", pkg
->description
);
731 goto UNKNOWN_FMT_FIELD
;
737 if (pkg
->essential
) {
738 temp
= (char *)realloc(temp
,16);
740 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
744 snprintf(temp
, (16), "Essential: yes\n");
752 temp
= (char *)realloc(temp
,strlen(pkg
->filename
)+12);
754 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
758 snprintf(temp
, (strlen(pkg
->filename
)+12), "Filename: %s\n", pkg
->filename
);
764 if (strcasecmp(field
, "Installed-Size") == 0) {
766 temp
= (char *)realloc(temp
,strlen(pkg
->installed_size
)+17);
768 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
772 snprintf(temp
, (strlen(pkg
->installed_size
)+17), "Installed-Size: %s\n", pkg
->installed_size
);
773 } else if (strcasecmp(field
, "Installed-Time") == 0 && pkg
->installed_time
) {
774 temp
= (char *)realloc(temp
,29);
776 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
780 snprintf(temp
, 29, "Installed-Time: %lu\n", pkg
->installed_time
);
786 /* Maintainer | MD5sum */
787 if (strcasecmp(field
, "Maintainer") == 0) {
789 if (pkg
->maintainer
) {
790 temp
= (char *)realloc(temp
,strlen(pkg
->maintainer
)+14);
792 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
796 snprintf(temp
, (strlen(pkg
->maintainer
)+14), "maintainer: %s\n", pkg
->maintainer
);
798 } else if (strcasecmp(field
, "MD5sum") == 0) {
801 temp
= (char *)realloc(temp
,strlen(pkg
->md5sum
)+11);
803 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
807 snprintf(temp
, (strlen(pkg
->md5sum
)+11), "MD5Sum: %s\n", pkg
->md5sum
);
810 goto UNKNOWN_FMT_FIELD
;
816 if (strcasecmp(field
, "Package") == 0) {
818 temp
= (char *)realloc(temp
,strlen(pkg
->name
)+11);
820 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
824 snprintf(temp
, (strlen(pkg
->name
)+11), "Package: %s\n", pkg
->name
);
825 } else if (strcasecmp(field
, "Priority") == 0) {
827 temp
= (char *)realloc(temp
,strlen(pkg
->priority
)+12);
829 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
833 snprintf(temp
, (strlen(pkg
->priority
)+12), "Priority: %s\n", pkg
->priority
);
834 } else if (strcasecmp(field
, "Provides") == 0) {
838 if (pkg
->provides_count
) {
839 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
840 for ( i
=0; i
< pkg
->provides_count
; i
++ ){
841 if (strstr(pkg
->provides_str
[i
],"opkg_internal_use_only")!=NULL
) {
842 memset (pkg
->provides_str
[i
],'\x0',strlen(pkg
->provides_str
[i
])); /* Pigi clear my trick flag, just in case */
843 flag_provide_false
= 1;
846 if ( !flag_provide_false
|| /* Pigi there is not my trick flag */
847 ((flag_provide_false
) && (pkg
->provides_count
> 1))){ /* Pigi There is, but we also have others Provides */
848 char provstr
[LINE_LEN
];
850 for(i
= 0; i
< pkg
->provides_count
; i
++) {
851 len
= len
+ (strlen(pkg
->provides_str
[i
])+5);
853 temp
= (char *)realloc(temp
,len
);
855 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
859 strncpy(temp
, "Provides:", 12);
860 for(i
= 0; i
< pkg
->provides_count
; i
++) {
861 if (strlen(pkg
->provides_str
[i
])>0){;
862 snprintf(provstr
, LINE_LEN
, "%s %s", i
== 1 ? "" : ",", pkg
->provides_str
[i
]);
863 strncat(temp
, provstr
, strlen(provstr
));
866 strncat(temp
, "\n", strlen("\n"));
870 goto UNKNOWN_FMT_FIELD
;
877 /* Replaces | Recommends*/
878 if (strcasecmp (field
, "Replaces") == 0) {
879 if (pkg
->replaces_count
) {
880 char replstr
[LINE_LEN
];
882 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
883 len
= len
+ (strlen(pkg
->replaces_str
[i
])+5);
885 temp
= (char *)realloc(temp
,len
);
887 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
891 strncpy(temp
, "Replaces:", 12);
892 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
893 snprintf(replstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->replaces_str
[i
]);
894 strncat(temp
, replstr
, strlen(replstr
));
896 strncat(temp
, "\n", strlen("\n"));
898 } else if (strcasecmp (field
, "Recommends") == 0) {
899 if (pkg
->recommends_count
) {
900 char recstr
[LINE_LEN
];
902 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
903 len
= len
+ (strlen( pkg
->recommends_str
[i
])+5);
905 temp
= (char *)realloc(temp
,len
);
907 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
911 strncpy(temp
, "Recommends:", 13);
912 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
913 snprintf(recstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->recommends_str
[i
]);
914 strncat(temp
, recstr
, strlen(recstr
));
916 strncat(temp
, "\n", strlen("\n"));
919 goto UNKNOWN_FMT_FIELD
;
925 /* Section | Size | Source | Status | Suggests */
926 if (strcasecmp(field
, "Section") == 0) {
929 temp
= (char *)realloc(temp
,strlen(pkg
->section
)+11);
931 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
935 snprintf(temp
, (strlen(pkg
->section
)+11), "Section: %s\n", pkg
->section
);
937 } else if (strcasecmp(field
, "Size") == 0) {
940 temp
= (char *)realloc(temp
,strlen(pkg
->size
)+8);
942 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
946 snprintf(temp
, (strlen(pkg
->size
)+8), "Size: %s\n", pkg
->size
);
948 } else if (strcasecmp(field
, "Source") == 0) {
951 temp
= (char *)realloc(temp
,strlen(pkg
->source
)+10);
953 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
957 snprintf(temp
, (strlen(pkg
->source
)+10), "Source: %s\n", pkg
->source
);
959 } else if (strcasecmp(field
, "Status") == 0) {
961 /* Benjamin Pineau note: we should avoid direct usage of
962 * strlen(arg) without keeping "arg" for later free()
964 char *pflag
=pkg_state_flag_to_str(pkg
->state_flag
);
965 char *pstat
=pkg_state_status_to_str(pkg
->state_status
);
966 char *pwant
=pkg_state_want_to_str(pkg
->state_want
);
968 size_t sum_of_sizes
= (size_t) ( strlen(pwant
)+ strlen(pflag
)+ strlen(pstat
) + 12 );
969 temp
= (char *)realloc(temp
,sum_of_sizes
);
971 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
975 snprintf(temp
, sum_of_sizes
, "Status: %s %s %s\n", pwant
, pflag
, pstat
);
978 if(pstat
) /* pfstat can be NULL if ENOMEM */
980 } else if (strcasecmp(field
, "Suggests") == 0) {
981 if (pkg
->suggests_count
) {
983 char sugstr
[LINE_LEN
];
985 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
986 len
= len
+ (strlen(pkg
->suggests_str
[i
])+5);
988 temp
= (char *)realloc(temp
,len
);
990 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
994 strncpy(temp
, "Suggests:", 10);
995 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
996 snprintf(sugstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->suggests_str
[i
]);
997 strncat(temp
, sugstr
, strlen(sugstr
));
999 strncat(temp
, "\n", strlen("\n"));
1002 goto UNKNOWN_FMT_FIELD
;
1008 if (strcasecmp(field
, "Tags") == 0) {
1011 temp
= (char *)realloc(temp
,strlen(pkg
->tags
)+8);
1012 if ( temp
== NULL
){
1013 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1017 snprintf(temp
, (strlen(pkg
->tags
)+8), "Tags: %s\n", pkg
->tags
);
1024 char *version
= pkg_version_str_alloc(pkg
);
1025 temp
= (char *)realloc(temp
,strlen(version
)+14);
1026 if ( temp
== NULL
){
1027 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1031 snprintf(temp
, (strlen(version
)+12), "Version: %s\n", version
);
1036 goto UNKNOWN_FMT_FIELD
;
1039 if ( strlen(temp
)<2 ) {
1045 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__
, field
);
1046 if ( strlen(temp
)<2 ) {
1053 void pkg_print_info(pkg_t
*pkg
, FILE *file
)
1061 buff
= pkg_formatted_info(pkg
);
1064 if (strlen(buff
)>2){
1065 t
= fwrite(buff
, 1, strlen(buff
), file
); //#~rzr:TODO
1070 void pkg_print_status(pkg_t
* pkg
, FILE * file
)
1076 /* XXX: QUESTION: Do we actually want more fields here? The
1077 original idea was to save space by installing only what was
1078 needed for actual computation, (package, version, status,
1079 essential, conffiles). The assumption is that all other fields
1080 can be found in th available file.
1082 But, someone proposed the idea to make it possible to
1083 reconstruct a .opk from an installed package, (ie. for beaming
1084 from one handheld to another). So, maybe we actually want a few
1085 more fields here, (depends, suggests, etc.), so that that would
1086 be guaranteed to work even in the absence of more information
1087 from the available file.
1089 28-MAR-03: kergoth and I discussed this yesterday. We think
1090 the essential info needs to be here for all installed packages
1091 because they may not appear in the Packages files on various
1092 feeds. Furthermore, one should be able to install from URL or
1093 local storage without requiring a Packages file from any feed.
1096 pkg_print_field(pkg
, file
, "Package");
1097 pkg_print_field(pkg
, file
, "Version");
1098 pkg_print_field(pkg
, file
, "Depends");
1099 pkg_print_field(pkg
, file
, "Recommends");
1100 pkg_print_field(pkg
, file
, "Suggests");
1101 pkg_print_field(pkg
, file
, "Provides");
1102 pkg_print_field(pkg
, file
, "Replaces");
1103 pkg_print_field(pkg
, file
, "Conflicts");
1104 pkg_print_field(pkg
, file
, "Status");
1105 pkg_print_field(pkg
, file
, "Essential"); /* @@@@ should be removed in future release. */
1106 pkg_print_field(pkg
, file
, "Architecture");
1107 pkg_print_field(pkg
, file
, "Conffiles");
1108 pkg_print_field(pkg
, file
, "Installed-Time");
1109 pkg_print_field(pkg
, file
, "Auto-Installed");
1113 void pkg_print_field(pkg_t
*pkg
, FILE *file
, const char *field
)
1116 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
1117 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n",
1118 __FUNCTION__
, field
);
1120 buff
= pkg_formatted_field(pkg
, field
);
1121 if (strlen(buff
)>2) {
1122 fprintf(file
, "%s", buff
);
1130 * libdpkg - Debian packaging suite library routines
1131 * vercmp.c - comparison of version numbers
1133 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1135 int pkg_compare_versions(const pkg_t
*pkg
, const pkg_t
*ref_pkg
)
1139 if (pkg
->epoch
> ref_pkg
->epoch
) {
1143 if (pkg
->epoch
< ref_pkg
->epoch
) {
1147 r
= verrevcmp(pkg
->version
, ref_pkg
->version
);
1152 r
= verrevcmp(pkg
->revision
, ref_pkg
->revision
);
1160 /* assume ascii; warning: evaluates x multiple times! */
1161 #define order(x) ((x) == '~' ? -1 \
1162 : isdigit((x)) ? 0 \
1164 : isalpha((x)) ? (x) \
1167 static int verrevcmp(const char *val
, const char *ref
) {
1171 while (*val
|| *ref
) {
1174 while ( (*val
&& !isdigit(*val
)) || (*ref
&& !isdigit(*ref
)) ) {
1175 int vc
= order(*val
), rc
= order(*ref
);
1176 if (vc
!= rc
) return vc
- rc
;
1180 while ( *val
== '0' ) val
++;
1181 while ( *ref
== '0' ) ref
++;
1182 while (isdigit(*val
) && isdigit(*ref
)) {
1183 if (!first_diff
) first_diff
= *val
- *ref
;
1186 if (isdigit(*val
)) return 1;
1187 if (isdigit(*ref
)) return -1;
1188 if (first_diff
) return first_diff
;
1193 int pkg_version_satisfied(pkg_t
*it
, pkg_t
*ref
, const char *op
)
1197 r
= pkg_compare_versions(it
, ref
);
1199 if (strcmp(op
, "<=") == 0 || strcmp(op
, "<") == 0) {
1203 if (strcmp(op
, ">=") == 0 || strcmp(op
, ">") == 0) {
1207 if (strcmp(op
, "<<") == 0) {
1211 if (strcmp(op
, ">>") == 0) {
1215 if (strcmp(op
, "=") == 0) {
1219 fprintf(stderr
, "unknown operator: %s", op
);
1223 int pkg_name_version_and_architecture_compare(const void *p1
, const void *p2
)
1225 const pkg_t
*a
= *(const pkg_t
**) p1
;
1226 const pkg_t
*b
= *(const pkg_t
**) p2
;
1229 if (!a
->name
|| !b
->name
) {
1230 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1231 a
, a
->name
, b
, b
->name
);
1235 namecmp
= strcmp(a
->name
, b
->name
);
1238 vercmp
= pkg_compare_versions(a
, b
);
1241 if (!a
->arch_priority
|| !b
->arch_priority
) {
1242 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1243 a
, a
->arch_priority
, b
, b
->arch_priority
);
1246 if (a
->arch_priority
> b
->arch_priority
)
1248 if (a
->arch_priority
< b
->arch_priority
)
1253 int abstract_pkg_name_compare(const void *p1
, const void *p2
)
1255 const abstract_pkg_t
*a
= *(const abstract_pkg_t
**)p1
;
1256 const abstract_pkg_t
*b
= *(const abstract_pkg_t
**)p2
;
1257 if (!a
->name
|| !b
->name
) {
1258 fprintf(stderr
, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1259 a
, a
->name
, b
, b
->name
);
1262 return strcmp(a
->name
, b
->name
);
1266 char *pkg_version_str_alloc(pkg_t
*pkg
)
1268 char *complete_version
;
1273 sprintf_alloc(&epoch_str
, "%d:", pkg
->epoch
);
1275 epoch_str
= strdup("");
1278 if (pkg
->revision
&& strlen(pkg
->revision
)) {
1279 sprintf_alloc(&revision_str
, "-%s", pkg
->revision
);
1281 revision_str
= strdup("");
1285 sprintf_alloc(&complete_version
, "%s%s%s",
1286 epoch_str
, pkg
->version
, revision_str
);
1291 return complete_version
;
1294 str_list_t
*pkg_get_installed_files(pkg_t
*pkg
)
1297 char *list_file_name
= NULL
;
1298 FILE *list_file
= NULL
;
1300 char *installed_file_name
;
1303 pkg
->installed_files_ref_cnt
++;
1305 if (pkg
->installed_files
) {
1306 return pkg
->installed_files
;
1309 pkg
->installed_files
= str_list_alloc();
1310 if (pkg
->installed_files
== NULL
) {
1311 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1315 /* For uninstalled packages, get the file list firectly from the package.
1316 For installed packages, look at the package.list file in the database.
1318 if (pkg
->state_status
== SS_NOT_INSTALLED
|| pkg
->dest
== NULL
) {
1319 if (pkg
->local_filename
== NULL
) {
1320 return pkg
->installed_files
;
1322 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1323 file. In other words, change deb_extract so that it can
1324 simply return the file list as a char *[] rather than
1325 insisting on writing in to a FILE * as it does now. */
1326 list_file
= tmpfile();
1327 err
= pkg_extract_data_file_names_to_stream(pkg
, list_file
);
1330 fprintf(stderr
, "%s: Error extracting file list from %s: %s\n",
1331 __FUNCTION__
, pkg
->local_filename
, strerror(err
));
1332 return pkg
->installed_files
;
1336 sprintf_alloc(&list_file_name
, "%s/%s.list",
1337 pkg
->dest
->info_dir
, pkg
->name
);
1338 if (! file_exists(list_file_name
)) {
1339 free(list_file_name
);
1340 return pkg
->installed_files
;
1343 list_file
= fopen(list_file_name
, "r");
1344 if (list_file
== NULL
) {
1345 fprintf(stderr
, "WARNING: Cannot open %s: %s\n",
1346 list_file_name
, strerror(errno
));
1347 free(list_file_name
);
1348 return pkg
->installed_files
;
1350 free(list_file_name
);
1353 rootdirlen
= strlen( pkg
->dest
->root_dir
);
1357 line
= file_read_line_alloc(list_file
);
1364 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1365 if( strncmp( pkg
->dest
->root_dir
,
1368 if (*file_name
== '.') {
1371 if (*file_name
== '/') {
1375 /* Freed in pkg_free_installed_files */
1376 sprintf_alloc(&installed_file_name
, "%s%s", pkg
->dest
->root_dir
, file_name
);
1378 // already contains root_dir as header -> ABSOLUTE
1379 sprintf_alloc(&installed_file_name
, "%s", file_name
);
1381 str_list_append(pkg
->installed_files
, installed_file_name
);
1387 return pkg
->installed_files
;
1390 /* XXX: CLEANUP: This function and it's counterpart,
1391 (pkg_get_installed_files), do not match our init/deinit naming
1392 convention. Nor the alloc/free convention. But, then again, neither
1393 of these conventions currrently fit the way these two functions
1395 int pkg_free_installed_files(pkg_t
*pkg
)
1397 str_list_elt_t
*iter
;
1399 pkg
->installed_files_ref_cnt
--;
1400 if (pkg
->installed_files_ref_cnt
> 0) {
1404 if (pkg
->installed_files
) {
1406 for (iter
= pkg
->installed_files
->head
; iter
; iter
= iter
->next
) {
1407 /* malloced in pkg_get_installed_files */
1412 str_list_deinit(pkg
->installed_files
);
1413 free (pkg
->installed_files
);
1416 pkg
->installed_files
= NULL
;
1421 int pkg_remove_installed_files_list(opkg_conf_t
*conf
, pkg_t
*pkg
)
1424 char *list_file_name
;
1426 //I don't think pkg_free_installed_files should be called here. Jamey
1427 //pkg_free_installed_files(pkg);
1429 sprintf_alloc(&list_file_name
, "%s/%s.list",
1430 pkg
->dest
->info_dir
, pkg
->name
);
1431 if (!conf
->noaction
) {
1432 err
= unlink(list_file_name
);
1433 free(list_file_name
);
1442 conffile_t
*pkg_get_conffile(pkg_t
*pkg
, const char *file_name
)
1444 conffile_list_elt_t
*iter
;
1445 conffile_t
*conffile
;
1451 for (iter
= pkg
->conffiles
.head
; iter
; iter
= iter
->next
) {
1452 conffile
= iter
->data
;
1454 if (strcmp(conffile
->name
, file_name
) == 0) {
1462 int pkg_run_script(opkg_conf_t
*conf
, pkg_t
*pkg
,
1463 const char *script
, const char *args
)
1469 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1470 maintainer script within a chroot environment. */
1472 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1473 have scripts in pkg->tmp_unpack_dir. */
1474 if (pkg
->state_status
== SS_INSTALLED
|| pkg
->state_status
== SS_UNPACKED
) {
1475 if (pkg
->dest
== NULL
) {
1476 fprintf(stderr
, "%s: ERROR: installed package %s has a NULL dest\n",
1477 __FUNCTION__
, pkg
->name
);
1480 sprintf_alloc(&path
, "%s/%s.%s", pkg
->dest
->info_dir
, pkg
->name
, script
);
1482 if (pkg
->tmp_unpack_dir
== NULL
) {
1483 fprintf(stderr
, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1484 __FUNCTION__
, pkg
->name
);
1487 sprintf_alloc(&path
, "%s/%s", pkg
->tmp_unpack_dir
, script
);
1490 opkg_message(conf
, OPKG_INFO
, "Running script %s\n", path
);
1491 if (conf
->noaction
) return 0;
1493 /* XXX: CLEANUP: There must be a better way to handle maintainer
1494 scripts when running with offline_root mode and/or a dest other
1495 than '/'. I've been playing around with some clever chroot
1496 tricks and I might come up with something workable. */
1497 if (conf
->offline_root
) {
1498 setenv("OPKG_OFFLINE_ROOT", conf
->offline_root
, 1);
1502 pkg
->dest
? pkg
->dest
->root_dir
: conf
->default_dest
->root_dir
, 1);
1504 if (! file_exists(path
)) {
1509 if (conf
->offline_root
) {
1510 fprintf(stderr
, "(offline root mode: not running %s.%s)\n", pkg
->name
, script
);
1515 sprintf_alloc(&cmd
, "%s %s", path
, args
);
1522 fprintf(stderr
, "%s script returned status %d\n", script
, err
);
1529 char *pkg_state_want_to_str(pkg_state_want_t sw
)
1533 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1534 if (pkg_state_want_map
[i
].value
== sw
) {
1535 return strdup(pkg_state_want_map
[i
].str
);
1539 fprintf(stderr
, "%s: ERROR: Illegal value for state_want: %d\n",
1541 return strdup("<STATE_WANT_UNKNOWN>");
1544 pkg_state_want_t
pkg_state_want_from_str(char *str
)
1548 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1549 if (strcmp(str
, pkg_state_want_map
[i
].str
) == 0) {
1550 return pkg_state_want_map
[i
].value
;
1554 fprintf(stderr
, "%s: ERROR: Illegal value for state_want string: %s\n",
1559 char *pkg_state_flag_to_str(pkg_state_flag_t sf
)
1562 int len
= 3; /* ok\000 is minimum */
1565 /* clear the temporary flags before converting to string */
1566 sf
&= SF_NONVOLATILE_FLAGS
;
1569 return strdup("ok");
1572 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1573 if (sf
& pkg_state_flag_map
[i
].value
) {
1574 len
+= strlen(pkg_state_flag_map
[i
].str
) + 1;
1578 if ( str
== NULL
) {
1579 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1583 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1584 if (sf
& pkg_state_flag_map
[i
].value
) {
1585 strcat(str
, pkg_state_flag_map
[i
].str
);
1590 str
[len
-1] = 0; /* squash last comma */
1595 pkg_state_flag_t
pkg_state_flag_from_str(const char *str
)
1600 if (strcmp(str
, "ok") == 0) {
1603 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1604 const char *sfname
= pkg_state_flag_map
[i
].str
;
1605 int sfname_len
= strlen(sfname
);
1606 if (strncmp(str
, sfname
, sfname_len
) == 0) {
1607 sf
|= pkg_state_flag_map
[i
].value
;
1609 if (str
[0] == ',') {
1620 char *pkg_state_status_to_str(pkg_state_status_t ss
)
1624 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1625 if (pkg_state_status_map
[i
].value
== ss
) {
1626 return strdup(pkg_state_status_map
[i
].str
);
1630 fprintf(stderr
, "%s: ERROR: Illegal value for state_status: %d\n",
1632 return strdup("<STATE_STATUS_UNKNOWN>");
1635 pkg_state_status_t
pkg_state_status_from_str(const char *str
)
1639 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1640 if (strcmp(str
, pkg_state_status_map
[i
].str
) == 0) {
1641 return pkg_state_status_map
[i
].value
;
1645 fprintf(stderr
, "%s: ERROR: Illegal value for state_status string: %s\n",
1647 return SS_NOT_INSTALLED
;
1650 int pkg_arch_supported(opkg_conf_t
*conf
, pkg_t
*pkg
)
1652 nv_pair_list_elt_t
*l
;
1654 if (!pkg
->architecture
)
1657 l
= conf
->arch_list
.head
;
1660 nv_pair_t
*nv
= l
->data
;
1661 if (strcmp(nv
->name
, pkg
->architecture
) == 0) {
1662 opkg_message(conf
, OPKG_DEBUG
, "arch %s (priority %s) supported for pkg %s\n", nv
->name
, nv
->value
, pkg
->name
);
1668 opkg_message(conf
, OPKG_DEBUG
, "arch %s unsupported for pkg %s\n", pkg
->architecture
, pkg
->name
);
1672 int pkg_get_arch_priority(opkg_conf_t
*conf
, const char *archname
)
1674 nv_pair_list_elt_t
*l
;
1676 l
= conf
->arch_list
.head
;
1679 nv_pair_t
*nv
= l
->data
;
1680 if (strcmp(nv
->name
, archname
) == 0) {
1681 int priority
= strtol(nv
->value
, NULL
, 0);
1689 int pkg_info_preinstall_check(opkg_conf_t
*conf
)
1692 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1693 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1694 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1696 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: updating arch priority for each package\n");
1697 pkg_hash_fetch_available(pkg_hash
, available_pkgs
);
1698 /* update arch_priority for each package */
1699 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1700 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1701 int arch_priority
= 1;
1704 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1705 if (pkg
->architecture
)
1706 arch_priority
= pkg_get_arch_priority(conf
, pkg
->architecture
);
1708 opkg_message(conf
, OPKG_ERROR
, "pkg_info_preinstall_check: no architecture for package %s\n", pkg
->name
);
1709 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1710 pkg
->arch_priority
= arch_priority
;
1713 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1714 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1715 if (!pkg
->arch_priority
&& (pkg
->state_flag
|| (pkg
->state_want
!= SW_UNKNOWN
))) {
1716 /* clear flags and want for any uninstallable package */
1717 opkg_message(conf
, OPKG_DEBUG
, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1718 pkg
->name
, pkg
->arch_priority
, pkg
->state_flag
, pkg
->state_want
);
1719 pkg
->state_want
= SW_UNKNOWN
;
1720 pkg
->state_flag
= 0;
1723 pkg_vec_free(available_pkgs
);
1725 /* update the file owner data structure */
1726 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: update file owner list\n");
1727 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1728 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1729 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1730 str_list_t
*installed_files
= pkg_get_installed_files(pkg
); /* this causes installed_files to be cached */
1731 str_list_elt_t
*iter
;
1732 if (installed_files
== NULL
) {
1733 opkg_message(conf
, OPKG_ERROR
, "No installed files for pkg %s\n", pkg
->name
);
1736 for (iter
= installed_files
->head
; iter
; iter
= iter
->next
) {
1737 char *installed_file
= iter
->data
;
1738 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1739 file_hash_set_file_owner(conf
, installed_file
, pkg
);
1741 pkg_free_installed_files(pkg
);
1743 pkg_vec_free(installed_pkgs
);
1748 struct pkg_write_filelist_data
{
1754 void pkg_write_filelist_helper(const char *key
, void *entry_
, void *data_
)
1756 struct pkg_write_filelist_data
*data
= data_
;
1757 pkg_t
*entry
= entry_
;
1758 if (entry
== data
->pkg
) {
1759 fprintf(data
->stream
, "%s\n", key
);
1763 int pkg_write_filelist(opkg_conf_t
*conf
, pkg_t
*pkg
)
1765 struct pkg_write_filelist_data data
;
1766 char *list_file_name
= NULL
;
1770 opkg_message(conf
, OPKG_ERROR
, "Null pkg\n");
1773 opkg_message(conf
, OPKG_INFO
,
1774 " creating %s.list file\n", pkg
->name
);
1775 sprintf_alloc(&list_file_name
, "%s/%s.list", pkg
->dest
->info_dir
, pkg
->name
);
1776 if (!list_file_name
) {
1777 opkg_message(conf
, OPKG_ERROR
, "Failed to alloc list_file_name\n");
1780 opkg_message(conf
, OPKG_INFO
,
1781 " creating %s file for pkg %s\n", list_file_name
, pkg
->name
);
1782 data
.stream
= fopen(list_file_name
, "w");
1784 opkg_message(conf
, OPKG_ERROR
, "Could not open %s for writing: %s\n",
1785 list_file_name
, strerror(errno
));
1790 hash_table_foreach(&conf
->file_hash
, pkg_write_filelist_helper
, &data
);
1791 fclose(data
.stream
);
1792 free(list_file_name
);
1797 int pkg_write_changed_filelists(opkg_conf_t
*conf
)
1799 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1800 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1806 opkg_message(conf
, OPKG_INFO
, "%s: saving changed filelists\n", __FUNCTION__
);
1807 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1808 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1809 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1810 if (pkg
->state_flag
& SF_FILELIST_CHANGED
) {
1811 opkg_message(conf
, OPKG_DEBUG
, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg
->name
, __FUNCTION__
);
1812 err
= pkg_write_filelist(conf
, pkg
);
1814 opkg_message(conf
, OPKG_NOTICE
, "pkg_write_filelist pkg=%s returned %d\n", pkg
->name
, err
);
1817 pkg_vec_free (installed_pkgs
);