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