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