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