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.
27 #include "pkg_parse.h"
28 #include "pkg_extract.h"
29 #include "opkg_message.h"
30 #include "opkg_utils.h"
32 #include "sprintf_alloc.h"
33 #include "file_util.h"
36 #include "opkg_conf.h"
38 typedef struct enum_map enum_map_t
;
45 static const enum_map_t pkg_state_want_map
[] = {
46 { SW_UNKNOWN
, "unknown"},
47 { SW_INSTALL
, "install"},
48 { SW_DEINSTALL
, "deinstall"},
52 static const enum_map_t pkg_state_flag_map
[] = {
54 { SF_REINSTREQ
, "reinstreq"},
56 { SF_REPLACE
, "replace"},
57 { SF_NOPRUNE
, "noprune"},
58 { SF_PREFER
, "prefer"},
59 { SF_OBSOLETE
, "obsolete"},
63 static const enum_map_t pkg_state_status_map
[] = {
64 { SS_NOT_INSTALLED
, "not-installed" },
65 { SS_UNPACKED
, "unpacked" },
66 { SS_HALF_CONFIGURED
, "half-configured" },
67 { SS_INSTALLED
, "installed" },
68 { SS_HALF_INSTALLED
, "half-installed" },
69 { SS_CONFIG_FILES
, "config-files" },
70 { SS_POST_INST_FAILED
, "post-inst-failed" },
71 { SS_REMOVAL_FAILED
, "removal-failed" }
74 static int verrevcmp(const char *val
, const char *ref
);
81 pkg
= calloc(1, sizeof(pkg_t
));
83 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
92 int pkg_init(pkg_t
*pkg
)
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 active_list_init(&pkg
->list
);
118 /* Abhaya: added init for conflicts fields */
119 pkg
->conflicts
= NULL
;
120 pkg
->conflicts_count
= 0;
122 /* added for replaces. Jamey 7/23/2002 */
123 pkg
->replaces
= NULL
;
124 pkg
->replaces_count
= 0;
126 pkg
->pre_depends_count
= 0;
127 pkg
->pre_depends_str
= NULL
;
128 pkg
->provides_count
= 0;
129 pkg
->provides
= NULL
;
130 pkg
->filename
= NULL
;
131 pkg
->local_filename
= NULL
;
132 pkg
->tmp_unpack_dir
= NULL
;
134 #if defined HAVE_SHA256
135 pkg
->sha256sum
= NULL
;
138 pkg
->installed_size
= NULL
;
139 pkg
->priority
= NULL
;
141 conffile_list_init(&pkg
->conffiles
);
142 pkg
->installed_files
= NULL
;
143 pkg
->installed_files_ref_cnt
= 0;
145 pkg
->provided_by_hand
= 0;
150 void compound_depend_deinit (compound_depend_t
*depends
)
153 for (i
= 0; i
< depends
->possibility_count
; i
++)
156 d
= depends
->possibilities
[i
];
160 free (depends
->possibilities
);
163 void pkg_deinit(pkg_t
*pkg
)
172 /* revision shares storage with version, so
174 pkg
->revision
= NULL
;
175 /* owned by opkg_conf_t */
177 /* owned by opkg_conf_t */
179 free(pkg
->architecture
);
180 pkg
->architecture
= NULL
;
181 free(pkg
->maintainer
);
182 pkg
->maintainer
= NULL
;
185 free(pkg
->description
);
186 pkg
->description
= NULL
;
187 pkg
->state_want
= SW_UNKNOWN
;
188 pkg
->state_flag
= SF_OK
;
189 pkg
->state_status
= SS_NOT_INSTALLED
;
191 active_list_clear(&pkg
->list
);
193 free (pkg
->replaces
);
194 pkg
->replaces
= NULL
;
196 for (i
= 0; i
< pkg
->depends_count
; i
++)
197 free (pkg
->depends_str
[i
]);
198 free(pkg
->depends_str
);
199 pkg
->depends_str
= NULL
;
201 for (i
= 0; i
< pkg
->provides_count
; i
++)
202 free (pkg
->provides_str
[i
]);
203 free(pkg
->provides_str
);
204 pkg
->provides_str
= NULL
;
206 for (i
= 0; i
< pkg
->conflicts_count
; i
++)
207 free (pkg
->conflicts_str
[i
]);
208 free(pkg
->conflicts_str
);
209 pkg
->conflicts_str
= NULL
;
211 for (i
= 0; i
< pkg
->replaces_count
; i
++)
212 free (pkg
->replaces_str
[i
]);
213 free(pkg
->replaces_str
);
214 pkg
->replaces_str
= NULL
;
216 for (i
= 0; i
< pkg
->recommends_count
; i
++)
217 free (pkg
->recommends_str
[i
]);
218 free(pkg
->recommends_str
);
219 pkg
->recommends_str
= NULL
;
221 for (i
= 0; i
< pkg
->suggests_count
; i
++)
222 free (pkg
->suggests_str
[i
]);
223 free(pkg
->suggests_str
);
224 pkg
->suggests_str
= NULL
;
228 int count
= pkg
->pre_depends_count
+ pkg
->depends_count
+ pkg
->recommends_count
+ pkg
->suggests_count
;
231 for (x
= 0; x
< count
; x
++)
232 compound_depend_deinit (&pkg
->depends
[x
]);
239 for (x
= 0; x
< pkg
->conflicts_count
; x
++)
240 compound_depend_deinit (&pkg
->conflicts
[x
]);
241 free (pkg
->conflicts
);
244 free (pkg
->provides
);
246 pkg
->pre_depends_count
= 0;
247 free(pkg
->pre_depends_str
);
248 pkg
->pre_depends_str
= NULL
;
249 pkg
->provides_count
= 0;
251 pkg
->filename
= NULL
;
252 free(pkg
->local_filename
);
253 pkg
->local_filename
= NULL
;
254 /* CLEANUP: It'd be nice to pullin the cleanup function from
255 opkg_install.c here. See comment in
256 opkg_install.c:cleanup_temporary_files */
257 free(pkg
->tmp_unpack_dir
);
258 pkg
->tmp_unpack_dir
= NULL
;
261 #if defined HAVE_SHA256
262 free(pkg
->sha256sum
);
263 pkg
->sha256sum
= NULL
;
267 free(pkg
->installed_size
);
268 pkg
->installed_size
= NULL
;
270 pkg
->priority
= NULL
;
273 conffile_list_deinit(&pkg
->conffiles
);
274 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
275 since if they are calling deinit, they should know. Maybe do an
276 assertion here instead? */
277 pkg
->installed_files_ref_cnt
= 1;
278 pkg_free_installed_files(pkg
);
284 int pkg_init_from_file(pkg_t
*pkg
, const char *filename
)
287 char **raw
, **raw_start
;
291 if (err
) { return err
; }
293 pkg
->local_filename
= strdup(filename
);
295 control_file
= tmpfile();
296 err
= pkg_extract_control_file_to_stream(pkg
, control_file
);
297 if (err
) { return err
; }
299 rewind(control_file
);
300 raw
= raw_start
= read_raw_pkgs_from_stream(control_file
);
301 pkg_parse_raw(pkg
, &raw
, NULL
, NULL
);
303 fclose(control_file
);
314 /* Merge any new information in newpkg into oldpkg */
315 /* XXX: CLEANUP: This function shouldn't actually modify anything in
316 newpkg, but should leave it usable. This rework is so that
317 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
319 * uh, i thought that i had originally written this so that it took
320 * two pkgs and returned a new one? we can do that again... -sma
322 int pkg_merge(pkg_t
*oldpkg
, pkg_t
*newpkg
, int set_status
)
324 if (oldpkg
== newpkg
) {
329 oldpkg
->src
= newpkg
->src
;
331 oldpkg
->dest
= newpkg
->dest
;
332 if (!oldpkg
->architecture
)
333 oldpkg
->architecture
= str_dup_safe(newpkg
->architecture
);
334 if (!oldpkg
->arch_priority
)
335 oldpkg
->arch_priority
= newpkg
->arch_priority
;
336 if (!oldpkg
->section
)
337 oldpkg
->section
= str_dup_safe(newpkg
->section
);
338 if(!oldpkg
->maintainer
)
339 oldpkg
->maintainer
= str_dup_safe(newpkg
->maintainer
);
340 if(!oldpkg
->description
)
341 oldpkg
->description
= str_dup_safe(newpkg
->description
);
343 /* merge the state_flags from the new package */
344 oldpkg
->state_want
= newpkg
->state_want
;
345 oldpkg
->state_status
= newpkg
->state_status
;
346 oldpkg
->state_flag
= newpkg
->state_flag
;
348 if (oldpkg
->state_want
== SW_UNKNOWN
)
349 oldpkg
->state_want
= newpkg
->state_want
;
350 if (oldpkg
->state_status
== SS_NOT_INSTALLED
)
351 oldpkg
->state_status
= newpkg
->state_status
;
352 oldpkg
->state_flag
|= newpkg
->state_flag
;
355 if (!oldpkg
->depends_str
&& !oldpkg
->pre_depends_str
&& !oldpkg
->recommends_str
&& !oldpkg
->suggests_str
) {
356 oldpkg
->depends_str
= newpkg
->depends_str
;
357 newpkg
->depends_str
= NULL
;
358 oldpkg
->depends_count
= newpkg
->depends_count
;
359 newpkg
->depends_count
= 0;
361 oldpkg
->depends
= newpkg
->depends
;
362 newpkg
->depends
= NULL
;
364 oldpkg
->pre_depends_str
= newpkg
->pre_depends_str
;
365 newpkg
->pre_depends_str
= NULL
;
366 oldpkg
->pre_depends_count
= newpkg
->pre_depends_count
;
367 newpkg
->pre_depends_count
= 0;
369 oldpkg
->recommends_str
= newpkg
->recommends_str
;
370 newpkg
->recommends_str
= NULL
;
371 oldpkg
->recommends_count
= newpkg
->recommends_count
;
372 newpkg
->recommends_count
= 0;
374 oldpkg
->suggests_str
= newpkg
->suggests_str
;
375 newpkg
->suggests_str
= NULL
;
376 oldpkg
->suggests_count
= newpkg
->suggests_count
;
377 newpkg
->suggests_count
= 0;
380 if (!oldpkg
->provides_str
) {
381 oldpkg
->provides_str
= newpkg
->provides_str
;
382 newpkg
->provides_str
= NULL
;
383 oldpkg
->provides_count
= newpkg
->provides_count
;
384 newpkg
->provides_count
= 0;
386 oldpkg
->provides
= newpkg
->provides
;
387 newpkg
->provides
= NULL
;
390 if (!oldpkg
->conflicts_str
) {
391 oldpkg
->conflicts_str
= newpkg
->conflicts_str
;
392 newpkg
->conflicts_str
= NULL
;
393 oldpkg
->conflicts_count
= newpkg
->conflicts_count
;
394 newpkg
->conflicts_count
= 0;
396 oldpkg
->conflicts
= newpkg
->conflicts
;
397 newpkg
->conflicts
= NULL
;
400 if (!oldpkg
->replaces_str
) {
401 oldpkg
->replaces_str
= newpkg
->replaces_str
;
402 newpkg
->replaces_str
= NULL
;
403 oldpkg
->replaces_count
= newpkg
->replaces_count
;
404 newpkg
->replaces_count
= 0;
406 oldpkg
->replaces
= newpkg
->replaces
;
407 newpkg
->replaces
= NULL
;
410 if (!oldpkg
->filename
)
411 oldpkg
->filename
= str_dup_safe(newpkg
->filename
);
413 fprintf(stdout
, "pkg=%s old local_filename=%s new local_filename=%s\n",
414 oldpkg
->name
, oldpkg
->local_filename
, newpkg
->local_filename
);
415 if (!oldpkg
->local_filename
)
416 oldpkg
->local_filename
= str_dup_safe(newpkg
->local_filename
);
417 if (!oldpkg
->tmp_unpack_dir
)
418 oldpkg
->tmp_unpack_dir
= str_dup_safe(newpkg
->tmp_unpack_dir
);
420 oldpkg
->md5sum
= str_dup_safe(newpkg
->md5sum
);
421 #if defined HAVE_SHA256
422 if (!oldpkg
->sha256sum
)
423 oldpkg
->sha256sum
= str_dup_safe(newpkg
->sha256sum
);
426 oldpkg
->size
= str_dup_safe(newpkg
->size
);
427 if (!oldpkg
->installed_size
)
428 oldpkg
->installed_size
= str_dup_safe(newpkg
->installed_size
);
429 if (!oldpkg
->priority
)
430 oldpkg
->priority
= str_dup_safe(newpkg
->priority
);
432 oldpkg
->source
= str_dup_safe(newpkg
->source
);
433 if (nv_pair_list_empty(&oldpkg
->conffiles
)){
434 list_splice_init(&newpkg
->conffiles
.head
, &oldpkg
->conffiles
.head
);
435 conffile_list_init(&newpkg
->conffiles
);
437 if (!oldpkg
->installed_files
){
438 oldpkg
->installed_files
= newpkg
->installed_files
;
439 oldpkg
->installed_files_ref_cnt
= newpkg
->installed_files_ref_cnt
;
440 newpkg
->installed_files
= NULL
;
442 if (!oldpkg
->essential
)
443 oldpkg
->essential
= newpkg
->essential
;
448 abstract_pkg_t
*abstract_pkg_new(void)
450 abstract_pkg_t
* ab_pkg
;
452 ab_pkg
= calloc(1, sizeof(abstract_pkg_t
));
454 if (ab_pkg
== NULL
) {
455 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
459 if ( abstract_pkg_init(ab_pkg
) < 0 )
465 int abstract_pkg_init(abstract_pkg_t
*ab_pkg
)
467 ab_pkg
->provided_by
= abstract_pkg_vec_alloc();
468 if (ab_pkg
->provided_by
==NULL
){
471 ab_pkg
->dependencies_checked
= 0;
472 ab_pkg
->state_status
= SS_NOT_INSTALLED
;
477 void set_flags_from_control(opkg_conf_t
*conf
, pkg_t
*pkg
){
480 char **raw_start
=NULL
;
482 size_t str_size
= strlen(pkg
->dest
->info_dir
)+strlen(pkg
->name
)+12;
483 temp_str
= (char *) alloca (str_size
);
484 memset(temp_str
, 0 , str_size
);
486 if (temp_str
== NULL
){
487 opkg_message(conf
, OPKG_INFO
, "Out of memory in %s\n", __FUNCTION__
);
490 sprintf( temp_str
,"%s/%s.control",pkg
->dest
->info_dir
,pkg
->name
);
492 raw
= raw_start
= read_raw_pkgs_from_file(temp_str
);
494 opkg_message(conf
, OPKG_ERROR
, "Unable to open the control file in %s\n", __FUNCTION__
);
499 if (!pkg_valorize_other_field(pkg
, &raw
) == 0) {
500 opkg_message(conf
, OPKG_DEBUG
, "unable to read control file for %s. May be empty\n", pkg
->name
);
515 #define CHECK_BUFF_SIZE(buff, line, buf_size, page_size) do { \
516 if (strlen(buff) + strlen(line) >= (buf_size)) { \
517 buf_size += page_size; \
518 buff = realloc(buff, buf_size); \
521 char * pkg_formatted_info(pkg_t
*pkg
)
525 const size_t page_size
= 8192;
526 size_t buff_size
= page_size
;
528 buff
= calloc(1, buff_size
);
530 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
534 line
= pkg_formatted_field(pkg
, "Package");
535 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
536 strncat(buff
,line
, strlen(line
));
539 line
= pkg_formatted_field(pkg
, "Version");
540 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
541 strncat(buff
,line
, strlen(line
));
544 line
= pkg_formatted_field(pkg
, "Depends");
545 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
546 strncat(buff
,line
, strlen(line
));
549 line
= pkg_formatted_field(pkg
, "Recommends");
550 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
551 strncat(buff
,line
, strlen(line
));
554 line
= pkg_formatted_field(pkg
, "Suggests");
555 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
556 strncat(buff
,line
, strlen(line
));
559 line
= pkg_formatted_field(pkg
, "Provides");
560 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
561 strncat(buff
,line
, strlen(line
));
564 line
= pkg_formatted_field(pkg
, "Replaces");
565 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
566 strncat(buff
,line
, strlen(line
));
569 line
= pkg_formatted_field(pkg
, "Conflicts");
570 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
571 strncat(buff
,line
, strlen(line
));
574 line
= pkg_formatted_field(pkg
, "Status");
575 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
576 strncat(buff
,line
, strlen(line
));
579 line
= pkg_formatted_field(pkg
, "Section");
580 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
581 strncat(buff
,line
, strlen(line
));
584 line
= pkg_formatted_field(pkg
, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
585 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
586 strncat(buff
,line
, strlen(line
));
589 line
= pkg_formatted_field(pkg
, "Architecture");
590 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
591 strncat(buff
,line
, strlen(line
));
594 line
= pkg_formatted_field(pkg
, "Maintainer");
595 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
596 strncat(buff
,line
, strlen(line
));
599 line
= pkg_formatted_field(pkg
, "MD5sum");
600 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
601 strncat(buff
,line
, strlen(line
));
604 line
= pkg_formatted_field(pkg
, "Size");
605 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
606 strncat(buff
,line
, strlen(line
));
609 line
= pkg_formatted_field(pkg
, "Filename");
610 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
611 strncat(buff
,line
, strlen(line
));
614 line
= pkg_formatted_field(pkg
, "Conffiles");
615 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
616 strncat(buff
,line
, strlen(line
));
619 line
= pkg_formatted_field(pkg
, "Source");
620 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
621 strncat(buff
,line
, strlen(line
));
624 line
= pkg_formatted_field(pkg
, "Description");
625 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
626 strncat(buff
,line
, strlen(line
));
629 line
= pkg_formatted_field(pkg
, "Installed-Time");
630 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
631 strncat(buff
,line
, strlen(line
));
634 line
= pkg_formatted_field(pkg
, "Tags");
635 CHECK_BUFF_SIZE(buff
, line
, buff_size
, page_size
);
636 strncat(buff
,line
, strlen(line
));
642 char * pkg_formatted_field(pkg_t
*pkg
, const char *field
)
644 static size_t LINE_LEN
= 128;
645 char * temp
= (char *)malloc(1);
647 int flag_provide_false
= 0;
650 Pigi: After some discussion with Florian we decided to modify the full procedure in
651 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
654 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
655 goto UNKNOWN_FMT_FIELD
;
664 if (strcasecmp(field
, "Architecture") == 0) {
666 if (pkg
->architecture
) {
667 temp
= (char *)realloc(temp
,strlen(pkg
->architecture
)+17);
669 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
673 snprintf(temp
, (strlen(pkg
->architecture
)+17), "Architecture: %s\n", pkg
->architecture
);
675 } else if (strcasecmp(field
, "Auto-Installed") == 0) {
676 /* Auto-Installed flag */
677 if (pkg
->auto_installed
) {
678 char * s
= "Auto-Installed: yes\n";
679 temp
= (char *)realloc(temp
, strlen(s
) + 1);
683 goto UNKNOWN_FMT_FIELD
;
688 if (strcasecmp(field
, "Conffiles") == 0) {
690 conffile_list_elt_t
*iter
;
691 char confstr
[LINE_LEN
];
693 if (nv_pair_list_empty(&pkg
->conffiles
)) {
698 for (iter
= nv_pair_list_first(&pkg
->conffiles
); iter
; iter
= nv_pair_list_next(&pkg
->conffiles
, iter
)) {
699 if (((conffile_t
*)iter
->data
)->name
&& ((conffile_t
*)iter
->data
)->value
) {
700 len
= len
+ (strlen(((conffile_t
*)iter
->data
)->name
)+strlen(((conffile_t
*)iter
->data
)->value
)+5);
703 temp
= (char *)realloc(temp
,len
);
705 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
709 strncpy(temp
, "Conffiles:\n", 12);
710 for (iter
= nv_pair_list_first(&pkg
->conffiles
); iter
; iter
= nv_pair_list_next(&pkg
->conffiles
, iter
)) {
711 if (((conffile_t
*)iter
->data
)->name
&& ((conffile_t
*)iter
->data
)->value
) {
712 snprintf(confstr
, LINE_LEN
, "%s %s\n",
713 ((conffile_t
*)iter
->data
)->name
,
714 ((conffile_t
*)iter
->data
)->value
);
715 strncat(temp
, confstr
, strlen(confstr
));
718 } else if (strcasecmp(field
, "Conflicts") == 0) {
721 if (pkg
->conflicts_count
) {
722 char conflictstr
[LINE_LEN
];
724 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
725 len
= len
+ (strlen(pkg
->conflicts_str
[i
])+5);
727 temp
= (char *)realloc(temp
,len
);
729 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
733 strncpy(temp
, "Conflicts:", 11);
734 for(i
= 0; i
< pkg
->conflicts_count
; i
++) {
735 snprintf(conflictstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->conflicts_str
[i
]);
736 strncat(temp
, conflictstr
, strlen(conflictstr
));
738 strncat(temp
, "\n", strlen("\n"));
741 goto UNKNOWN_FMT_FIELD
;
746 if (strcasecmp(field
, "Depends") == 0) {
750 if (pkg
->depends_count
) {
751 char depstr
[LINE_LEN
];
753 for(i
= 0; i
< pkg
->depends_count
; i
++) {
754 len
= len
+ (strlen(pkg
->depends_str
[i
])+4);
756 temp
= (char *)realloc(temp
,len
);
758 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
762 strncpy(temp
, "Depends:", 10);
763 for(i
= 0; i
< pkg
->depends_count
; i
++) {
764 snprintf(depstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->depends_str
[i
]);
765 strncat(temp
, depstr
, strlen(depstr
));
767 strncat(temp
, "\n", strlen("\n"));
769 } else if (strcasecmp(field
, "Description") == 0) {
771 if (pkg
->description
) {
772 temp
= (char *)realloc(temp
,strlen(pkg
->description
)+16);
774 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
778 snprintf(temp
, (strlen(pkg
->description
)+16), "Description: %s\n", pkg
->description
);
781 goto UNKNOWN_FMT_FIELD
;
787 if (pkg
->essential
) {
788 temp
= (char *)realloc(temp
,16);
790 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
794 snprintf(temp
, (16), "Essential: yes\n");
802 temp
= (char *)realloc(temp
,strlen(pkg
->filename
)+12);
804 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
808 snprintf(temp
, (strlen(pkg
->filename
)+12), "Filename: %s\n", pkg
->filename
);
814 if (strcasecmp(field
, "Installed-Size") == 0) {
816 temp
= (char *)realloc(temp
,strlen(pkg
->installed_size
)+17);
818 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
822 snprintf(temp
, (strlen(pkg
->installed_size
)+17), "Installed-Size: %s\n", pkg
->installed_size
);
823 } else if (strcasecmp(field
, "Installed-Time") == 0 && pkg
->installed_time
) {
824 temp
= (char *)realloc(temp
,29);
826 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
830 snprintf(temp
, 29, "Installed-Time: %lu\n", pkg
->installed_time
);
836 /* Maintainer | MD5sum */
837 if (strcasecmp(field
, "Maintainer") == 0) {
839 if (pkg
->maintainer
) {
840 temp
= (char *)realloc(temp
,strlen(pkg
->maintainer
)+14);
842 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
846 snprintf(temp
, (strlen(pkg
->maintainer
)+14), "maintainer: %s\n", pkg
->maintainer
);
848 } else if (strcasecmp(field
, "MD5sum") == 0) {
851 temp
= (char *)realloc(temp
,strlen(pkg
->md5sum
)+11);
853 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
857 snprintf(temp
, (strlen(pkg
->md5sum
)+11), "MD5Sum: %s\n", pkg
->md5sum
);
860 goto UNKNOWN_FMT_FIELD
;
866 if (strcasecmp(field
, "Package") == 0) {
868 temp
= (char *)realloc(temp
,strlen(pkg
->name
)+11);
870 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
874 snprintf(temp
, (strlen(pkg
->name
)+11), "Package: %s\n", pkg
->name
);
875 } else if (strcasecmp(field
, "Priority") == 0) {
877 temp
= (char *)realloc(temp
,strlen(pkg
->priority
)+12);
879 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
883 snprintf(temp
, (strlen(pkg
->priority
)+12), "Priority: %s\n", pkg
->priority
);
884 } else if (strcasecmp(field
, "Provides") == 0) {
888 if (pkg
->provides_count
) {
889 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
890 for ( i
=0; i
< pkg
->provides_count
; i
++ ){
891 if (strstr(pkg
->provides_str
[i
],"opkg_internal_use_only")!=NULL
) {
892 memset (pkg
->provides_str
[i
],'\x0',strlen(pkg
->provides_str
[i
])); /* Pigi clear my trick flag, just in case */
893 flag_provide_false
= 1;
896 if ( !flag_provide_false
|| /* Pigi there is not my trick flag */
897 ((flag_provide_false
) && (pkg
->provides_count
> 1))){ /* Pigi There is, but we also have others Provides */
898 char provstr
[LINE_LEN
];
900 for(i
= 0; i
< pkg
->provides_count
; i
++) {
901 len
= len
+ (strlen(pkg
->provides_str
[i
])+5);
903 temp
= (char *)realloc(temp
,len
);
905 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
909 strncpy(temp
, "Provides:", 12);
910 for(i
= 0; i
< pkg
->provides_count
; i
++) {
911 if (strlen(pkg
->provides_str
[i
])>0){;
912 snprintf(provstr
, LINE_LEN
, "%s %s", i
== 1 ? "" : ",", pkg
->provides_str
[i
]);
913 strncat(temp
, provstr
, strlen(provstr
));
916 strncat(temp
, "\n", strlen("\n"));
920 goto UNKNOWN_FMT_FIELD
;
927 /* Replaces | Recommends*/
928 if (strcasecmp (field
, "Replaces") == 0) {
929 if (pkg
->replaces_count
) {
930 char replstr
[LINE_LEN
];
932 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
933 len
= len
+ (strlen(pkg
->replaces_str
[i
])+5);
935 temp
= (char *)realloc(temp
,len
);
937 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
941 strncpy(temp
, "Replaces:", 12);
942 for (i
= 0; i
< pkg
->replaces_count
; i
++) {
943 snprintf(replstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->replaces_str
[i
]);
944 strncat(temp
, replstr
, strlen(replstr
));
946 strncat(temp
, "\n", strlen("\n"));
948 } else if (strcasecmp (field
, "Recommends") == 0) {
949 if (pkg
->recommends_count
) {
950 char recstr
[LINE_LEN
];
952 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
953 len
= len
+ (strlen( pkg
->recommends_str
[i
])+5);
955 temp
= (char *)realloc(temp
,len
);
957 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
961 strncpy(temp
, "Recommends:", 13);
962 for(i
= 0; i
< pkg
->recommends_count
; i
++) {
963 snprintf(recstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->recommends_str
[i
]);
964 strncat(temp
, recstr
, strlen(recstr
));
966 strncat(temp
, "\n", strlen("\n"));
969 goto UNKNOWN_FMT_FIELD
;
975 /* Section | SHA256sum | Size | Source | Status | Suggests */
976 if (strcasecmp(field
, "Section") == 0) {
979 temp
= (char *)realloc(temp
,strlen(pkg
->section
)+11);
981 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
985 snprintf(temp
, (strlen(pkg
->section
)+11), "Section: %s\n", pkg
->section
);
987 #if defined HAVE_SHA256
988 } else if (strcasecmp(field
, "SHA256sum") == 0) {
990 if (pkg
->sha256sum
) {
991 temp
= (char *)realloc(temp
,strlen(pkg
->sha256sum
)+13);
993 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
997 snprintf(temp
, (strlen(pkg
->sha256sum
)+13), "SHA256sum: %s\n", pkg
->sha256sum
);
1000 } else if (strcasecmp(field
, "Size") == 0) {
1003 temp
= (char *)realloc(temp
,strlen(pkg
->size
)+8);
1004 if ( temp
== NULL
){
1005 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1009 snprintf(temp
, (strlen(pkg
->size
)+8), "Size: %s\n", pkg
->size
);
1011 } else if (strcasecmp(field
, "Source") == 0) {
1014 temp
= (char *)realloc(temp
,strlen(pkg
->source
)+10);
1015 if ( temp
== NULL
){
1016 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1020 snprintf(temp
, (strlen(pkg
->source
)+10), "Source: %s\n", pkg
->source
);
1022 } else if (strcasecmp(field
, "Status") == 0) {
1024 /* Benjamin Pineau note: we should avoid direct usage of
1025 * strlen(arg) without keeping "arg" for later free()
1027 char *pflag
=pkg_state_flag_to_str(pkg
->state_flag
);
1028 char *pstat
=pkg_state_status_to_str(pkg
->state_status
);
1029 char *pwant
=pkg_state_want_to_str(pkg
->state_want
);
1031 size_t sum_of_sizes
= (size_t) ( strlen(pwant
)+ strlen(pflag
)+ strlen(pstat
) + 12 );
1032 temp
= (char *)realloc(temp
,sum_of_sizes
);
1033 if ( temp
== NULL
){
1034 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1038 snprintf(temp
, sum_of_sizes
, "Status: %s %s %s\n", pwant
, pflag
, pstat
);
1041 if(pstat
) /* pfstat can be NULL if ENOMEM */
1043 } else if (strcasecmp(field
, "Suggests") == 0) {
1044 if (pkg
->suggests_count
) {
1046 char sugstr
[LINE_LEN
];
1048 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
1049 len
= len
+ (strlen(pkg
->suggests_str
[i
])+5);
1051 temp
= (char *)realloc(temp
,len
);
1052 if ( temp
== NULL
){
1053 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1057 strncpy(temp
, "Suggests:", 10);
1058 for(i
= 0; i
< pkg
->suggests_count
; i
++) {
1059 snprintf(sugstr
, LINE_LEN
, "%s %s", i
== 0 ? "" : ",", pkg
->suggests_str
[i
]);
1060 strncat(temp
, sugstr
, strlen(sugstr
));
1062 strncat(temp
, "\n", strlen("\n"));
1065 goto UNKNOWN_FMT_FIELD
;
1071 if (strcasecmp(field
, "Tags") == 0) {
1074 temp
= (char *)realloc(temp
,strlen(pkg
->tags
)+8);
1075 if ( temp
== NULL
){
1076 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1080 snprintf(temp
, (strlen(pkg
->tags
)+8), "Tags: %s\n", pkg
->tags
);
1087 char *version
= pkg_version_str_alloc(pkg
);
1088 temp
= (char *)realloc(temp
,strlen(version
)+14);
1089 if ( temp
== NULL
){
1090 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1094 snprintf(temp
, (strlen(version
)+12), "Version: %s\n", version
);
1099 goto UNKNOWN_FMT_FIELD
;
1102 if ( strlen(temp
)<2 ) {
1108 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__
, field
);
1109 if ( strlen(temp
)<2 ) {
1116 void pkg_print_info(pkg_t
*pkg
, FILE *file
)
1124 buff
= pkg_formatted_info(pkg
);
1127 if (strlen(buff
)>2){
1128 t
= fwrite(buff
, 1, strlen(buff
), file
); //#~rzr:TODO
1133 void pkg_print_status(pkg_t
* pkg
, FILE * file
)
1139 /* XXX: QUESTION: Do we actually want more fields here? The
1140 original idea was to save space by installing only what was
1141 needed for actual computation, (package, version, status,
1142 essential, conffiles). The assumption is that all other fields
1143 can be found in th available file.
1145 But, someone proposed the idea to make it possible to
1146 reconstruct a .opk from an installed package, (ie. for beaming
1147 from one handheld to another). So, maybe we actually want a few
1148 more fields here, (depends, suggests, etc.), so that that would
1149 be guaranteed to work even in the absence of more information
1150 from the available file.
1152 28-MAR-03: kergoth and I discussed this yesterday. We think
1153 the essential info needs to be here for all installed packages
1154 because they may not appear in the Packages files on various
1155 feeds. Furthermore, one should be able to install from URL or
1156 local storage without requiring a Packages file from any feed.
1159 pkg_print_field(pkg
, file
, "Package");
1160 pkg_print_field(pkg
, file
, "Version");
1161 pkg_print_field(pkg
, file
, "Depends");
1162 pkg_print_field(pkg
, file
, "Recommends");
1163 pkg_print_field(pkg
, file
, "Suggests");
1164 pkg_print_field(pkg
, file
, "Provides");
1165 pkg_print_field(pkg
, file
, "Replaces");
1166 pkg_print_field(pkg
, file
, "Conflicts");
1167 pkg_print_field(pkg
, file
, "Status");
1168 pkg_print_field(pkg
, file
, "Essential"); /* @@@@ should be removed in future release. */
1169 pkg_print_field(pkg
, file
, "Architecture");
1170 pkg_print_field(pkg
, file
, "Conffiles");
1171 pkg_print_field(pkg
, file
, "Installed-Time");
1172 pkg_print_field(pkg
, file
, "Auto-Installed");
1176 void pkg_print_field(pkg_t
*pkg
, FILE *file
, const char *field
)
1179 if (strlen(field
) < PKG_MINIMUM_FIELD_NAME_LEN
) {
1180 fprintf(stderr
, "%s: ERROR: Unknown field name: %s\n",
1181 __FUNCTION__
, field
);
1183 buff
= pkg_formatted_field(pkg
, field
);
1184 if (strlen(buff
)>2) {
1185 fprintf(file
, "%s", buff
);
1193 * libdpkg - Debian packaging suite library routines
1194 * vercmp.c - comparison of version numbers
1196 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1198 int pkg_compare_versions(const pkg_t
*pkg
, const pkg_t
*ref_pkg
)
1202 if (pkg
->epoch
> ref_pkg
->epoch
) {
1206 if (pkg
->epoch
< ref_pkg
->epoch
) {
1210 r
= verrevcmp(pkg
->version
, ref_pkg
->version
);
1215 r
= verrevcmp(pkg
->revision
, ref_pkg
->revision
);
1223 /* assume ascii; warning: evaluates x multiple times! */
1224 #define order(x) ((x) == '~' ? -1 \
1225 : isdigit((x)) ? 0 \
1227 : isalpha((x)) ? (x) \
1230 static int verrevcmp(const char *val
, const char *ref
) {
1234 while (*val
|| *ref
) {
1237 while ( (*val
&& !isdigit(*val
)) || (*ref
&& !isdigit(*ref
)) ) {
1238 int vc
= order(*val
), rc
= order(*ref
);
1239 if (vc
!= rc
) return vc
- rc
;
1243 while ( *val
== '0' ) val
++;
1244 while ( *ref
== '0' ) ref
++;
1245 while (isdigit(*val
) && isdigit(*ref
)) {
1246 if (!first_diff
) first_diff
= *val
- *ref
;
1249 if (isdigit(*val
)) return 1;
1250 if (isdigit(*ref
)) return -1;
1251 if (first_diff
) return first_diff
;
1256 int pkg_version_satisfied(pkg_t
*it
, pkg_t
*ref
, const char *op
)
1260 r
= pkg_compare_versions(it
, ref
);
1262 if (strcmp(op
, "<=") == 0 || strcmp(op
, "<") == 0) {
1266 if (strcmp(op
, ">=") == 0 || strcmp(op
, ">") == 0) {
1270 if (strcmp(op
, "<<") == 0) {
1274 if (strcmp(op
, ">>") == 0) {
1278 if (strcmp(op
, "=") == 0) {
1282 fprintf(stderr
, "unknown operator: %s", op
);
1286 int pkg_name_version_and_architecture_compare(const void *p1
, const void *p2
)
1288 const pkg_t
*a
= *(const pkg_t
**) p1
;
1289 const pkg_t
*b
= *(const pkg_t
**) p2
;
1292 if (!a
->name
|| !b
->name
) {
1293 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1294 a
, a
->name
, b
, b
->name
);
1298 namecmp
= strcmp(a
->name
, b
->name
);
1301 vercmp
= pkg_compare_versions(a
, b
);
1304 if (!a
->arch_priority
|| !b
->arch_priority
) {
1305 fprintf(stderr
, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1306 a
, a
->arch_priority
, b
, b
->arch_priority
);
1309 if (a
->arch_priority
> b
->arch_priority
)
1311 if (a
->arch_priority
< b
->arch_priority
)
1316 int abstract_pkg_name_compare(const void *p1
, const void *p2
)
1318 const abstract_pkg_t
*a
= *(const abstract_pkg_t
**)p1
;
1319 const abstract_pkg_t
*b
= *(const abstract_pkg_t
**)p2
;
1320 if (!a
->name
|| !b
->name
) {
1321 fprintf(stderr
, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1322 a
, a
->name
, b
, b
->name
);
1325 return strcmp(a
->name
, b
->name
);
1329 char *pkg_version_str_alloc(pkg_t
*pkg
)
1331 char *complete_version
;
1336 sprintf_alloc(&epoch_str
, "%d:", pkg
->epoch
);
1338 epoch_str
= strdup("");
1341 if (pkg
->revision
&& strlen(pkg
->revision
)) {
1342 sprintf_alloc(&revision_str
, "-%s", pkg
->revision
);
1344 revision_str
= strdup("");
1348 sprintf_alloc(&complete_version
, "%s%s%s",
1349 epoch_str
, pkg
->version
, revision_str
);
1354 return complete_version
;
1357 str_list_t
*pkg_get_installed_files(pkg_t
*pkg
)
1360 char *list_file_name
= NULL
;
1361 FILE *list_file
= NULL
;
1363 char *installed_file_name
;
1366 pkg
->installed_files_ref_cnt
++;
1368 if (pkg
->installed_files
) {
1369 return pkg
->installed_files
;
1372 pkg
->installed_files
= str_list_alloc();
1373 if (pkg
->installed_files
== NULL
) {
1374 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1378 /* For uninstalled packages, get the file list directly from the package.
1379 For installed packages, look at the package.list file in the database.
1381 if (pkg
->state_status
== SS_NOT_INSTALLED
|| pkg
->dest
== NULL
) {
1382 if (pkg
->local_filename
== NULL
) {
1383 return pkg
->installed_files
;
1385 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1386 file. In other words, change deb_extract so that it can
1387 simply return the file list as a char *[] rather than
1388 insisting on writing in to a FILE * as it does now. */
1389 list_file
= tmpfile();
1390 err
= pkg_extract_data_file_names_to_stream(pkg
, list_file
);
1393 fprintf(stderr
, "%s: Error extracting file list from %s: %s\n",
1394 __FUNCTION__
, pkg
->local_filename
, strerror(err
));
1395 return pkg
->installed_files
;
1399 sprintf_alloc(&list_file_name
, "%s/%s.list",
1400 pkg
->dest
->info_dir
, pkg
->name
);
1401 if (! file_exists(list_file_name
)) {
1402 free(list_file_name
);
1403 return pkg
->installed_files
;
1406 list_file
= fopen(list_file_name
, "r");
1407 if (list_file
== NULL
) {
1408 fprintf(stderr
, "WARNING: Cannot open %s: %s\n",
1409 list_file_name
, strerror(errno
));
1410 free(list_file_name
);
1411 return pkg
->installed_files
;
1413 free(list_file_name
);
1416 rootdirlen
= strlen( pkg
->dest
->root_dir
);
1420 line
= file_read_line_alloc(list_file
);
1427 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1428 if( strncmp( pkg
->dest
->root_dir
,
1431 if (*file_name
== '.') {
1434 if (*file_name
== '/') {
1438 /* Freed in pkg_free_installed_files */
1439 sprintf_alloc(&installed_file_name
, "%s%s", pkg
->dest
->root_dir
, file_name
);
1441 // already contains root_dir as header -> ABSOLUTE
1442 sprintf_alloc(&installed_file_name
, "%s", file_name
);
1444 str_list_append(pkg
->installed_files
, installed_file_name
);
1445 free(installed_file_name
);
1451 return pkg
->installed_files
;
1454 /* XXX: CLEANUP: This function and it's counterpart,
1455 (pkg_get_installed_files), do not match our init/deinit naming
1456 convention. Nor the alloc/free convention. But, then again, neither
1457 of these conventions currrently fit the way these two functions
1459 int pkg_free_installed_files(pkg_t
*pkg
)
1461 pkg
->installed_files_ref_cnt
--;
1463 if (pkg
->installed_files_ref_cnt
> 0)
1466 if (pkg
->installed_files
) {
1467 str_list_purge(pkg
->installed_files
);
1470 pkg
->installed_files
= NULL
;
1475 int pkg_remove_installed_files_list(opkg_conf_t
*conf
, pkg_t
*pkg
)
1478 char *list_file_name
;
1480 //I don't think pkg_free_installed_files should be called here. Jamey
1481 //pkg_free_installed_files(pkg);
1483 sprintf_alloc(&list_file_name
, "%s/%s.list",
1484 pkg
->dest
->info_dir
, pkg
->name
);
1485 if (!conf
->noaction
) {
1486 err
= unlink(list_file_name
);
1487 free(list_file_name
);
1496 conffile_t
*pkg_get_conffile(pkg_t
*pkg
, const char *file_name
)
1498 conffile_list_elt_t
*iter
;
1499 conffile_t
*conffile
;
1505 for (iter
= nv_pair_list_first(&pkg
->conffiles
); iter
; iter
= nv_pair_list_next(&pkg
->conffiles
, iter
)) {
1506 conffile
= (conffile_t
*)iter
->data
;
1508 if (strcmp(conffile
->name
, file_name
) == 0) {
1516 int pkg_run_script(opkg_conf_t
*conf
, pkg_t
*pkg
,
1517 const char *script
, const char *args
)
1523 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1524 maintainer script within a chroot environment. */
1526 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1527 have scripts in pkg->tmp_unpack_dir. */
1528 if (pkg
->state_status
== SS_INSTALLED
|| pkg
->state_status
== SS_UNPACKED
) {
1529 if (pkg
->dest
== NULL
) {
1530 fprintf(stderr
, "%s: ERROR: installed package %s has a NULL dest\n",
1531 __FUNCTION__
, pkg
->name
);
1534 sprintf_alloc(&path
, "%s/%s.%s", pkg
->dest
->info_dir
, pkg
->name
, script
);
1536 if (pkg
->tmp_unpack_dir
== NULL
) {
1537 fprintf(stderr
, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1538 __FUNCTION__
, pkg
->name
);
1541 sprintf_alloc(&path
, "%s/%s", pkg
->tmp_unpack_dir
, script
);
1544 opkg_message(conf
, OPKG_INFO
, "Running script %s\n", path
);
1545 if (conf
->noaction
) return 0;
1547 /* XXX: CLEANUP: There must be a better way to handle maintainer
1548 scripts when running with offline_root mode and/or a dest other
1549 than '/'. I've been playing around with some clever chroot
1550 tricks and I might come up with something workable. */
1552 * Attempt to provide a restricted environment for offline operation
1553 * Need the following set as a minimum:
1554 * OPKG_OFFLINE_ROOT = absolute path to root dir
1555 * D = absolute path to root dir (for OE generated postinst)
1556 * PATH = something safe (a restricted set of utilities)
1559 bool AllowOfflineMode
= false;
1560 if (conf
->offline_root
) {
1561 setenv("OPKG_OFFLINE_ROOT", conf
->offline_root
, 1);
1562 setenv("D", conf
->offline_root
, 1);
1563 if (NULL
== conf
->offline_root_path
|| '\0' == conf
->offline_root_path
[0]) {
1564 setenv("PATH", "/dev/null", 1);
1566 setenv("PATH", conf
->offline_root_path
, 1);
1567 AllowOfflineMode
= true;
1572 pkg
->dest
? pkg
->dest
->root_dir
: conf
->default_dest
->root_dir
, 1);
1574 if (! file_exists(path
)) {
1579 if (conf
->offline_root
&& !AllowOfflineMode
) {
1580 fprintf(stderr
, "(offline root mode: not running %s.%s)\n", pkg
->name
, script
);
1585 sprintf_alloc(&cmd
, "%s %s", path
, args
);
1592 fprintf(stderr
, "%s script returned status %d\n", script
, err
);
1599 char *pkg_state_want_to_str(pkg_state_want_t sw
)
1603 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1604 if (pkg_state_want_map
[i
].value
== sw
) {
1605 return strdup(pkg_state_want_map
[i
].str
);
1609 fprintf(stderr
, "%s: ERROR: Illegal value for state_want: %d\n",
1611 return strdup("<STATE_WANT_UNKNOWN>");
1614 pkg_state_want_t
pkg_state_want_from_str(char *str
)
1618 for (i
=0; i
< ARRAY_SIZE(pkg_state_want_map
); i
++) {
1619 if (strcmp(str
, pkg_state_want_map
[i
].str
) == 0) {
1620 return pkg_state_want_map
[i
].value
;
1624 fprintf(stderr
, "%s: ERROR: Illegal value for state_want string: %s\n",
1629 char *pkg_state_flag_to_str(pkg_state_flag_t sf
)
1632 int len
= 3; /* ok\000 is minimum */
1635 /* clear the temporary flags before converting to string */
1636 sf
&= SF_NONVOLATILE_FLAGS
;
1639 return strdup("ok");
1642 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1643 if (sf
& pkg_state_flag_map
[i
].value
) {
1644 len
+= strlen(pkg_state_flag_map
[i
].str
) + 1;
1648 if ( str
== NULL
) {
1649 fprintf(stderr
, "%s: out of memory\n", __FUNCTION__
);
1653 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1654 if (sf
& pkg_state_flag_map
[i
].value
) {
1655 strcat(str
, pkg_state_flag_map
[i
].str
);
1660 str
[len
-1] = 0; /* squash last comma */
1665 pkg_state_flag_t
pkg_state_flag_from_str(const char *str
)
1670 if (strcmp(str
, "ok") == 0) {
1673 for (i
=0; i
< ARRAY_SIZE(pkg_state_flag_map
); i
++) {
1674 const char *sfname
= pkg_state_flag_map
[i
].str
;
1675 int sfname_len
= strlen(sfname
);
1676 if (strncmp(str
, sfname
, sfname_len
) == 0) {
1677 sf
|= pkg_state_flag_map
[i
].value
;
1679 if (str
[0] == ',') {
1690 char *pkg_state_status_to_str(pkg_state_status_t ss
)
1694 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1695 if (pkg_state_status_map
[i
].value
== ss
) {
1696 return strdup(pkg_state_status_map
[i
].str
);
1700 fprintf(stderr
, "%s: ERROR: Illegal value for state_status: %d\n",
1702 return strdup("<STATE_STATUS_UNKNOWN>");
1705 pkg_state_status_t
pkg_state_status_from_str(const char *str
)
1709 for (i
=0; i
< ARRAY_SIZE(pkg_state_status_map
); i
++) {
1710 if (strcmp(str
, pkg_state_status_map
[i
].str
) == 0) {
1711 return pkg_state_status_map
[i
].value
;
1715 fprintf(stderr
, "%s: ERROR: Illegal value for state_status string: %s\n",
1717 return SS_NOT_INSTALLED
;
1720 int pkg_arch_supported(opkg_conf_t
*conf
, pkg_t
*pkg
)
1722 nv_pair_list_elt_t
*l
;
1724 if (!pkg
->architecture
)
1727 list_for_each_entry(l
, &conf
->arch_list
.head
, node
) {
1728 nv_pair_t
*nv
= (nv_pair_t
*)l
->data
;
1729 if (strcmp(nv
->name
, pkg
->architecture
) == 0) {
1730 opkg_message(conf
, OPKG_DEBUG
, "arch %s (priority %s) supported for pkg %s\n", nv
->name
, nv
->value
, pkg
->name
);
1735 opkg_message(conf
, OPKG_DEBUG
, "arch %s unsupported for pkg %s\n", pkg
->architecture
, pkg
->name
);
1739 int pkg_get_arch_priority(opkg_conf_t
*conf
, const char *archname
)
1741 nv_pair_list_elt_t
*l
;
1743 list_for_each_entry(l
, &conf
->arch_list
.head
, node
) {
1744 nv_pair_t
*nv
= (nv_pair_t
*)l
->data
;
1745 if (strcmp(nv
->name
, archname
) == 0) {
1746 int priority
= strtol(nv
->value
, NULL
, 0);
1753 int pkg_info_preinstall_check(opkg_conf_t
*conf
)
1756 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1757 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1758 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1760 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: updating arch priority for each package\n");
1761 pkg_hash_fetch_available(pkg_hash
, available_pkgs
);
1762 /* update arch_priority for each package */
1763 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1764 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1765 int arch_priority
= 1;
1768 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1769 if (pkg
->architecture
)
1770 arch_priority
= pkg_get_arch_priority(conf
, pkg
->architecture
);
1772 opkg_message(conf
, OPKG_ERROR
, "pkg_info_preinstall_check: no architecture for package %s\n", pkg
->name
);
1773 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1774 pkg
->arch_priority
= arch_priority
;
1777 for (i
= 0; i
< available_pkgs
->len
; i
++) {
1778 pkg_t
*pkg
= available_pkgs
->pkgs
[i
];
1779 if (!pkg
->arch_priority
&& (pkg
->state_flag
|| (pkg
->state_want
!= SW_UNKNOWN
))) {
1780 /* clear flags and want for any uninstallable package */
1781 opkg_message(conf
, OPKG_DEBUG
, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1782 pkg
->name
, pkg
->arch_priority
, pkg
->state_flag
, pkg
->state_want
);
1783 pkg
->state_want
= SW_UNKNOWN
;
1784 pkg
->state_flag
= 0;
1787 pkg_vec_free(available_pkgs
);
1789 /* update the file owner data structure */
1790 opkg_message(conf
, OPKG_INFO
, "pkg_info_preinstall_check: update file owner list\n");
1791 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1792 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1793 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1794 str_list_t
*installed_files
= pkg_get_installed_files(pkg
); /* this causes installed_files to be cached */
1795 str_list_elt_t
*iter
, *niter
;
1796 if (installed_files
== NULL
) {
1797 opkg_message(conf
, OPKG_ERROR
, "No installed files for pkg %s\n", pkg
->name
);
1800 for (iter
= str_list_first(installed_files
), niter
= str_list_next(installed_files
, iter
);
1802 iter
= niter
, niter
= str_list_next(installed_files
, iter
)) {
1803 char *installed_file
= (char *) iter
->data
;
1804 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1805 file_hash_set_file_owner(conf
, installed_file
, pkg
);
1807 pkg_free_installed_files(pkg
);
1809 pkg_vec_free(installed_pkgs
);
1814 struct pkg_write_filelist_data
{
1820 void pkg_write_filelist_helper(const char *key
, void *entry_
, void *data_
)
1822 struct pkg_write_filelist_data
*data
= data_
;
1823 pkg_t
*entry
= entry_
;
1824 if (entry
== data
->pkg
) {
1825 fprintf(data
->stream
, "%s\n", key
);
1829 int pkg_write_filelist(opkg_conf_t
*conf
, pkg_t
*pkg
)
1831 struct pkg_write_filelist_data data
;
1832 char *list_file_name
= NULL
;
1836 opkg_message(conf
, OPKG_ERROR
, "Null pkg\n");
1839 opkg_message(conf
, OPKG_INFO
,
1840 " creating %s.list file\n", pkg
->name
);
1841 sprintf_alloc(&list_file_name
, "%s/%s.list", pkg
->dest
->info_dir
, pkg
->name
);
1842 if (!list_file_name
) {
1843 opkg_message(conf
, OPKG_ERROR
, "Failed to alloc list_file_name\n");
1846 opkg_message(conf
, OPKG_INFO
,
1847 " creating %s file for pkg %s\n", list_file_name
, pkg
->name
);
1848 data
.stream
= fopen(list_file_name
, "w");
1850 opkg_message(conf
, OPKG_ERROR
, "Could not open %s for writing: %s\n",
1851 list_file_name
, strerror(errno
));
1856 hash_table_foreach(&conf
->file_hash
, pkg_write_filelist_helper
, &data
);
1857 fclose(data
.stream
);
1858 free(list_file_name
);
1860 pkg
->state_flag
&= ~SF_FILELIST_CHANGED
;
1865 int pkg_write_changed_filelists(opkg_conf_t
*conf
)
1867 pkg_vec_t
*installed_pkgs
= pkg_vec_alloc();
1868 hash_table_t
*pkg_hash
= &conf
->pkg_hash
;
1874 opkg_message(conf
, OPKG_INFO
, "%s: saving changed filelists\n", __FUNCTION__
);
1875 pkg_hash_fetch_all_installed(pkg_hash
, installed_pkgs
);
1876 for (i
= 0; i
< installed_pkgs
->len
; i
++) {
1877 pkg_t
*pkg
= installed_pkgs
->pkgs
[i
];
1878 if (pkg
->state_flag
& SF_FILELIST_CHANGED
) {
1879 opkg_message(conf
, OPKG_DEBUG
, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg
->name
, __FUNCTION__
);
1880 err
= pkg_write_filelist(conf
, pkg
);
1882 opkg_message(conf
, OPKG_NOTICE
, "pkg_write_filelist pkg=%s returned %d\n", pkg
->name
, err
);
1885 pkg_vec_free (installed_pkgs
);