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