Add sha256 ckecksums to okpg
[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 "sprintf_alloc.h"
33 #include "file_util.h"
34 #include "str_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 int value;
42 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 int verrevcmp(const char *val, const char *ref);
75
76
77 pkg_t *pkg_new(void)
78 {
79 pkg_t *pkg;
80
81 pkg = calloc(1, sizeof(pkg_t));
82 if (pkg == NULL) {
83 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
84 return NULL;
85 }
86
87 pkg_init(pkg);
88
89 return pkg;
90 }
91
92 int pkg_init(pkg_t *pkg)
93 {
94 pkg->name = NULL;
95 pkg->epoch = 0;
96 pkg->version = NULL;
97 pkg->revision = NULL;
98 pkg->dest = NULL;
99 pkg->src = NULL;
100 pkg->architecture = NULL;
101 pkg->maintainer = NULL;
102 pkg->section = 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;
110 pkg->depends = NULL;
111 pkg->suggests_str = NULL;
112 pkg->recommends_str = NULL;
113 pkg->suggests_count = 0;
114 pkg->recommends_count = 0;
115
116 active_list_init(&pkg->list);
117
118 /* Abhaya: added init for conflicts fields */
119 pkg->conflicts = NULL;
120 pkg->conflicts_count = 0;
121
122 /* added for replaces. Jamey 7/23/2002 */
123 pkg->replaces = NULL;
124 pkg->replaces_count = 0;
125
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;
133 pkg->md5sum = NULL;
134 #if defined HAVE_SHA256
135 pkg->sha256sum = NULL;
136 #endif
137 pkg->size = NULL;
138 pkg->installed_size = NULL;
139 pkg->priority = NULL;
140 pkg->source = NULL;
141 conffile_list_init(&pkg->conffiles);
142 pkg->installed_files = NULL;
143 pkg->installed_files_ref_cnt = 0;
144 pkg->essential = 0;
145 pkg->provided_by_hand = 0;
146
147 return 0;
148 }
149
150 void compound_depend_deinit (compound_depend_t *depends)
151 {
152 int i;
153 for (i = 0; i < depends->possibility_count; i++)
154 {
155 depend_t *d;
156 d = depends->possibilities[i];
157 free (d->version);
158 free (d);
159 }
160 free (depends->possibilities);
161 }
162
163 void pkg_deinit(pkg_t *pkg)
164 {
165 int i;
166
167 free(pkg->name);
168 pkg->name = NULL;
169 pkg->epoch = 0;
170 free(pkg->version);
171 pkg->version = NULL;
172 /* revision shares storage with version, so
173 don't free */
174 pkg->revision = NULL;
175 /* owned by opkg_conf_t */
176 pkg->dest = NULL;
177 /* owned by opkg_conf_t */
178 pkg->src = NULL;
179 free(pkg->architecture);
180 pkg->architecture = NULL;
181 free(pkg->maintainer);
182 pkg->maintainer = NULL;
183 free(pkg->section);
184 pkg->section = 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;
190
191 active_list_clear(&pkg->list);
192
193 free (pkg->replaces);
194 pkg->replaces = NULL;
195
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;
200
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;
205
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;
210
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;
215
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;
220
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;
225
226 if (pkg->depends)
227 {
228 int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
229 int x;
230
231 for (x = 0; x < count; x++)
232 compound_depend_deinit (&pkg->depends[x]);
233 free (pkg->depends);
234 }
235
236 if (pkg->conflicts)
237 {
238 int x;
239 for (x = 0; x < pkg->conflicts_count; x++)
240 compound_depend_deinit (&pkg->conflicts[x]);
241 free (pkg->conflicts);
242 }
243
244 free (pkg->provides);
245
246 pkg->pre_depends_count = 0;
247 free(pkg->pre_depends_str);
248 pkg->pre_depends_str = NULL;
249 pkg->provides_count = 0;
250 free(pkg->filename);
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;
259 free(pkg->md5sum);
260 pkg->md5sum = NULL;
261 #if defined HAVE_SHA256
262 free(pkg->sha256sum);
263 pkg->sha256sum = NULL;
264 #endif
265 free(pkg->size);
266 pkg->size = NULL;
267 free(pkg->installed_size);
268 pkg->installed_size = NULL;
269 free(pkg->priority);
270 pkg->priority = NULL;
271 free(pkg->source);
272 pkg->source = 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);
279 pkg->essential = 0;
280 free (pkg->tags);
281 pkg->tags = NULL;
282 }
283
284 int pkg_init_from_file(pkg_t *pkg, const char *filename)
285 {
286 int err;
287 char **raw;
288 FILE *control_file;
289
290 err = pkg_init(pkg);
291 if (err) { return err; }
292
293 pkg->local_filename = strdup(filename);
294
295 control_file = tmpfile();
296 err = pkg_extract_control_file_to_stream(pkg, control_file);
297 if (err) { return err; }
298
299 rewind(control_file);
300 raw = read_raw_pkgs_from_stream(control_file);
301 pkg_parse_raw(pkg, &raw, NULL, NULL);
302
303 fclose(control_file);
304
305 return 0;
306 }
307
308 /* Merge any new information in newpkg into oldpkg */
309 /* XXX: CLEANUP: This function shouldn't actually modify anything in
310 newpkg, but should leave it usable. This rework is so that
311 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
312 /*
313 * uh, i thought that i had originally written this so that it took
314 * two pkgs and returned a new one? we can do that again... -sma
315 */
316 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
317 {
318 if (oldpkg == newpkg) {
319 return 0;
320 }
321
322 if (!oldpkg->src)
323 oldpkg->src = newpkg->src;
324 if (!oldpkg->dest)
325 oldpkg->dest = newpkg->dest;
326 if (!oldpkg->architecture)
327 oldpkg->architecture = str_dup_safe(newpkg->architecture);
328 if (!oldpkg->arch_priority)
329 oldpkg->arch_priority = newpkg->arch_priority;
330 if (!oldpkg->section)
331 oldpkg->section = str_dup_safe(newpkg->section);
332 if(!oldpkg->maintainer)
333 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
334 if(!oldpkg->description)
335 oldpkg->description = str_dup_safe(newpkg->description);
336 if (set_status) {
337 /* merge the state_flags from the new package */
338 oldpkg->state_want = newpkg->state_want;
339 oldpkg->state_status = newpkg->state_status;
340 oldpkg->state_flag = newpkg->state_flag;
341 } else {
342 if (oldpkg->state_want == SW_UNKNOWN)
343 oldpkg->state_want = newpkg->state_want;
344 if (oldpkg->state_status == SS_NOT_INSTALLED)
345 oldpkg->state_status = newpkg->state_status;
346 oldpkg->state_flag |= newpkg->state_flag;
347 }
348
349 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
350 oldpkg->depends_str = newpkg->depends_str;
351 newpkg->depends_str = NULL;
352 oldpkg->depends_count = newpkg->depends_count;
353 newpkg->depends_count = 0;
354
355 oldpkg->depends = newpkg->depends;
356 newpkg->depends = NULL;
357
358 oldpkg->pre_depends_str = newpkg->pre_depends_str;
359 newpkg->pre_depends_str = NULL;
360 oldpkg->pre_depends_count = newpkg->pre_depends_count;
361 newpkg->pre_depends_count = 0;
362
363 oldpkg->recommends_str = newpkg->recommends_str;
364 newpkg->recommends_str = NULL;
365 oldpkg->recommends_count = newpkg->recommends_count;
366 newpkg->recommends_count = 0;
367
368 oldpkg->suggests_str = newpkg->suggests_str;
369 newpkg->suggests_str = NULL;
370 oldpkg->suggests_count = newpkg->suggests_count;
371 newpkg->suggests_count = 0;
372 }
373
374 if (!oldpkg->provides_str) {
375 oldpkg->provides_str = newpkg->provides_str;
376 newpkg->provides_str = NULL;
377 oldpkg->provides_count = newpkg->provides_count;
378 newpkg->provides_count = 0;
379
380 oldpkg->provides = newpkg->provides;
381 newpkg->provides = NULL;
382 }
383
384 if (!oldpkg->conflicts_str) {
385 oldpkg->conflicts_str = newpkg->conflicts_str;
386 newpkg->conflicts_str = NULL;
387 oldpkg->conflicts_count = newpkg->conflicts_count;
388 newpkg->conflicts_count = 0;
389
390 oldpkg->conflicts = newpkg->conflicts;
391 newpkg->conflicts = NULL;
392 }
393
394 if (!oldpkg->replaces_str) {
395 oldpkg->replaces_str = newpkg->replaces_str;
396 newpkg->replaces_str = NULL;
397 oldpkg->replaces_count = newpkg->replaces_count;
398 newpkg->replaces_count = 0;
399
400 oldpkg->replaces = newpkg->replaces;
401 newpkg->replaces = NULL;
402 }
403
404 if (!oldpkg->filename)
405 oldpkg->filename = str_dup_safe(newpkg->filename);
406 if (0)
407 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
408 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
409 if (!oldpkg->local_filename)
410 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
411 if (!oldpkg->tmp_unpack_dir)
412 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
413 if (!oldpkg->md5sum)
414 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
415 #if defined HAVE_SHA256
416 if (!oldpkg->sha256sum)
417 oldpkg->sha256sum = str_dup_safe(newpkg->sha256sum);
418 #endif
419 if (!oldpkg->size)
420 oldpkg->size = str_dup_safe(newpkg->size);
421 if (!oldpkg->installed_size)
422 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
423 if (!oldpkg->priority)
424 oldpkg->priority = str_dup_safe(newpkg->priority);
425 if (!oldpkg->source)
426 oldpkg->source = str_dup_safe(newpkg->source);
427 if (nv_pair_list_empty(&oldpkg->conffiles)){
428 list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
429 conffile_list_init(&newpkg->conffiles);
430 }
431 if (!oldpkg->installed_files){
432 oldpkg->installed_files = newpkg->installed_files;
433 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
434 newpkg->installed_files = NULL;
435 }
436 if (!oldpkg->essential)
437 oldpkg->essential = newpkg->essential;
438
439 return 0;
440 }
441
442 abstract_pkg_t *abstract_pkg_new(void)
443 {
444 abstract_pkg_t * ab_pkg;
445
446 ab_pkg = calloc(1, sizeof(abstract_pkg_t));
447
448 if (ab_pkg == NULL) {
449 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
450 return NULL;
451 }
452
453 if ( abstract_pkg_init(ab_pkg) < 0 )
454 return NULL;
455
456 return ab_pkg;
457 }
458
459 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
460 {
461 ab_pkg->provided_by = abstract_pkg_vec_alloc();
462 if (ab_pkg->provided_by==NULL){
463 return -1;
464 }
465 ab_pkg->dependencies_checked = 0;
466 ab_pkg->state_status = SS_NOT_INSTALLED;
467
468 return 0;
469 }
470
471 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
472 char * temp_str;
473 char **raw =NULL;
474 char **raw_start=NULL;
475
476 size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
477 temp_str = (char *) alloca (str_size);
478 memset(temp_str, 0 , str_size);
479
480 if (temp_str == NULL ){
481 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
482 return;
483 }
484 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
485
486 raw = raw_start = read_raw_pkgs_from_file(temp_str);
487 if (raw == NULL ){
488 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
489 return;
490 }
491
492 while(*raw){
493 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
494 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
495 }
496 }
497 raw = raw_start;
498 while (*raw) {
499 if (raw!=NULL)
500 free(*raw++);
501 }
502
503 free(raw_start);
504
505 return ;
506
507 }
508
509 #define CHECK_BUFF_SIZE(buff, line, buf_size, page_size) do { \
510 if (strlen(buff) + strlen(line) >= (buf_size)) { \
511 buf_size += page_size; \
512 buff = realloc(buff, buf_size); \
513 } \
514 } while(0)
515 char * pkg_formatted_info(pkg_t *pkg )
516 {
517 char *line;
518 char * buff;
519 const size_t page_size = 8192;
520 size_t buff_size = page_size;
521
522 buff = calloc(1, buff_size);
523 if (buff == NULL) {
524 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
525 return NULL;
526 }
527
528 line = pkg_formatted_field(pkg, "Package");
529 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
530 strncat(buff ,line, strlen(line));
531 free(line);
532
533 line = pkg_formatted_field(pkg, "Version");
534 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
535 strncat(buff ,line, strlen(line));
536 free(line);
537
538 line = pkg_formatted_field(pkg, "Depends");
539 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
540 strncat(buff ,line, strlen(line));
541 free(line);
542
543 line = pkg_formatted_field(pkg, "Recommends");
544 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
545 strncat(buff ,line, strlen(line));
546 free(line);
547
548 line = pkg_formatted_field(pkg, "Suggests");
549 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
550 strncat(buff ,line, strlen(line));
551 free(line);
552
553 line = pkg_formatted_field(pkg, "Provides");
554 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
555 strncat(buff ,line, strlen(line));
556 free(line);
557
558 line = pkg_formatted_field(pkg, "Replaces");
559 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
560 strncat(buff ,line, strlen(line));
561 free(line);
562
563 line = pkg_formatted_field(pkg, "Conflicts");
564 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
565 strncat(buff ,line, strlen(line));
566 free(line);
567
568 line = pkg_formatted_field(pkg, "Status");
569 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
570 strncat(buff ,line, strlen(line));
571 free(line);
572
573 line = pkg_formatted_field(pkg, "Section");
574 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
575 strncat(buff ,line, strlen(line));
576 free(line);
577
578 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
579 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
580 strncat(buff ,line, strlen(line));
581 free(line);
582
583 line = pkg_formatted_field(pkg, "Architecture");
584 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
585 strncat(buff ,line, strlen(line));
586 free(line);
587
588 line = pkg_formatted_field(pkg, "Maintainer");
589 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
590 strncat(buff ,line, strlen(line));
591 free(line);
592
593 line = pkg_formatted_field(pkg, "MD5sum");
594 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
595 strncat(buff ,line, strlen(line));
596 free(line);
597
598 line = pkg_formatted_field(pkg, "Size");
599 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
600 strncat(buff ,line, strlen(line));
601 free(line);
602
603 line = pkg_formatted_field(pkg, "Filename");
604 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
605 strncat(buff ,line, strlen(line));
606 free(line);
607
608 line = pkg_formatted_field(pkg, "Conffiles");
609 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
610 strncat(buff ,line, strlen(line));
611 free(line);
612
613 line = pkg_formatted_field(pkg, "Source");
614 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
615 strncat(buff ,line, strlen(line));
616 free(line);
617
618 line = pkg_formatted_field(pkg, "Description");
619 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
620 strncat(buff ,line, strlen(line));
621 free(line);
622
623 line = pkg_formatted_field(pkg, "Installed-Time");
624 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
625 strncat(buff ,line, strlen(line));
626 free(line);
627
628 line = pkg_formatted_field(pkg, "Tags");
629 CHECK_BUFF_SIZE(buff, line, buff_size, page_size);
630 strncat(buff ,line, strlen(line));
631 free(line);
632
633 return buff;
634 }
635
636 char * pkg_formatted_field(pkg_t *pkg, const char *field )
637 {
638 static size_t LINE_LEN = 128;
639 char * temp = (char *)malloc(1);
640 int len = 0;
641 int flag_provide_false = 0;
642
643 /*
644 Pigi: After some discussion with Florian we decided to modify the full procedure in
645 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
646 */
647
648 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
649 goto UNKNOWN_FMT_FIELD;
650 }
651
652 temp[0]='\0';
653
654 switch (field[0])
655 {
656 case 'a':
657 case 'A':
658 if (strcasecmp(field, "Architecture") == 0) {
659 /* Architecture */
660 if (pkg->architecture) {
661 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
662 if ( temp == NULL ){
663 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
664 return NULL;
665 }
666 temp[0]='\0';
667 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
668 }
669 } else if (strcasecmp(field, "Auto-Installed") == 0) {
670 /* Auto-Installed flag */
671 if (pkg->auto_installed) {
672 char * s = "Auto-Installed: yes\n";
673 temp = (char *)realloc(temp, strlen(s) + 1);
674 strcpy (temp, s);
675 }
676 } else {
677 goto UNKNOWN_FMT_FIELD;
678 }
679 break;
680 case 'c':
681 case 'C':
682 if (strcasecmp(field, "Conffiles") == 0) {
683 /* Conffiles */
684 conffile_list_elt_t *iter;
685 char confstr[LINE_LEN];
686
687 if (nv_pair_list_empty(&pkg->conffiles)) {
688 return temp;
689 }
690
691 len = 14 ;
692 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
693 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
694 len = len + (strlen(((conffile_t *)iter->data)->name)+strlen(((conffile_t *)iter->data)->value)+5);
695 }
696 }
697 temp = (char *)realloc(temp,len);
698 if ( temp == NULL ){
699 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
700 return NULL;
701 }
702 temp[0]='\0';
703 strncpy(temp, "Conffiles:\n", 12);
704 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
705 if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
706 snprintf(confstr, LINE_LEN, "%s %s\n",
707 ((conffile_t *)iter->data)->name,
708 ((conffile_t *)iter->data)->value);
709 strncat(temp, confstr, strlen(confstr));
710 }
711 }
712 } else if (strcasecmp(field, "Conflicts") == 0) {
713 int i;
714
715 if (pkg->conflicts_count) {
716 char conflictstr[LINE_LEN];
717 len = 14 ;
718 for(i = 0; i < pkg->conflicts_count; i++) {
719 len = len + (strlen(pkg->conflicts_str[i])+5);
720 }
721 temp = (char *)realloc(temp,len);
722 if ( temp == NULL ){
723 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
724 return NULL;
725 }
726 temp[0]='\0';
727 strncpy(temp, "Conflicts:", 11);
728 for(i = 0; i < pkg->conflicts_count; i++) {
729 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
730 strncat(temp, conflictstr, strlen(conflictstr));
731 }
732 strncat(temp, "\n", strlen("\n"));
733 }
734 } else {
735 goto UNKNOWN_FMT_FIELD;
736 }
737 break;
738 case 'd':
739 case 'D':
740 if (strcasecmp(field, "Depends") == 0) {
741 /* Depends */
742 int i;
743
744 if (pkg->depends_count) {
745 char depstr[LINE_LEN];
746 len = 14 ;
747 for(i = 0; i < pkg->depends_count; i++) {
748 len = len + (strlen(pkg->depends_str[i])+4);
749 }
750 temp = (char *)realloc(temp,len);
751 if ( temp == NULL ){
752 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
753 return NULL;
754 }
755 temp[0]='\0';
756 strncpy(temp, "Depends:", 10);
757 for(i = 0; i < pkg->depends_count; i++) {
758 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
759 strncat(temp, depstr, strlen(depstr));
760 }
761 strncat(temp, "\n", strlen("\n"));
762 }
763 } else if (strcasecmp(field, "Description") == 0) {
764 /* Description */
765 if (pkg->description) {
766 temp = (char *)realloc(temp,strlen(pkg->description)+16);
767 if ( temp == NULL ){
768 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
769 return NULL;
770 }
771 temp[0]='\0';
772 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
773 }
774 } else {
775 goto UNKNOWN_FMT_FIELD;
776 }
777 break;
778 case 'e':
779 case 'E': {
780 /* Essential */
781 if (pkg->essential) {
782 temp = (char *)realloc(temp,16);
783 if ( temp == NULL ){
784 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
785 return NULL;
786 }
787 temp[0]='\0';
788 snprintf(temp, (16), "Essential: yes\n");
789 }
790 }
791 break;
792 case 'f':
793 case 'F': {
794 /* Filename */
795 if (pkg->filename) {
796 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
797 if ( temp == NULL ){
798 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
799 return NULL;
800 }
801 temp[0]='\0';
802 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
803 }
804 }
805 break;
806 case 'i':
807 case 'I': {
808 if (strcasecmp(field, "Installed-Size") == 0) {
809 /* Installed-Size */
810 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
811 if ( temp == NULL ){
812 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
813 return NULL;
814 }
815 temp[0]='\0';
816 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
817 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
818 temp = (char *)realloc(temp,29);
819 if ( temp == NULL ){
820 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
821 return NULL;
822 }
823 temp[0]='\0';
824 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
825 }
826 }
827 break;
828 case 'm':
829 case 'M': {
830 /* Maintainer | MD5sum */
831 if (strcasecmp(field, "Maintainer") == 0) {
832 /* Maintainer */
833 if (pkg->maintainer) {
834 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
835 if ( temp == NULL ){
836 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
837 return NULL;
838 }
839 temp[0]='\0';
840 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
841 }
842 } else if (strcasecmp(field, "MD5sum") == 0) {
843 /* MD5sum */
844 if (pkg->md5sum) {
845 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
846 if ( temp == NULL ){
847 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
848 return NULL;
849 }
850 temp[0]='\0';
851 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
852 }
853 } else {
854 goto UNKNOWN_FMT_FIELD;
855 }
856 }
857 break;
858 case 'p':
859 case 'P': {
860 if (strcasecmp(field, "Package") == 0) {
861 /* Package */
862 temp = (char *)realloc(temp,strlen(pkg->name)+11);
863 if ( temp == NULL ){
864 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
865 return NULL;
866 }
867 temp[0]='\0';
868 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
869 } else if (strcasecmp(field, "Priority") == 0) {
870 /* Priority */
871 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
872 if ( temp == NULL ){
873 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
874 return NULL;
875 }
876 temp[0]='\0';
877 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
878 } else if (strcasecmp(field, "Provides") == 0) {
879 /* Provides */
880 int i;
881
882 if (pkg->provides_count) {
883 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
884 for ( i=0; i < pkg->provides_count; i++ ){
885 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
886 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
887 flag_provide_false = 1;
888 }
889 }
890 if ( !flag_provide_false || /* Pigi there is not my trick flag */
891 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
892 char provstr[LINE_LEN];
893 len = 15;
894 for(i = 0; i < pkg->provides_count; i++) {
895 len = len + (strlen(pkg->provides_str[i])+5);
896 }
897 temp = (char *)realloc(temp,len);
898 if ( temp == NULL ){
899 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
900 return NULL;
901 }
902 temp[0]='\0';
903 strncpy(temp, "Provides:", 12);
904 for(i = 0; i < pkg->provides_count; i++) {
905 if (strlen(pkg->provides_str[i])>0){;
906 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
907 strncat(temp, provstr, strlen(provstr));
908 }
909 }
910 strncat(temp, "\n", strlen("\n"));
911 }
912 }
913 } else {
914 goto UNKNOWN_FMT_FIELD;
915 }
916 }
917 break;
918 case 'r':
919 case 'R': {
920 int i;
921 /* Replaces | Recommends*/
922 if (strcasecmp (field, "Replaces") == 0) {
923 if (pkg->replaces_count) {
924 char replstr[LINE_LEN];
925 len = 14;
926 for (i = 0; i < pkg->replaces_count; i++) {
927 len = len + (strlen(pkg->replaces_str[i])+5);
928 }
929 temp = (char *)realloc(temp,len);
930 if ( temp == NULL ){
931 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
932 return NULL;
933 }
934 temp[0]='\0';
935 strncpy(temp, "Replaces:", 12);
936 for (i = 0; i < pkg->replaces_count; i++) {
937 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
938 strncat(temp, replstr, strlen(replstr));
939 }
940 strncat(temp, "\n", strlen("\n"));
941 }
942 } else if (strcasecmp (field, "Recommends") == 0) {
943 if (pkg->recommends_count) {
944 char recstr[LINE_LEN];
945 len = 15;
946 for(i = 0; i < pkg->recommends_count; i++) {
947 len = len + (strlen( pkg->recommends_str[i])+5);
948 }
949 temp = (char *)realloc(temp,len);
950 if ( temp == NULL ){
951 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
952 return NULL;
953 }
954 temp[0]='\0';
955 strncpy(temp, "Recommends:", 13);
956 for(i = 0; i < pkg->recommends_count; i++) {
957 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
958 strncat(temp, recstr, strlen(recstr));
959 }
960 strncat(temp, "\n", strlen("\n"));
961 }
962 } else {
963 goto UNKNOWN_FMT_FIELD;
964 }
965 }
966 break;
967 case 's':
968 case 'S': {
969 /* Section | SHA256sum | Size | Source | Status | Suggests */
970 if (strcasecmp(field, "Section") == 0) {
971 /* Section */
972 if (pkg->section) {
973 temp = (char *)realloc(temp,strlen(pkg->section)+11);
974 if ( temp == NULL ){
975 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
976 return NULL;
977 }
978 temp[0]='\0';
979 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
980 }
981 #if defined HAVE_SHA256
982 } else if (strcasecmp(field, "SHA256sum") == 0) {
983 /* SHA256sum */
984 if (pkg->sha256sum) {
985 temp = (char *)realloc(temp,strlen(pkg->sha256sum)+13);
986 if ( temp == NULL ){
987 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
988 return NULL;
989 }
990 temp[0]='\0';
991 snprintf(temp, (strlen(pkg->sha256sum)+13), "SHA256sum: %s\n", pkg->sha256sum);
992 }
993 #endif
994 } else if (strcasecmp(field, "Size") == 0) {
995 /* Size */
996 if (pkg->size) {
997 temp = (char *)realloc(temp,strlen(pkg->size)+8);
998 if ( temp == NULL ){
999 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1000 return NULL;
1001 }
1002 temp[0]='\0';
1003 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
1004 }
1005 } else if (strcasecmp(field, "Source") == 0) {
1006 /* Source */
1007 if (pkg->source) {
1008 temp = (char *)realloc(temp,strlen(pkg->source)+10);
1009 if ( temp == NULL ){
1010 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1011 return NULL;
1012 }
1013 temp[0]='\0';
1014 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
1015 }
1016 } else if (strcasecmp(field, "Status") == 0) {
1017 /* Status */
1018 /* Benjamin Pineau note: we should avoid direct usage of
1019 * strlen(arg) without keeping "arg" for later free()
1020 */
1021 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
1022 char *pstat=pkg_state_status_to_str(pkg->state_status);
1023 char *pwant=pkg_state_want_to_str(pkg->state_want);
1024
1025 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
1026 temp = (char *)realloc(temp,sum_of_sizes);
1027 if ( temp == NULL ){
1028 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1029 return NULL;
1030 }
1031 temp[0]='\0';
1032 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
1033 free(pflag);
1034 free(pwant);
1035 if(pstat) /* pfstat can be NULL if ENOMEM */
1036 free(pstat);
1037 } else if (strcasecmp(field, "Suggests") == 0) {
1038 if (pkg->suggests_count) {
1039 int i;
1040 char sugstr[LINE_LEN];
1041 len = 13;
1042 for(i = 0; i < pkg->suggests_count; i++) {
1043 len = len + (strlen(pkg->suggests_str[i])+5);
1044 }
1045 temp = (char *)realloc(temp,len);
1046 if ( temp == NULL ){
1047 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1048 return NULL;
1049 }
1050 temp[0]='\0';
1051 strncpy(temp, "Suggests:", 10);
1052 for(i = 0; i < pkg->suggests_count; i++) {
1053 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
1054 strncat(temp, sugstr, strlen(sugstr));
1055 }
1056 strncat(temp, "\n", strlen("\n"));
1057 }
1058 } else {
1059 goto UNKNOWN_FMT_FIELD;
1060 }
1061 }
1062 break;
1063 case 't':
1064 case 'T':
1065 if (strcasecmp(field, "Tags") == 0) {
1066 /* Tags */
1067 if (pkg->tags) {
1068 temp = (char *)realloc(temp,strlen(pkg->tags)+8);
1069 if ( temp == NULL ){
1070 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1071 return NULL;
1072 }
1073 temp[0]='\0';
1074 snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
1075 }
1076 }
1077 break;
1078 case 'v':
1079 case 'V': {
1080 /* Version */
1081 char *version = pkg_version_str_alloc(pkg);
1082 temp = (char *)realloc(temp,strlen(version)+14);
1083 if ( temp == NULL ){
1084 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1085 return NULL;
1086 }
1087 temp[0]='\0';
1088 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
1089 free(version);
1090 }
1091 break;
1092 default:
1093 goto UNKNOWN_FMT_FIELD;
1094 }
1095
1096 if ( strlen(temp)<2 ) {
1097 temp[0]='\0';
1098 }
1099 return temp;
1100
1101 UNKNOWN_FMT_FIELD:
1102 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
1103 if ( strlen(temp)<2 ) {
1104 temp[0]='\0';
1105 }
1106
1107 return temp;
1108 }
1109
1110 void pkg_print_info(pkg_t *pkg, FILE *file)
1111 {
1112 int t=0;
1113 char * buff;
1114 if (pkg == NULL) {
1115 return;
1116 }
1117
1118 buff = pkg_formatted_info(pkg);
1119 if ( buff == NULL )
1120 return;
1121 if (strlen(buff)>2){
1122 t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
1123 }
1124 free(buff);
1125 }
1126
1127 void pkg_print_status(pkg_t * pkg, FILE * file)
1128 {
1129 if (pkg == NULL) {
1130 return;
1131 }
1132
1133 /* XXX: QUESTION: Do we actually want more fields here? The
1134 original idea was to save space by installing only what was
1135 needed for actual computation, (package, version, status,
1136 essential, conffiles). The assumption is that all other fields
1137 can be found in th available file.
1138
1139 But, someone proposed the idea to make it possible to
1140 reconstruct a .opk from an installed package, (ie. for beaming
1141 from one handheld to another). So, maybe we actually want a few
1142 more fields here, (depends, suggests, etc.), so that that would
1143 be guaranteed to work even in the absence of more information
1144 from the available file.
1145
1146 28-MAR-03: kergoth and I discussed this yesterday. We think
1147 the essential info needs to be here for all installed packages
1148 because they may not appear in the Packages files on various
1149 feeds. Furthermore, one should be able to install from URL or
1150 local storage without requiring a Packages file from any feed.
1151 -Jamey
1152 */
1153 pkg_print_field(pkg, file, "Package");
1154 pkg_print_field(pkg, file, "Version");
1155 pkg_print_field(pkg, file, "Depends");
1156 pkg_print_field(pkg, file, "Recommends");
1157 pkg_print_field(pkg, file, "Suggests");
1158 pkg_print_field(pkg, file, "Provides");
1159 pkg_print_field(pkg, file, "Replaces");
1160 pkg_print_field(pkg, file, "Conflicts");
1161 pkg_print_field(pkg, file, "Status");
1162 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1163 pkg_print_field(pkg, file, "Architecture");
1164 pkg_print_field(pkg, file, "Conffiles");
1165 pkg_print_field(pkg, file, "Installed-Time");
1166 pkg_print_field(pkg, file, "Auto-Installed");
1167 fputs("\n", file);
1168 }
1169
1170 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1171 {
1172 char *buff;
1173 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1174 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1175 __FUNCTION__, field);
1176 }
1177 buff = pkg_formatted_field(pkg, field);
1178 if (strlen(buff)>2) {
1179 fprintf(file, "%s", buff);
1180 fflush(file);
1181 }
1182 free(buff);
1183 return;
1184 }
1185
1186 /*
1187 * libdpkg - Debian packaging suite library routines
1188 * vercmp.c - comparison of version numbers
1189 *
1190 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1191 */
1192 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1193 {
1194 int r;
1195
1196 if (pkg->epoch > ref_pkg->epoch) {
1197 return 1;
1198 }
1199
1200 if (pkg->epoch < ref_pkg->epoch) {
1201 return -1;
1202 }
1203
1204 r = verrevcmp(pkg->version, ref_pkg->version);
1205 if (r) {
1206 return r;
1207 }
1208
1209 r = verrevcmp(pkg->revision, ref_pkg->revision);
1210 if (r) {
1211 return r;
1212 }
1213
1214 return r;
1215 }
1216
1217 /* assume ascii; warning: evaluates x multiple times! */
1218 #define order(x) ((x) == '~' ? -1 \
1219 : isdigit((x)) ? 0 \
1220 : !(x) ? 0 \
1221 : isalpha((x)) ? (x) \
1222 : (x) + 256)
1223
1224 static int verrevcmp(const char *val, const char *ref) {
1225 if (!val) val= "";
1226 if (!ref) ref= "";
1227
1228 while (*val || *ref) {
1229 int first_diff= 0;
1230
1231 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1232 int vc= order(*val), rc= order(*ref);
1233 if (vc != rc) return vc - rc;
1234 val++; ref++;
1235 }
1236
1237 while ( *val == '0' ) val++;
1238 while ( *ref == '0' ) ref++;
1239 while (isdigit(*val) && isdigit(*ref)) {
1240 if (!first_diff) first_diff= *val - *ref;
1241 val++; ref++;
1242 }
1243 if (isdigit(*val)) return 1;
1244 if (isdigit(*ref)) return -1;
1245 if (first_diff) return first_diff;
1246 }
1247 return 0;
1248 }
1249
1250 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1251 {
1252 int r;
1253
1254 r = pkg_compare_versions(it, ref);
1255
1256 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1257 return r <= 0;
1258 }
1259
1260 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1261 return r >= 0;
1262 }
1263
1264 if (strcmp(op, "<<") == 0) {
1265 return r < 0;
1266 }
1267
1268 if (strcmp(op, ">>") == 0) {
1269 return r > 0;
1270 }
1271
1272 if (strcmp(op, "=") == 0) {
1273 return r == 0;
1274 }
1275
1276 fprintf(stderr, "unknown operator: %s", op);
1277 return 0;
1278 }
1279
1280 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
1281 {
1282 const pkg_t *a = *(const pkg_t**) p1;
1283 const pkg_t *b = *(const pkg_t**) p2;
1284 int namecmp;
1285 int vercmp;
1286 if (!a->name || !b->name) {
1287 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1288 a, a->name, b, b->name);
1289 return 0;
1290 }
1291
1292 namecmp = strcmp(a->name, b->name);
1293 if (namecmp)
1294 return namecmp;
1295 vercmp = pkg_compare_versions(a, b);
1296 if (vercmp)
1297 return vercmp;
1298 if (!a->arch_priority || !b->arch_priority) {
1299 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1300 a, a->arch_priority, b, b->arch_priority);
1301 return 0;
1302 }
1303 if (a->arch_priority > b->arch_priority)
1304 return 1;
1305 if (a->arch_priority < b->arch_priority)
1306 return -1;
1307 return 0;
1308 }
1309
1310 int abstract_pkg_name_compare(const void *p1, const void *p2)
1311 {
1312 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1313 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1314 if (!a->name || !b->name) {
1315 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1316 a, a->name, b, b->name);
1317 return 0;
1318 }
1319 return strcmp(a->name, b->name);
1320 }
1321
1322
1323 char *pkg_version_str_alloc(pkg_t *pkg)
1324 {
1325 char *complete_version;
1326 char *epoch_str;
1327 char *revision_str;
1328
1329 if (pkg->epoch) {
1330 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1331 } else {
1332 epoch_str = strdup("");
1333 }
1334
1335 if (pkg->revision && strlen(pkg->revision)) {
1336 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1337 } else {
1338 revision_str = strdup("");
1339 }
1340
1341
1342 sprintf_alloc(&complete_version, "%s%s%s",
1343 epoch_str, pkg->version, revision_str);
1344
1345 free(epoch_str);
1346 free(revision_str);
1347
1348 return complete_version;
1349 }
1350
1351 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1352 {
1353 int err;
1354 char *list_file_name = NULL;
1355 FILE *list_file = NULL;
1356 char *line;
1357 char *installed_file_name;
1358 int rootdirlen;
1359
1360 pkg->installed_files_ref_cnt++;
1361
1362 if (pkg->installed_files) {
1363 return pkg->installed_files;
1364 }
1365
1366 pkg->installed_files = str_list_alloc();
1367 if (pkg->installed_files == NULL) {
1368 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1369 return NULL;
1370 }
1371
1372 /* For uninstalled packages, get the file list directly from the package.
1373 For installed packages, look at the package.list file in the database.
1374 */
1375 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1376 if (pkg->local_filename == NULL) {
1377 return pkg->installed_files;
1378 }
1379 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1380 file. In other words, change deb_extract so that it can
1381 simply return the file list as a char *[] rather than
1382 insisting on writing in to a FILE * as it does now. */
1383 list_file = tmpfile();
1384 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1385 if (err) {
1386 fclose(list_file);
1387 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1388 __FUNCTION__, pkg->local_filename, strerror(err));
1389 return pkg->installed_files;
1390 }
1391 rewind(list_file);
1392 } else {
1393 sprintf_alloc(&list_file_name, "%s/%s.list",
1394 pkg->dest->info_dir, pkg->name);
1395 if (! file_exists(list_file_name)) {
1396 free(list_file_name);
1397 return pkg->installed_files;
1398 }
1399
1400 list_file = fopen(list_file_name, "r");
1401 if (list_file == NULL) {
1402 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1403 list_file_name, strerror(errno));
1404 free(list_file_name);
1405 return pkg->installed_files;
1406 }
1407 free(list_file_name);
1408 }
1409
1410 rootdirlen = strlen( pkg->dest->root_dir );
1411 while (1) {
1412 char *file_name;
1413
1414 line = file_read_line_alloc(list_file);
1415 if (line == NULL) {
1416 break;
1417 }
1418 str_chomp(line);
1419 file_name = line;
1420
1421 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1422 if( strncmp( pkg->dest->root_dir,
1423 file_name,
1424 rootdirlen ) ) {
1425 if (*file_name == '.') {
1426 file_name++;
1427 }
1428 if (*file_name == '/') {
1429 file_name++;
1430 }
1431
1432 /* Freed in pkg_free_installed_files */
1433 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1434 } else {
1435 // already contains root_dir as header -> ABSOLUTE
1436 sprintf_alloc(&installed_file_name, "%s", file_name);
1437 }
1438 str_list_append(pkg->installed_files, installed_file_name);
1439 free(installed_file_name);
1440 free(line);
1441 }
1442
1443 fclose(list_file);
1444
1445 return pkg->installed_files;
1446 }
1447
1448 /* XXX: CLEANUP: This function and it's counterpart,
1449 (pkg_get_installed_files), do not match our init/deinit naming
1450 convention. Nor the alloc/free convention. But, then again, neither
1451 of these conventions currrently fit the way these two functions
1452 work. */
1453 int pkg_free_installed_files(pkg_t *pkg)
1454 {
1455 pkg->installed_files_ref_cnt--;
1456
1457 if (pkg->installed_files_ref_cnt > 0)
1458 return 0;
1459
1460 if (pkg->installed_files) {
1461 str_list_purge(pkg->installed_files);
1462 }
1463
1464 pkg->installed_files = NULL;
1465
1466 return 0;
1467 }
1468
1469 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1470 {
1471 int err;
1472 char *list_file_name;
1473
1474 //I don't think pkg_free_installed_files should be called here. Jamey
1475 //pkg_free_installed_files(pkg);
1476
1477 sprintf_alloc(&list_file_name, "%s/%s.list",
1478 pkg->dest->info_dir, pkg->name);
1479 if (!conf->noaction) {
1480 err = unlink(list_file_name);
1481 free(list_file_name);
1482
1483 if (err) {
1484 return errno;
1485 }
1486 }
1487 return 0;
1488 }
1489
1490 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1491 {
1492 conffile_list_elt_t *iter;
1493 conffile_t *conffile;
1494
1495 if (pkg == NULL) {
1496 return NULL;
1497 }
1498
1499 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1500 conffile = (conffile_t *)iter->data;
1501
1502 if (strcmp(conffile->name, file_name) == 0) {
1503 return conffile;
1504 }
1505 }
1506
1507 return NULL;
1508 }
1509
1510 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1511 const char *script, const char *args)
1512 {
1513 int err;
1514 char *path;
1515 char *cmd;
1516
1517 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1518 maintainer script within a chroot environment. */
1519
1520 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1521 have scripts in pkg->tmp_unpack_dir. */
1522 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1523 if (pkg->dest == NULL) {
1524 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1525 __FUNCTION__, pkg->name);
1526 return EINVAL;
1527 }
1528 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1529 } else {
1530 if (pkg->tmp_unpack_dir == NULL) {
1531 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1532 __FUNCTION__, pkg->name);
1533 return EINVAL;
1534 }
1535 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1536 }
1537
1538 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1539 if (conf->noaction) return 0;
1540
1541 /* XXX: CLEANUP: There must be a better way to handle maintainer
1542 scripts when running with offline_root mode and/or a dest other
1543 than '/'. I've been playing around with some clever chroot
1544 tricks and I might come up with something workable. */
1545 /*
1546 * Attempt to provide a restricted environment for offline operation
1547 * Need the following set as a minimum:
1548 * OPKG_OFFLINE_ROOT = absolute path to root dir
1549 * D = absolute path to root dir (for OE generated postinst)
1550 * PATH = something safe (a restricted set of utilities)
1551 */
1552
1553 bool AllowOfflineMode = false;
1554 if (conf->offline_root) {
1555 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1556 setenv("D", conf->offline_root, 1);
1557 if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
1558 setenv("PATH", "/dev/null", 1);
1559 } else {
1560 setenv("PATH", conf->offline_root_path, 1);
1561 AllowOfflineMode = true;
1562 }
1563 }
1564
1565 setenv("PKG_ROOT",
1566 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1567
1568 if (! file_exists(path)) {
1569 free(path);
1570 return 0;
1571 }
1572
1573 if (conf->offline_root && !AllowOfflineMode) {
1574 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1575 free(path);
1576 return 0;
1577 }
1578
1579 sprintf_alloc(&cmd, "%s %s", path, args);
1580 free(path);
1581
1582 err = xsystem(cmd);
1583 free(cmd);
1584
1585 if (err) {
1586 fprintf(stderr, "%s script returned status %d\n", script, err);
1587 return err;
1588 }
1589
1590 return 0;
1591 }
1592
1593 char *pkg_state_want_to_str(pkg_state_want_t sw)
1594 {
1595 int i;
1596
1597 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1598 if (pkg_state_want_map[i].value == sw) {
1599 return strdup(pkg_state_want_map[i].str);
1600 }
1601 }
1602
1603 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1604 __FUNCTION__, sw);
1605 return strdup("<STATE_WANT_UNKNOWN>");
1606 }
1607
1608 pkg_state_want_t pkg_state_want_from_str(char *str)
1609 {
1610 int i;
1611
1612 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1613 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1614 return pkg_state_want_map[i].value;
1615 }
1616 }
1617
1618 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1619 __FUNCTION__, str);
1620 return SW_UNKNOWN;
1621 }
1622
1623 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1624 {
1625 int i;
1626 int len = 3; /* ok\000 is minimum */
1627 char *str = NULL;
1628
1629 /* clear the temporary flags before converting to string */
1630 sf &= SF_NONVOLATILE_FLAGS;
1631
1632 if (sf == 0) {
1633 return strdup("ok");
1634 } else {
1635
1636 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1637 if (sf & pkg_state_flag_map[i].value) {
1638 len += strlen(pkg_state_flag_map[i].str) + 1;
1639 }
1640 }
1641 str = malloc(len);
1642 if ( str == NULL ) {
1643 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1644 return NULL;
1645 }
1646 str[0] = 0;
1647 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1648 if (sf & pkg_state_flag_map[i].value) {
1649 strcat(str, pkg_state_flag_map[i].str);
1650 strcat(str, ",");
1651 }
1652 }
1653 len = strlen(str);
1654 str[len-1] = 0; /* squash last comma */
1655 return str;
1656 }
1657 }
1658
1659 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1660 {
1661 int i;
1662 int sf = SF_OK;
1663
1664 if (strcmp(str, "ok") == 0) {
1665 return SF_OK;
1666 }
1667 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1668 const char *sfname = pkg_state_flag_map[i].str;
1669 int sfname_len = strlen(sfname);
1670 if (strncmp(str, sfname, sfname_len) == 0) {
1671 sf |= pkg_state_flag_map[i].value;
1672 str += sfname_len;
1673 if (str[0] == ',') {
1674 str++;
1675 } else {
1676 break;
1677 }
1678 }
1679 }
1680
1681 return sf;
1682 }
1683
1684 char *pkg_state_status_to_str(pkg_state_status_t ss)
1685 {
1686 int i;
1687
1688 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1689 if (pkg_state_status_map[i].value == ss) {
1690 return strdup(pkg_state_status_map[i].str);
1691 }
1692 }
1693
1694 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1695 __FUNCTION__, ss);
1696 return strdup("<STATE_STATUS_UNKNOWN>");
1697 }
1698
1699 pkg_state_status_t pkg_state_status_from_str(const char *str)
1700 {
1701 int i;
1702
1703 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1704 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1705 return pkg_state_status_map[i].value;
1706 }
1707 }
1708
1709 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1710 __FUNCTION__, str);
1711 return SS_NOT_INSTALLED;
1712 }
1713
1714 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1715 {
1716 nv_pair_list_elt_t *l;
1717
1718 if (!pkg->architecture)
1719 return 1;
1720
1721 list_for_each_entry(l , &conf->arch_list.head, node) {
1722 nv_pair_t *nv = (nv_pair_t *)l->data;
1723 if (strcmp(nv->name, pkg->architecture) == 0) {
1724 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1725 return 1;
1726 }
1727 }
1728
1729 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1730 return 0;
1731 }
1732
1733 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1734 {
1735 nv_pair_list_elt_t *l;
1736
1737 list_for_each_entry(l , &conf->arch_list.head, node) {
1738 nv_pair_t *nv = (nv_pair_t *)l->data;
1739 if (strcmp(nv->name, archname) == 0) {
1740 int priority = strtol(nv->value, NULL, 0);
1741 return priority;
1742 }
1743 }
1744 return 0;
1745 }
1746
1747 int pkg_info_preinstall_check(opkg_conf_t *conf)
1748 {
1749 int i;
1750 hash_table_t *pkg_hash = &conf->pkg_hash;
1751 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1752 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1753
1754 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1755 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1756 /* update arch_priority for each package */
1757 for (i = 0; i < available_pkgs->len; i++) {
1758 pkg_t *pkg = available_pkgs->pkgs[i];
1759 int arch_priority = 1;
1760 if (!pkg)
1761 continue;
1762 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1763 if (pkg->architecture)
1764 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1765 else
1766 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1767 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1768 pkg->arch_priority = arch_priority;
1769 }
1770
1771 for (i = 0; i < available_pkgs->len; i++) {
1772 pkg_t *pkg = available_pkgs->pkgs[i];
1773 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1774 /* clear flags and want for any uninstallable package */
1775 opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1776 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1777 pkg->state_want = SW_UNKNOWN;
1778 pkg->state_flag = 0;
1779 }
1780 }
1781 pkg_vec_free(available_pkgs);
1782
1783 /* update the file owner data structure */
1784 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1785 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1786 for (i = 0; i < installed_pkgs->len; i++) {
1787 pkg_t *pkg = installed_pkgs->pkgs[i];
1788 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1789 str_list_elt_t *iter, *niter;
1790 if (installed_files == NULL) {
1791 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1792 break;
1793 }
1794 for (iter = str_list_first(installed_files), niter = str_list_next(installed_files, iter);
1795 iter;
1796 iter = niter, niter = str_list_next(installed_files, iter)) {
1797 char *installed_file = (char *) iter->data;
1798 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1799 file_hash_set_file_owner(conf, installed_file, pkg);
1800 }
1801 pkg_free_installed_files(pkg);
1802 }
1803 pkg_vec_free(installed_pkgs);
1804
1805 return 0;
1806 }
1807
1808 struct pkg_write_filelist_data {
1809 opkg_conf_t *conf;
1810 pkg_t *pkg;
1811 FILE *stream;
1812 };
1813
1814 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1815 {
1816 struct pkg_write_filelist_data *data = data_;
1817 pkg_t *entry = entry_;
1818 if (entry == data->pkg) {
1819 fprintf(data->stream, "%s\n", key);
1820 }
1821 }
1822
1823 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1824 {
1825 struct pkg_write_filelist_data data;
1826 char *list_file_name = NULL;
1827 int err = 0;
1828
1829 if (!pkg) {
1830 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1831 return -EINVAL;
1832 }
1833 opkg_message(conf, OPKG_INFO,
1834 " creating %s.list file\n", pkg->name);
1835 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1836 if (!list_file_name) {
1837 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1838 return -ENOMEM;
1839 }
1840 opkg_message(conf, OPKG_INFO,
1841 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1842 data.stream = fopen(list_file_name, "w");
1843 if (!data.stream) {
1844 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1845 list_file_name, strerror(errno));
1846 return errno;
1847 }
1848 data.pkg = pkg;
1849 data.conf = conf;
1850 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1851 fclose(data.stream);
1852 free(list_file_name);
1853
1854 pkg->state_flag &= ~SF_FILELIST_CHANGED;
1855
1856 return err;
1857 }
1858
1859 int pkg_write_changed_filelists(opkg_conf_t *conf)
1860 {
1861 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1862 hash_table_t *pkg_hash = &conf->pkg_hash;
1863 int i;
1864 int err;
1865 if (conf->noaction)
1866 return 0;
1867
1868 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1869 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1870 for (i = 0; i < installed_pkgs->len; i++) {
1871 pkg_t *pkg = installed_pkgs->pkgs[i];
1872 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1873 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1874 err = pkg_write_filelist(conf, pkg);
1875 if (err)
1876 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
1877 }
1878 }
1879 pkg_vec_free (installed_pkgs);
1880 return 0;
1881 }