s/strdup/xstrdup/ - check memory allocations for failure.
[project/opkg-lede.git] / libopkg / pkg.c
1 /* pkg.c - the opkg package management system
2
3 Carl D. Worth
4
5 Copyright (C) 2001 University of Southern California
6
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.
11
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.
16 */
17
18 #include "includes.h"
19 #include <ctype.h>
20 #include <alloca.h>
21 #include <string.h>
22 #include <stdbool.h>
23 #include <errno.h>
24
25 #include "pkg.h"
26
27 #include "pkg_parse.h"
28 #include "pkg_extract.h"
29 #include "opkg_message.h"
30 #include "opkg_utils.h"
31
32 #include "libbb/libbb.h"
33 #include "sprintf_alloc.h"
34 #include "file_util.h"
35 #include "str_util.h"
36 #include "xsystem.h"
37 #include "opkg_conf.h"
38
39 typedef struct enum_map enum_map_t;
40 struct enum_map
41 {
42 int value;
43 char *str;
44 };
45
46 static const enum_map_t pkg_state_want_map[] = {
47 { SW_UNKNOWN, "unknown"},
48 { SW_INSTALL, "install"},
49 { SW_DEINSTALL, "deinstall"},
50 { SW_PURGE, "purge"}
51 };
52
53 static const enum_map_t pkg_state_flag_map[] = {
54 { SF_OK, "ok"},
55 { SF_REINSTREQ, "reinstreq"},
56 { SF_HOLD, "hold"},
57 { SF_REPLACE, "replace"},
58 { SF_NOPRUNE, "noprune"},
59 { SF_PREFER, "prefer"},
60 { SF_OBSOLETE, "obsolete"},
61 { SF_USER, "user"},
62 };
63
64 static const enum_map_t pkg_state_status_map[] = {
65 { SS_NOT_INSTALLED, "not-installed" },
66 { SS_UNPACKED, "unpacked" },
67 { SS_HALF_CONFIGURED, "half-configured" },
68 { SS_INSTALLED, "installed" },
69 { SS_HALF_INSTALLED, "half-installed" },
70 { SS_CONFIG_FILES, "config-files" },
71 { SS_POST_INST_FAILED, "post-inst-failed" },
72 { SS_REMOVAL_FAILED, "removal-failed" }
73 };
74
75 static int verrevcmp(const char *val, const char *ref);
76
77
78 pkg_t *pkg_new(void)
79 {
80 pkg_t *pkg;
81
82 pkg = calloc(1, sizeof(pkg_t));
83 if (pkg == NULL) {
84 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
85 return NULL;
86 }
87
88 pkg_init(pkg);
89
90 return pkg;
91 }
92
93 int pkg_init(pkg_t *pkg)
94 {
95 pkg->name = NULL;
96 pkg->epoch = 0;
97 pkg->version = NULL;
98 pkg->revision = NULL;
99 pkg->dest = NULL;
100 pkg->src = NULL;
101 pkg->architecture = NULL;
102 pkg->maintainer = NULL;
103 pkg->section = NULL;
104 pkg->description = NULL;
105 pkg->state_want = SW_UNKNOWN;
106 pkg->state_flag = SF_OK;
107 pkg->state_status = SS_NOT_INSTALLED;
108 pkg->depends_str = NULL;
109 pkg->provides_str = NULL;
110 pkg->depends_count = 0;
111 pkg->depends = NULL;
112 pkg->suggests_str = NULL;
113 pkg->recommends_str = NULL;
114 pkg->suggests_count = 0;
115 pkg->recommends_count = 0;
116
117 active_list_init(&pkg->list);
118
119 /* Abhaya: added init for conflicts fields */
120 pkg->conflicts = NULL;
121 pkg->conflicts_count = 0;
122
123 /* added for replaces. Jamey 7/23/2002 */
124 pkg->replaces = NULL;
125 pkg->replaces_count = 0;
126
127 pkg->pre_depends_count = 0;
128 pkg->pre_depends_str = NULL;
129 pkg->provides_count = 0;
130 pkg->provides = NULL;
131 pkg->filename = NULL;
132 pkg->local_filename = NULL;
133 pkg->tmp_unpack_dir = NULL;
134 pkg->md5sum = NULL;
135 #if defined HAVE_SHA256
136 pkg->sha256sum = NULL;
137 #endif
138 pkg->size = NULL;
139 pkg->installed_size = NULL;
140 pkg->priority = NULL;
141 pkg->source = NULL;
142 conffile_list_init(&pkg->conffiles);
143 pkg->installed_files = NULL;
144 pkg->installed_files_ref_cnt = 0;
145 pkg->essential = 0;
146 pkg->provided_by_hand = 0;
147
148 return 0;
149 }
150
151 void compound_depend_deinit (compound_depend_t *depends)
152 {
153 int i;
154 for (i = 0; i < depends->possibility_count; i++)
155 {
156 depend_t *d;
157 d = depends->possibilities[i];
158 free (d->version);
159 free (d);
160 }
161 free (depends->possibilities);
162 }
163
164 void pkg_deinit(pkg_t *pkg)
165 {
166 int i;
167
168 free(pkg->name);
169 pkg->name = NULL;
170 pkg->epoch = 0;
171 free(pkg->version);
172 pkg->version = NULL;
173 /* revision shares storage with version, so
174 don't free */
175 pkg->revision = NULL;
176 /* owned by opkg_conf_t */
177 pkg->dest = NULL;
178 /* owned by opkg_conf_t */
179 pkg->src = NULL;
180 free(pkg->architecture);
181 pkg->architecture = NULL;
182 free(pkg->maintainer);
183 pkg->maintainer = NULL;
184 free(pkg->section);
185 pkg->section = NULL;
186 free(pkg->description);
187 pkg->description = NULL;
188 pkg->state_want = SW_UNKNOWN;
189 pkg->state_flag = SF_OK;
190 pkg->state_status = SS_NOT_INSTALLED;
191
192 active_list_clear(&pkg->list);
193
194 free (pkg->replaces);
195 pkg->replaces = NULL;
196
197 for (i = 0; i < pkg->depends_count; i++)
198 free (pkg->depends_str[i]);
199 free(pkg->depends_str);
200 pkg->depends_str = NULL;
201
202 for (i = 0; i < pkg->provides_count; i++)
203 free (pkg->provides_str[i]);
204 free(pkg->provides_str);
205 pkg->provides_str = NULL;
206
207 for (i = 0; i < pkg->conflicts_count; i++)
208 free (pkg->conflicts_str[i]);
209 free(pkg->conflicts_str);
210 pkg->conflicts_str = NULL;
211
212 for (i = 0; i < pkg->replaces_count; i++)
213 free (pkg->replaces_str[i]);
214 free(pkg->replaces_str);
215 pkg->replaces_str = NULL;
216
217 for (i = 0; i < pkg->recommends_count; i++)
218 free (pkg->recommends_str[i]);
219 free(pkg->recommends_str);
220 pkg->recommends_str = NULL;
221
222 for (i = 0; i < pkg->suggests_count; i++)
223 free (pkg->suggests_str[i]);
224 free(pkg->suggests_str);
225 pkg->suggests_str = NULL;
226
227 if (pkg->depends)
228 {
229 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
230 int x;
231
232 for (x = 0; x < count; x++)
233 compound_depend_deinit (&pkg->depends[x]);
234 free (pkg->depends);
235 }
236
237 if (pkg->conflicts)
238 {
239 int x;
240 for (x = 0; x < pkg->conflicts_count; x++)
241 compound_depend_deinit (&pkg->conflicts[x]);
242 free (pkg->conflicts);
243 }
244
245 free (pkg->provides);
246
247 pkg->pre_depends_count = 0;
248 free(pkg->pre_depends_str);
249 pkg->pre_depends_str = NULL;
250 pkg->provides_count = 0;
251 free(pkg->filename);
252 pkg->filename = NULL;
253 free(pkg->local_filename);
254 pkg->local_filename = NULL;
255 /* CLEANUP: It'd be nice to pullin the cleanup function from
256 opkg_install.c here. See comment in
257 opkg_install.c:cleanup_temporary_files */
258 free(pkg->tmp_unpack_dir);
259 pkg->tmp_unpack_dir = NULL;
260 free(pkg->md5sum);
261 pkg->md5sum = NULL;
262 #if defined HAVE_SHA256
263 free(pkg->sha256sum);
264 pkg->sha256sum = NULL;
265 #endif
266 free(pkg->size);
267 pkg->size = NULL;
268 free(pkg->installed_size);
269 pkg->installed_size = NULL;
270 free(pkg->priority);
271 pkg->priority = NULL;
272 free(pkg->source);
273 pkg->source = NULL;
274 conffile_list_deinit(&pkg->conffiles);
275 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
276 since if they are calling deinit, they should know. Maybe do an
277 assertion here instead? */
278 pkg->installed_files_ref_cnt = 1;
279 pkg_free_installed_files(pkg);
280 pkg->essential = 0;
281 free (pkg->tags);
282 pkg->tags = NULL;
283 }
284
285 int pkg_init_from_file(pkg_t *pkg, const char *filename)
286 {
287 int err;
288 char **raw, **raw_start;
289 FILE *control_file;
290
291 err = pkg_init(pkg);
292 if (err) { return err; }
293
294 pkg->local_filename = xstrdup(filename);
295
296 control_file = tmpfile();
297 err = pkg_extract_control_file_to_stream(pkg, control_file);
298 if (err) { return err; }
299
300 rewind(control_file);
301 raw = raw_start = read_raw_pkgs_from_stream(control_file);
302 pkg_parse_raw(pkg, &raw, NULL, NULL);
303
304 fclose(control_file);
305
306 raw = raw_start;
307 while (*raw) {
308 free(*raw++);
309 }
310 free(raw_start);
311
312 return 0;
313 }
314
315 /* Merge any new information in newpkg into oldpkg */
316 /* XXX: CLEANUP: This function shouldn't actually modify anything in
317 newpkg, but should leave it usable. This rework is so that
318 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
319 /*
320 * uh, i thought that i had originally written this so that it took
321 * two pkgs and returned a new one? we can do that again... -sma
322 */
323 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
324 {
325 if (oldpkg == newpkg) {
326 return 0;
327 }
328
329 if (!oldpkg->src)
330 oldpkg->src = newpkg->src;
331 if (!oldpkg->dest)
332 oldpkg->dest = newpkg->dest;
333 if (!oldpkg->architecture)
334 oldpkg->architecture = xstrdup(newpkg->architecture);
335 if (!oldpkg->arch_priority)
336 oldpkg->arch_priority = newpkg->arch_priority;
337 if (!oldpkg->section)
338 oldpkg->section = xstrdup(newpkg->section);
339 if(!oldpkg->maintainer)
340 oldpkg->maintainer = xstrdup(newpkg->maintainer);
341 if(!oldpkg->description)
342 oldpkg->description = xstrdup(newpkg->description);
343 if (set_status) {
344 /* merge the state_flags from the new package */
345 oldpkg->state_want = newpkg->state_want;
346 oldpkg->state_status = newpkg->state_status;
347 oldpkg->state_flag = newpkg->state_flag;
348 } else {
349 if (oldpkg->state_want == SW_UNKNOWN)
350 oldpkg->state_want = newpkg->state_want;
351 if (oldpkg->state_status == SS_NOT_INSTALLED)
352 oldpkg->state_status = newpkg->state_status;
353 oldpkg->state_flag |= newpkg->state_flag;
354 }
355
356 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
357 oldpkg->depends_str = newpkg->depends_str;
358 newpkg->depends_str = NULL;
359 oldpkg->depends_count = newpkg->depends_count;
360 newpkg->depends_count = 0;
361
362 oldpkg->depends = newpkg->depends;
363 newpkg->depends = NULL;
364
365 oldpkg->pre_depends_str = newpkg->pre_depends_str;
366 newpkg->pre_depends_str = NULL;
367 oldpkg->pre_depends_count = newpkg->pre_depends_count;
368 newpkg->pre_depends_count = 0;
369
370 oldpkg->recommends_str = newpkg->recommends_str;
371 newpkg->recommends_str = NULL;
372 oldpkg->recommends_count = newpkg->recommends_count;
373 newpkg->recommends_count = 0;
374
375 oldpkg->suggests_str = newpkg->suggests_str;
376 newpkg->suggests_str = NULL;
377 oldpkg->suggests_count = newpkg->suggests_count;
378 newpkg->suggests_count = 0;
379 }
380
381 if (!oldpkg->provides_str) {
382 oldpkg->provides_str = newpkg->provides_str;
383 newpkg->provides_str = NULL;
384 oldpkg->provides_count = newpkg->provides_count;
385 newpkg->provides_count = 0;
386
387 oldpkg->provides = newpkg->provides;
388 newpkg->provides = NULL;
389 }
390
391 if (!oldpkg->conflicts_str) {
392 oldpkg->conflicts_str = newpkg->conflicts_str;
393 newpkg->conflicts_str = NULL;
394 oldpkg->conflicts_count = newpkg->conflicts_count;
395 newpkg->conflicts_count = 0;
396
397 oldpkg->conflicts = newpkg->conflicts;
398 newpkg->conflicts = NULL;
399 }
400
401 if (!oldpkg->replaces_str) {
402 oldpkg->replaces_str = newpkg->replaces_str;
403 newpkg->replaces_str = NULL;
404 oldpkg->replaces_count = newpkg->replaces_count;
405 newpkg->replaces_count = 0;
406
407 oldpkg->replaces = newpkg->replaces;
408 newpkg->replaces = NULL;
409 }
410
411 if (!oldpkg->filename)
412 oldpkg->filename = xstrdup(newpkg->filename);
413 if (0)
414 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
415 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
416 if (!oldpkg->local_filename)
417 oldpkg->local_filename = xstrdup(newpkg->local_filename);
418 if (!oldpkg->tmp_unpack_dir)
419 oldpkg->tmp_unpack_dir = xstrdup(newpkg->tmp_unpack_dir);
420 if (!oldpkg->md5sum)
421 oldpkg->md5sum = xstrdup(newpkg->md5sum);
422 #if defined HAVE_SHA256
423 if (!oldpkg->sha256sum)
424 oldpkg->sha256sum = xstrdup(newpkg->sha256sum);
425 #endif
426 if (!oldpkg->size)
427 oldpkg->size = xstrdup(newpkg->size);
428 if (!oldpkg->installed_size)
429 oldpkg->installed_size = xstrdup(newpkg->installed_size);
430 if (!oldpkg->priority)
431 oldpkg->priority = xstrdup(newpkg->priority);
432 if (!oldpkg->source)
433 oldpkg->source = xstrdup(newpkg->source);
434 if (nv_pair_list_empty(&oldpkg->conffiles)){
435 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
436 conffile_list_init(&newpkg->conffiles);
437 }
438 if (!oldpkg->installed_files){
439 oldpkg->installed_files = newpkg->installed_files;
440 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
441 newpkg->installed_files = NULL;
442 }
443 if (!oldpkg->essential)
444 oldpkg->essential = newpkg->essential;
445
446 return 0;
447 }
448
449 abstract_pkg_t *abstract_pkg_new(void)
450 {
451 abstract_pkg_t * ab_pkg;
452
453 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
454
455 if (ab_pkg == NULL) {
456 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
457 return NULL;
458 }
459
460 if ( abstract_pkg_init(ab_pkg) < 0 )
461 return NULL;
462
463 return ab_pkg;
464 }
465
466 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
467 {
468 ab_pkg->provided_by = abstract_pkg_vec_alloc();
469 if (ab_pkg->provided_by==NULL){
470 return -1;
471 }
472 ab_pkg->dependencies_checked = 0;
473 ab_pkg->state_status = SS_NOT_INSTALLED;
474
475 return 0;
476 }
477
478 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
479 char * temp_str;
480 char **raw =NULL;
481 char **raw_start=NULL;
482
483 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
484 temp_str = (char *) alloca (str_size);
485 memset(temp_str, 0 , str_size);
486
487 if (temp_str == NULL ){
488 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
489 return;
490 }
491 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
492
493 raw = raw_start = read_raw_pkgs_from_file(temp_str);
494 if (raw == NULL ){
495 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
496 return;
497 }
498
499 while(*raw){
500 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
501 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
502 }
503 }
504 raw = raw_start;
505 while (*raw) {
506 if (raw!=NULL)
507 free(*raw++);
508 }
509
510 free(raw_start);
511
512 return ;
513
514 }
515
516 void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
517 {
518 int i;
519 int flag_provide_false = 0;
520
521 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
522 goto UNKNOWN_FMT_FIELD;
523 }
524
525 switch (field[0])
526 {
527 case 'a':
528 case 'A':
529 if (strcasecmp(field, "Architecture") == 0) {
530 if (pkg->architecture) {
531 fprintf(fp, "Architecture: %s\n", pkg->architecture);
532 }
533 } else if (strcasecmp(field, "Auto-Installed") == 0) {
534 if (pkg->auto_installed)
535 fprintf(fp, "Auto-Installed: yes\n");
536 } else {
537 goto UNKNOWN_FMT_FIELD;
538 }
539 break;
540 case 'c':
541 case 'C':
542 if (strcasecmp(field, "Conffiles") == 0) {
543 conffile_list_elt_t *iter;
544
545 if (nv_pair_list_empty(&pkg->conffiles))
546 return;
547
548 fprintf(fp, "Conffiles:\n");
549 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
550 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
551 fprintf(fp, "%s %s\n",
552 ((conffile_t *)iter->data)->name,
553 ((conffile_t *)iter->data)->value);
554 }
555 }
556 } else if (strcasecmp(field, "Conflicts") == 0) {
557 if (pkg->conflicts_count) {
558 fprintf(fp, "Conflicts:");
559 for(i = 0; i < pkg->conflicts_count; i++) {
560 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
561 }
562 fprintf(fp, "\n");
563 }
564 } else {
565 goto UNKNOWN_FMT_FIELD;
566 }
567 break;
568 case 'd':
569 case 'D':
570 if (strcasecmp(field, "Depends") == 0) {
571 if (pkg->depends_count) {
572 fprintf(fp, "Depends:");
573 for(i = 0; i < pkg->depends_count; i++) {
574 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
575 }
576 fprintf(fp, "\n");
577 }
578 } else if (strcasecmp(field, "Description") == 0) {
579 if (pkg->description) {
580 fprintf(fp, "Description: %s\n", pkg->description);
581 }
582 } else {
583 goto UNKNOWN_FMT_FIELD;
584 }
585 break;
586 case 'e':
587 case 'E':
588 if (pkg->essential) {
589 fprintf(fp, "Essential: yes\n");
590 }
591 break;
592 case 'f':
593 case 'F':
594 if (pkg->filename) {
595 fprintf(fp, "Filename: %s\n", pkg->filename);
596 }
597 break;
598 case 'i':
599 case 'I':
600 if (strcasecmp(field, "Installed-Size") == 0) {
601 fprintf(fp, "Installed-Size: %s\n", pkg->installed_size);
602 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
603 fprintf(fp, "Installed-Time: %lu\n", pkg->installed_time);
604 }
605 break;
606 case 'm':
607 case 'M':
608 if (strcasecmp(field, "Maintainer") == 0) {
609 if (pkg->maintainer) {
610 fprintf(fp, "maintainer: %s\n", pkg->maintainer);
611 }
612 } else if (strcasecmp(field, "MD5sum") == 0) {
613 if (pkg->md5sum) {
614 fprintf(fp, "MD5Sum: %s\n", pkg->md5sum);
615 }
616 } else {
617 goto UNKNOWN_FMT_FIELD;
618 }
619 break;
620 case 'p':
621 case 'P':
622 if (strcasecmp(field, "Package") == 0) {
623 fprintf(fp, "Package: %s\n", pkg->name);
624 } else if (strcasecmp(field, "Priority") == 0) {
625 fprintf(fp, "Priority: %s\n", pkg->priority);
626 } else if (strcasecmp(field, "Provides") == 0) {
627 if (pkg->provides_count) {
628 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
629 for ( i=0; i < pkg->provides_count; i++ ){
630 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
631 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
632 flag_provide_false = 1;
633 }
634 }
635 if ( !flag_provide_false || /* Pigi there is not my trick flag */
636 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
637 fprintf(fp, "Provides:");
638 for(i = 0; i < pkg->provides_count; i++) {
639 if (strlen(pkg->provides_str[i])>0) {
640 fprintf(fp, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
641 }
642 }
643 fprintf(fp, "\n");
644 }
645 }
646 } else {
647 goto UNKNOWN_FMT_FIELD;
648 }
649 break;
650 case 'r':
651 case 'R':
652 if (strcasecmp (field, "Replaces") == 0) {
653 if (pkg->replaces_count) {
654 fprintf(fp, "Replaces:");
655 for (i = 0; i < pkg->replaces_count; i++) {
656 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
657 }
658 fprintf(fp, "\n");
659 }
660 } else if (strcasecmp (field, "Recommends") == 0) {
661 if (pkg->recommends_count) {
662 fprintf(fp, "Recommends:");
663 for(i = 0; i < pkg->recommends_count; i++) {
664 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
665 }
666 fprintf(fp, "\n");
667 }
668 } else {
669 goto UNKNOWN_FMT_FIELD;
670 }
671 break;
672 case 's':
673 case 'S':
674 if (strcasecmp(field, "Section") == 0) {
675 if (pkg->section) {
676 fprintf(fp, "Section: %s\n", pkg->section);
677 }
678 #if defined HAVE_SHA256
679 } else if (strcasecmp(field, "SHA256sum") == 0) {
680 if (pkg->sha256sum) {
681 fprintf(fp, "SHA256sum: %s\n", pkg->sha256sum);
682 }
683 #endif
684 } else if (strcasecmp(field, "Size") == 0) {
685 if (pkg->size) {
686 fprintf(fp, "Size: %s\n", pkg->size);
687 }
688 } else if (strcasecmp(field, "Source") == 0) {
689 if (pkg->source) {
690 fprintf(fp, "Source: %s\n", pkg->source);
691 }
692 } else if (strcasecmp(field, "Status") == 0) {
693 char *pflag = pkg_state_flag_to_str(pkg->state_flag);
694 char *pstat = pkg_state_status_to_str(pkg->state_status);
695 char *pwant = pkg_state_want_to_str(pkg->state_want);
696
697 if (pflag == NULL || pstat == NULL || pwant == NULL)
698 return;
699
700 fprintf(fp, "Status: %s %s %s\n", pwant, pflag, pstat);
701
702 free(pflag);
703 free(pwant);
704 free(pstat);
705 } else if (strcasecmp(field, "Suggests") == 0) {
706 if (pkg->suggests_count) {
707 fprintf(fp, "Suggests:");
708 for(i = 0; i < pkg->suggests_count; i++) {
709 fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
710 }
711 fprintf(fp, "\n");
712 }
713 } else {
714 goto UNKNOWN_FMT_FIELD;
715 }
716 break;
717 case 't':
718 case 'T':
719 if (strcasecmp(field, "Tags") == 0) {
720 if (pkg->tags) {
721 fprintf(fp, "Tags: %s\n", pkg->tags);
722 }
723 }
724 break;
725 case 'v':
726 case 'V':
727 {
728 char *version = pkg_version_str_alloc(pkg);
729 if (version == NULL)
730 return;
731 fprintf(fp, "Version: %s\n", version);
732 free(version);
733 }
734 break;
735 default:
736 goto UNKNOWN_FMT_FIELD;
737 }
738
739 return;
740
741 UNKNOWN_FMT_FIELD:
742 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
743 }
744
745 void pkg_formatted_info(FILE *fp, pkg_t *pkg)
746 {
747 pkg_formatted_field(fp, pkg, "Package");
748 pkg_formatted_field(fp, pkg, "Version");
749 pkg_formatted_field(fp, pkg, "Depends");
750 pkg_formatted_field(fp, pkg, "Recommends");
751 pkg_formatted_field(fp, pkg, "Suggests");
752 pkg_formatted_field(fp, pkg, "Provides");
753 pkg_formatted_field(fp, pkg, "Replaces");
754 pkg_formatted_field(fp, pkg, "Conflicts");
755 pkg_formatted_field(fp, pkg, "Status");
756 pkg_formatted_field(fp, pkg, "Section");
757 pkg_formatted_field(fp, pkg, "Essential");
758 pkg_formatted_field(fp, pkg, "Architecture");
759 pkg_formatted_field(fp, pkg, "Maintainer");
760 pkg_formatted_field(fp, pkg, "MD5sum");
761 pkg_formatted_field(fp, pkg, "Size");
762 pkg_formatted_field(fp, pkg, "Filename");
763 pkg_formatted_field(fp, pkg, "Conffiles");
764 pkg_formatted_field(fp, pkg, "Source");
765 pkg_formatted_field(fp, pkg, "Description");
766 pkg_formatted_field(fp, pkg, "Installed-Time");
767 pkg_formatted_field(fp, pkg, "Tags");
768 fputs("\n", fp);
769 }
770
771 void pkg_print_status(pkg_t * pkg, FILE * file)
772 {
773 if (pkg == NULL) {
774 return;
775 }
776
777 /* XXX: QUESTION: Do we actually want more fields here? The
778 original idea was to save space by installing only what was
779 needed for actual computation, (package, version, status,
780 essential, conffiles). The assumption is that all other fields
781 can be found in th available file.
782
783 But, someone proposed the idea to make it possible to
784 reconstruct a .opk from an installed package, (ie. for beaming
785 from one handheld to another). So, maybe we actually want a few
786 more fields here, (depends, suggests, etc.), so that that would
787 be guaranteed to work even in the absence of more information
788 from the available file.
789
790 28-MAR-03: kergoth and I discussed this yesterday. We think
791 the essential info needs to be here for all installed packages
792 because they may not appear in the Packages files on various
793 feeds. Furthermore, one should be able to install from URL or
794 local storage without requiring a Packages file from any feed.
795 -Jamey
796 */
797 pkg_formatted_field(file, pkg, "Package");
798 pkg_formatted_field(file, pkg, "Version");
799 pkg_formatted_field(file, pkg, "Depends");
800 pkg_formatted_field(file, pkg, "Recommends");
801 pkg_formatted_field(file, pkg, "Suggests");
802 pkg_formatted_field(file, pkg, "Provides");
803 pkg_formatted_field(file, pkg, "Replaces");
804 pkg_formatted_field(file, pkg, "Conflicts");
805 pkg_formatted_field(file, pkg, "Status");
806 pkg_formatted_field(file, pkg, "Essential");
807 pkg_formatted_field(file, pkg, "Architecture");
808 pkg_formatted_field(file, pkg, "Conffiles");
809 pkg_formatted_field(file, pkg, "Installed-Time");
810 pkg_formatted_field(file, pkg, "Auto-Installed");
811 fputs("\n", file);
812 }
813
814 /*
815 * libdpkg - Debian packaging suite library routines
816 * vercmp.c - comparison of version numbers
817 *
818 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
819 */
820 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
821 {
822 int r;
823
824 if (pkg->epoch > ref_pkg->epoch) {
825 return 1;
826 }
827
828 if (pkg->epoch < ref_pkg->epoch) {
829 return -1;
830 }
831
832 r = verrevcmp(pkg->version, ref_pkg->version);
833 if (r) {
834 return r;
835 }
836
837 r = verrevcmp(pkg->revision, ref_pkg->revision);
838 if (r) {
839 return r;
840 }
841
842 return r;
843 }
844
845 /* assume ascii; warning: evaluates x multiple times! */
846 #define order(x) ((x) == '~' ? -1 \
847 : isdigit((x)) ? 0 \
848 : !(x) ? 0 \
849 : isalpha((x)) ? (x) \
850 : (x) + 256)
851
852 static int verrevcmp(const char *val, const char *ref) {
853 if (!val) val= "";
854 if (!ref) ref= "";
855
856 while (*val || *ref) {
857 int first_diff= 0;
858
859 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
860 int vc= order(*val), rc= order(*ref);
861 if (vc != rc) return vc - rc;
862 val++; ref++;
863 }
864
865 while ( *val == '0' ) val++;
866 while ( *ref == '0' ) ref++;
867 while (isdigit(*val) && isdigit(*ref)) {
868 if (!first_diff) first_diff= *val - *ref;
869 val++; ref++;
870 }
871 if (isdigit(*val)) return 1;
872 if (isdigit(*ref)) return -1;
873 if (first_diff) return first_diff;
874 }
875 return 0;
876 }
877
878 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
879 {
880 int r;
881
882 r = pkg_compare_versions(it, ref);
883
884 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
885 return r <= 0;
886 }
887
888 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
889 return r >= 0;
890 }
891
892 if (strcmp(op, "<<") == 0) {
893 return r < 0;
894 }
895
896 if (strcmp(op, ">>") == 0) {
897 return r > 0;
898 }
899
900 if (strcmp(op, "=") == 0) {
901 return r == 0;
902 }
903
904 fprintf(stderr, "unknown operator: %s", op);
905 return 0;
906 }
907
908 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
909 {
910 const pkg_t *a = *(const pkg_t**) p1;
911 const pkg_t *b = *(const pkg_t**) p2;
912 int namecmp;
913 int vercmp;
914 if (!a->name || !b->name) {
915 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
916 a, a->name, b, b->name);
917 return 0;
918 }
919
920 namecmp = strcmp(a->name, b->name);
921 if (namecmp)
922 return namecmp;
923 vercmp = pkg_compare_versions(a, b);
924 if (vercmp)
925 return vercmp;
926 if (!a->arch_priority || !b->arch_priority) {
927 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
928 a, a->arch_priority, b, b->arch_priority);
929 return 0;
930 }
931 if (a->arch_priority > b->arch_priority)
932 return 1;
933 if (a->arch_priority < b->arch_priority)
934 return -1;
935 return 0;
936 }
937
938 int abstract_pkg_name_compare(const void *p1, const void *p2)
939 {
940 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
941 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
942 if (!a->name || !b->name) {
943 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
944 a, a->name, b, b->name);
945 return 0;
946 }
947 return strcmp(a->name, b->name);
948 }
949
950
951 char *pkg_version_str_alloc(pkg_t *pkg)
952 {
953 char *complete_version;
954 char *epoch_str;
955 char *revision_str;
956
957 if (pkg->epoch) {
958 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
959 } else {
960 epoch_str = xstrdup("");
961 }
962
963 if (pkg->revision && strlen(pkg->revision)) {
964 sprintf_alloc(&revision_str, "-%s", pkg->revision);
965 } else {
966 revision_str = xstrdup("");
967 }
968
969
970 sprintf_alloc(&complete_version, "%s%s%s",
971 epoch_str, pkg->version, revision_str);
972
973 free(epoch_str);
974 free(revision_str);
975
976 return complete_version;
977 }
978
979 str_list_t *pkg_get_installed_files(pkg_t *pkg)
980 {
981 int err;
982 char *list_file_name = NULL;
983 FILE *list_file = NULL;
984 char *line;
985 char *installed_file_name;
986 int rootdirlen;
987
988 pkg->installed_files_ref_cnt++;
989
990 if (pkg->installed_files) {
991 return pkg->installed_files;
992 }
993
994 pkg->installed_files = str_list_alloc();
995 if (pkg->installed_files == NULL) {
996 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
997 return NULL;
998 }
999
1000 /* For uninstalled packages, get the file list directly from the package.
1001 For installed packages, look at the package.list file in the database.
1002 */
1003 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1004 if (pkg->local_filename == NULL) {
1005 return pkg->installed_files;
1006 }
1007 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1008 file. In other words, change deb_extract so that it can
1009 simply return the file list as a char *[] rather than
1010 insisting on writing in to a FILE * as it does now. */
1011 list_file = tmpfile();
1012 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1013 if (err) {
1014 fclose(list_file);
1015 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1016 __FUNCTION__, pkg->local_filename, strerror(err));
1017 return pkg->installed_files;
1018 }
1019 rewind(list_file);
1020 } else {
1021 sprintf_alloc(&list_file_name, "%s/%s.list",
1022 pkg->dest->info_dir, pkg->name);
1023 if (! file_exists(list_file_name)) {
1024 free(list_file_name);
1025 return pkg->installed_files;
1026 }
1027
1028 list_file = fopen(list_file_name, "r");
1029 if (list_file == NULL) {
1030 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1031 list_file_name, strerror(errno));
1032 free(list_file_name);
1033 return pkg->installed_files;
1034 }
1035 free(list_file_name);
1036 }
1037
1038 rootdirlen = strlen( pkg->dest->root_dir );
1039 while (1) {
1040 char *file_name;
1041
1042 line = file_read_line_alloc(list_file);
1043 if (line == NULL) {
1044 break;
1045 }
1046 str_chomp(line);
1047 file_name = line;
1048
1049 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1050 if( strncmp( pkg->dest->root_dir,
1051 file_name,
1052 rootdirlen ) ) {
1053 if (*file_name == '.') {
1054 file_name++;
1055 }
1056 if (*file_name == '/') {
1057 file_name++;
1058 }
1059
1060 /* Freed in pkg_free_installed_files */
1061 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1062 } else {
1063 // already contains root_dir as header -> ABSOLUTE
1064 sprintf_alloc(&installed_file_name, "%s", file_name);
1065 }
1066 str_list_append(pkg->installed_files, installed_file_name);
1067 free(installed_file_name);
1068 free(line);
1069 }
1070
1071 fclose(list_file);
1072
1073 return pkg->installed_files;
1074 }
1075
1076 /* XXX: CLEANUP: This function and it's counterpart,
1077 (pkg_get_installed_files), do not match our init/deinit naming
1078 convention. Nor the alloc/free convention. But, then again, neither
1079 of these conventions currrently fit the way these two functions
1080 work. */
1081 int pkg_free_installed_files(pkg_t *pkg)
1082 {
1083 pkg->installed_files_ref_cnt--;
1084
1085 if (pkg->installed_files_ref_cnt > 0)
1086 return 0;
1087
1088 if (pkg->installed_files) {
1089 str_list_purge(pkg->installed_files);
1090 }
1091
1092 pkg->installed_files = NULL;
1093
1094 return 0;
1095 }
1096
1097 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1098 {
1099 int err;
1100 char *list_file_name;
1101
1102 //I don't think pkg_free_installed_files should be called here. Jamey
1103 //pkg_free_installed_files(pkg);
1104
1105 sprintf_alloc(&list_file_name, "%s/%s.list",
1106 pkg->dest->info_dir, pkg->name);
1107 if (!conf->noaction) {
1108 err = unlink(list_file_name);
1109 free(list_file_name);
1110
1111 if (err) {
1112 return errno;
1113 }
1114 }
1115 return 0;
1116 }
1117
1118 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1119 {
1120 conffile_list_elt_t *iter;
1121 conffile_t *conffile;
1122
1123 if (pkg == NULL) {
1124 return NULL;
1125 }
1126
1127 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1128 conffile = (conffile_t *)iter->data;
1129
1130 if (strcmp(conffile->name, file_name) == 0) {
1131 return conffile;
1132 }
1133 }
1134
1135 return NULL;
1136 }
1137
1138 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1139 const char *script, const char *args)
1140 {
1141 int err;
1142 char *path;
1143 char *cmd;
1144
1145 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1146 maintainer script within a chroot environment. */
1147
1148 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1149 have scripts in pkg->tmp_unpack_dir. */
1150 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1151 if (pkg->dest == NULL) {
1152 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1153 __FUNCTION__, pkg->name);
1154 return EINVAL;
1155 }
1156 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1157 } else {
1158 if (pkg->tmp_unpack_dir == NULL) {
1159 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1160 __FUNCTION__, pkg->name);
1161 return EINVAL;
1162 }
1163 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1164 }
1165
1166 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1167 if (conf->noaction) return 0;
1168
1169 /* XXX: CLEANUP: There must be a better way to handle maintainer
1170 scripts when running with offline_root mode and/or a dest other
1171 than '/'. I've been playing around with some clever chroot
1172 tricks and I might come up with something workable. */
1173 /*
1174 * Attempt to provide a restricted environment for offline operation
1175 * Need the following set as a minimum:
1176 * OPKG_OFFLINE_ROOT = absolute path to root dir
1177 * D = absolute path to root dir (for OE generated postinst)
1178 * PATH = something safe (a restricted set of utilities)
1179 */
1180
1181 bool AllowOfflineMode = false;
1182 if (conf->offline_root) {
1183 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1184 setenv("D", conf->offline_root, 1);
1185 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1186 setenv("PATH", "/dev/null", 1);
1187 } else {
1188 setenv("PATH", conf->offline_root_path, 1);
1189 AllowOfflineMode = true;
1190 }
1191 }
1192
1193 setenv("PKG_ROOT",
1194 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1195
1196 if (! file_exists(path)) {
1197 free(path);
1198 return 0;
1199 }
1200
1201 if (conf->offline_root && !AllowOfflineMode) {
1202 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1203 free(path);
1204 return 0;
1205 }
1206
1207 sprintf_alloc(&cmd, "%s %s", path, args);
1208 free(path);
1209
1210 err = xsystem(cmd);
1211 free(cmd);
1212
1213 if (err) {
1214 fprintf(stderr, "%s script returned status %d\n", script, err);
1215 return err;
1216 }
1217
1218 return 0;
1219 }
1220
1221 char *pkg_state_want_to_str(pkg_state_want_t sw)
1222 {
1223 int i;
1224
1225 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1226 if (pkg_state_want_map[i].value == sw) {
1227 return xstrdup(pkg_state_want_map[i].str);
1228 }
1229 }
1230
1231 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1232 __FUNCTION__, sw);
1233 return xstrdup("<STATE_WANT_UNKNOWN>");
1234 }
1235
1236 pkg_state_want_t pkg_state_want_from_str(char *str)
1237 {
1238 int i;
1239
1240 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1241 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1242 return pkg_state_want_map[i].value;
1243 }
1244 }
1245
1246 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1247 __FUNCTION__, str);
1248 return SW_UNKNOWN;
1249 }
1250
1251 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1252 {
1253 int i;
1254 int len = 3; /* ok\000 is minimum */
1255 char *str = NULL;
1256
1257 /* clear the temporary flags before converting to string */
1258 sf &= SF_NONVOLATILE_FLAGS;
1259
1260 if (sf == 0) {
1261 return xstrdup("ok");
1262 } else {
1263
1264 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1265 if (sf & pkg_state_flag_map[i].value) {
1266 len += strlen(pkg_state_flag_map[i].str) + 1;
1267 }
1268 }
1269 str = malloc(len);
1270 if ( str == NULL ) {
1271 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1272 return NULL;
1273 }
1274 str[0] = 0;
1275 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1276 if (sf & pkg_state_flag_map[i].value) {
1277 strcat(str, pkg_state_flag_map[i].str);
1278 strcat(str, ",");
1279 }
1280 }
1281 len = strlen(str);
1282 str[len-1] = 0; /* squash last comma */
1283 return str;
1284 }
1285 }
1286
1287 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1288 {
1289 int i;
1290 int sf = SF_OK;
1291
1292 if (strcmp(str, "ok") == 0) {
1293 return SF_OK;
1294 }
1295 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1296 const char *sfname = pkg_state_flag_map[i].str;
1297 int sfname_len = strlen(sfname);
1298 if (strncmp(str, sfname, sfname_len) == 0) {
1299 sf |= pkg_state_flag_map[i].value;
1300 str += sfname_len;
1301 if (str[0] == ',') {
1302 str++;
1303 } else {
1304 break;
1305 }
1306 }
1307 }
1308
1309 return sf;
1310 }
1311
1312 char *pkg_state_status_to_str(pkg_state_status_t ss)
1313 {
1314 int i;
1315
1316 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1317 if (pkg_state_status_map[i].value == ss) {
1318 return xstrdup(pkg_state_status_map[i].str);
1319 }
1320 }
1321
1322 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1323 __FUNCTION__, ss);
1324 return xstrdup("<STATE_STATUS_UNKNOWN>");
1325 }
1326
1327 pkg_state_status_t pkg_state_status_from_str(const char *str)
1328 {
1329 int i;
1330
1331 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1332 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1333 return pkg_state_status_map[i].value;
1334 }
1335 }
1336
1337 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1338 __FUNCTION__, str);
1339 return SS_NOT_INSTALLED;
1340 }
1341
1342 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1343 {
1344 nv_pair_list_elt_t *l;
1345
1346 if (!pkg->architecture)
1347 return 1;
1348
1349 list_for_each_entry(l , &conf->arch_list.head, node) {
1350 nv_pair_t *nv = (nv_pair_t *)l->data;
1351 if (strcmp(nv->name, pkg->architecture) == 0) {
1352 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1353 return 1;
1354 }
1355 }
1356
1357 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1358 return 0;
1359 }
1360
1361 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1362 {
1363 nv_pair_list_elt_t *l;
1364
1365 list_for_each_entry(l , &conf->arch_list.head, node) {
1366 nv_pair_t *nv = (nv_pair_t *)l->data;
1367 if (strcmp(nv->name, archname) == 0) {
1368 int priority = strtol(nv->value, NULL, 0);
1369 return priority;
1370 }
1371 }
1372 return 0;
1373 }
1374
1375 int pkg_info_preinstall_check(opkg_conf_t *conf)
1376 {
1377 int i;
1378 hash_table_t *pkg_hash = &conf->pkg_hash;
1379 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1380 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1381
1382 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1383 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1384 /* update arch_priority for each package */
1385 for (i = 0; i < available_pkgs->len; i++) {
1386 pkg_t *pkg = available_pkgs->pkgs[i];
1387 int arch_priority = 1;
1388 if (!pkg)
1389 continue;
1390 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1391 if (pkg->architecture)
1392 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1393 else
1394 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1395 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1396 pkg->arch_priority = arch_priority;
1397 }
1398
1399 for (i = 0; i < available_pkgs->len; i++) {
1400 pkg_t *pkg = available_pkgs->pkgs[i];
1401 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1402 /* clear flags and want for any uninstallable package */
1403 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1404 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1405 pkg->state_want = SW_UNKNOWN;
1406 pkg->state_flag = 0;
1407 }
1408 }
1409 pkg_vec_free(available_pkgs);
1410
1411 /* update the file owner data structure */
1412 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1413 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1414 for (i = 0; i < installed_pkgs->len; i++) {
1415 pkg_t *pkg = installed_pkgs->pkgs[i];
1416 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1417 str_list_elt_t *iter, *niter;
1418 if (installed_files == NULL) {
1419 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1420 break;
1421 }
1422 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1423 iter;
1424 iter = niter, niter = str_list_next(installed_files, iter)) {
1425 char *installed_file = (char *) iter->data;
1426 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1427 file_hash_set_file_owner(conf, installed_file, pkg);
1428 }
1429 pkg_free_installed_files(pkg);
1430 }
1431 pkg_vec_free(installed_pkgs);
1432
1433 return 0;
1434 }
1435
1436 struct pkg_write_filelist_data {
1437 opkg_conf_t *conf;
1438 pkg_t *pkg;
1439 FILE *stream;
1440 };
1441
1442 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1443 {
1444 struct pkg_write_filelist_data *data = data_;
1445 pkg_t *entry = entry_;
1446 if (entry == data->pkg) {
1447 fprintf(data->stream, "%s\n", key);
1448 }
1449 }
1450
1451 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1452 {
1453 struct pkg_write_filelist_data data;
1454 char *list_file_name = NULL;
1455 int err = 0;
1456
1457 if (!pkg) {
1458 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1459 return -EINVAL;
1460 }
1461 opkg_message(conf, OPKG_INFO,
1462 " creating %s.list file\n", pkg->name);
1463 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1464 if (!list_file_name) {
1465 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1466 return -ENOMEM;
1467 }
1468 opkg_message(conf, OPKG_INFO,
1469 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1470 data.stream = fopen(list_file_name, "w");
1471 if (!data.stream) {
1472 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1473 list_file_name, strerror(errno));
1474 return errno;
1475 }
1476 data.pkg = pkg;
1477 data.conf = conf;
1478 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1479 fclose(data.stream);
1480 free(list_file_name);
1481
1482 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1483
1484 return err;
1485 }
1486
1487 int pkg_write_changed_filelists(opkg_conf_t *conf)
1488 {
1489 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1490 hash_table_t *pkg_hash = &conf->pkg_hash;
1491 int i;
1492 int err;
1493 if (conf->noaction)
1494 return 0;
1495
1496 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1497 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1498 for (i = 0; i < installed_pkgs->len; i++) {
1499 pkg_t *pkg = installed_pkgs->pkgs[i];
1500 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1501 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1502 err = pkg_write_filelist(conf, pkg);
1503 if (err)
1504 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1505 }
1506 }
1507 pkg_vec_free (installed_pkgs);
1508 return 0;
1509 }