using hash_table reduce an O(n^2) algorithm to O(n)
[oweals/opkg-lede.git] / libopkg / opkg_install.c
1 /* opkg_install.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 <errno.h>
20 #include <dirent.h>
21 #include <glob.h>
22 #include <time.h>
23 #include <signal.h>
24 #ifndef __USE_GNU
25 typedef void (*sighandler_t)(int);
26 #endif
27
28 #include "pkg.h"
29 #include "pkg_hash.h"
30 #include "pkg_extract.h"
31
32 #include "opkg_install.h"
33 #include "opkg_configure.h"
34 #include "opkg_download.h"
35 #include "opkg_remove.h"
36
37 #include "opkg_utils.h"
38 #include "opkg_message.h"
39 #include "opkg_state.h"
40 #include "opkg_defines.h"
41
42 #include "sprintf_alloc.h"
43 #include "file_util.h"
44 #include "str_util.h"
45 #include "xsystem.h"
46 #include "user.h"
47
48 static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg);
49 static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg);
50
51 static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
52 static int prerm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
53 static int prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
54 static int prerm_deconfigure_conflictors_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
55 static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
56 static int preinst_configure_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
57 static int check_data_file_clashes(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
58 static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
59 static int check_data_file_clashes_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
60 static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
61 static int backup_modified_conffiles_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
62 static int postrm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
63 static int postrm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
64
65 static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
66 static int install_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
67 static int remove_disappeared(opkg_conf_t *conf, pkg_t *pkg);
68 static int install_data_files(opkg_conf_t *conf, pkg_t *pkg);
69 static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg);
70
71 static int cleanup_temporary_files(opkg_conf_t *conf, pkg_t *pkg);
72
73 static int user_prefers_old_conffile(const char *file, const char *backup);
74
75 static char *backup_filename_alloc(const char *file_name);
76 static int backup_make_backup(opkg_conf_t *conf, const char *file_name);
77 static int backup_exists_for(const char *file_name);
78 static int backup_remove(const char *file_name);
79
80
81 int opkg_install_from_file(opkg_conf_t *conf, const char *filename)
82 {
83      int err, cmp;
84      pkg_t *pkg, *old;
85      char *old_version, *new_version;
86
87      pkg = pkg_new();
88      if (pkg == NULL) {
89           return ENOMEM;
90      }
91
92      err = pkg_init_from_file(pkg, filename);
93      if (err) {
94           return err;
95      }
96
97      if (!pkg->architecture) {
98           opkg_message(conf, OPKG_ERROR, "Package %s has no Architecture defined.\n", pkg->name);
99           return -EINVAL;
100      }
101
102      /* XXX: CLEANUP: hash_insert_pkg has a nasty side effect of possibly
103         freeing the pkg that we pass in. It might be nice to clean this up
104         if possible.  */
105      pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf);
106      old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
107
108      pkg->local_filename = strdup(filename);
109
110      if (old) {
111           old_version = pkg_version_str_alloc(old);
112           new_version = pkg_version_str_alloc(pkg);
113
114           cmp = pkg_compare_versions(old, pkg);
115           if ( (conf->force_downgrade==1) && (cmp > 0) ){     /* We've been asked to allow downgrade  and version is precedent */
116              cmp = -1 ;                                       /* then we force opkg to downgrade */ 
117                                                               /* We need to use a value < 0 because in the 0 case we are asking to */
118                                                               /* reinstall, and some check could fail asking the "force-reinstall" option */
119           } 
120           if (cmp > 0) {
121                  opkg_message(conf, OPKG_NOTICE,
122                               "Not downgrading package %s on %s from %s to %s.\n",
123                               old->name, old->dest->name, old_version, new_version);
124                  pkg->state_want = SW_DEINSTALL;
125                  pkg->state_flag |= SF_OBSOLETE;
126                  free(old_version);
127                  free(new_version);
128                  return 0;
129           } else {
130                free(old_version);
131                free(new_version);
132           }
133      }
134
135      opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
136      return opkg_install_pkg(conf, pkg,0);
137 }
138
139 opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name)
140 {
141      int cmp, err;
142      pkg_t *old, *new;
143      char *old_version, *new_version;
144
145      opkg_message(conf, OPKG_DEBUG2, " Getting old  from pkg_hash_fetch \n" );
146      old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg_name);
147      if ( old ) 
148         opkg_message(conf, OPKG_DEBUG2, " Old versions from pkg_hash_fetch %s \n",  old->version );
149     
150      opkg_message(conf, OPKG_DEBUG2, " Getting new  from pkg_hash_fetch \n" );
151      new = pkg_hash_fetch_best_installation_candidate_by_name(conf, pkg_name, &err);
152      if ( new ) 
153         opkg_message(conf, OPKG_DEBUG2, " New versions from pkg_hash_fetch %s \n",  new->version );
154
155 /* Pigi Basically here is broken the version stuff.
156    What's happening is that nothing provide the version to differents 
157    functions, so the returned struct is always the latest.
158    That's why the install by name don't work.
159 */
160      opkg_message(conf, OPKG_DEBUG2, " Versions from pkg_hash_fetch in %s ", __FUNCTION__ );
161
162      if ( old ) 
163         opkg_message(conf, OPKG_DEBUG2, " old %s ", old->version );
164      if ( new ) 
165         opkg_message(conf, OPKG_DEBUG2, " new %s ", new->version );
166      opkg_message(conf, OPKG_DEBUG2, " \n");
167
168      if (new == NULL) {
169           if (err)
170             return err;
171           else
172             return OPKG_PKG_HAS_NO_CANDIDATE;
173      }
174
175      new->state_flag |= SF_USER;
176      if (old) {
177           old_version = pkg_version_str_alloc(old);
178           new_version = pkg_version_str_alloc(new);
179
180           cmp = pkg_compare_versions(old, new);
181           if ( (conf->force_downgrade==1) && (cmp > 0) ){     /* We've been asked to allow downgrade  and version is precedent */
182              opkg_message(conf, OPKG_DEBUG, " Forcing downgrade \n");
183              cmp = -1 ;                                       /* then we force opkg to downgrade */ 
184                                                               /* We need to use a value < 0 because in the 0 case we are asking to */
185                                                               /* reinstall, and some check could fail asking the "force-reinstall" option */
186           } 
187           opkg_message(conf, OPKG_DEBUG, 
188                        "Comparing visible versions of pkg %s:"
189                        "\n\t%s is installed "
190                        "\n\t%s is available "
191                        "\n\t%d was comparison result\n",
192                        pkg_name, old_version, new_version, cmp);
193           if (cmp == 0 && !conf->force_reinstall) {
194                opkg_message(conf, OPKG_NOTICE,
195                             "Package %s (%s) installed in %s is up to date.\n",
196                             old->name, old_version, old->dest->name);
197                free(old_version);
198                free(new_version);
199                return 0;
200           } else if (cmp > 0) {
201                opkg_message(conf, OPKG_NOTICE,
202                             "Not downgrading package %s on %s from %s to %s.\n",
203                             old->name, old->dest->name, old_version, new_version);
204                free(old_version);
205                free(new_version);
206                return 0;
207           } else if (cmp < 0) {
208                new->dest = old->dest;
209                old->state_want = SW_DEINSTALL;    /* Here probably the problem for bug 1277 */
210           }
211      }
212
213      /* XXX: CLEANUP: The error code of opkg_install_by_name is really
214         supposed to be an opkg_error_t, but opkg_install_pkg could
215         return any kind of integer, (might be errno from a syscall,
216         etc.). This is a real mess and will need to be cleaned up if
217         anyone ever wants to make a nice libopkg. */
218
219      opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
220      return opkg_install_pkg(conf, new,0);
221 }
222
223 opkg_error_t opkg_install_multi_by_name(opkg_conf_t *conf, const char *pkg_name)
224 {
225      abstract_pkg_vec_t *providers = pkg_hash_fetch_all_installation_candidates (&conf->pkg_hash, pkg_name);
226      int i;
227      opkg_error_t err;
228      abstract_pkg_t *ppkg ;
229
230      if (providers == NULL)
231           return OPKG_PKG_HAS_NO_CANDIDATE;
232
233      for (i = 0; i < providers->len; i++) {
234           ppkg = abstract_pkg_vec_get(providers, i);
235           opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_by_name %d \n",__FUNCTION__, i);
236           err = opkg_install_by_name(conf, ppkg->name);
237           if (err)
238                return err;
239 /* XXX Maybe ppkg should be freed ? */
240      }
241      return 0;
242 }
243
244 /*
245  * Walk dependence graph starting with pkg, collect packages to be
246  * installed into pkgs_needed, in dependence order.
247  */
248 int pkg_mark_dependencies_for_installation(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *pkgs_needed)
249 {
250      int i, err;
251      pkg_vec_t *depends = pkg_vec_alloc();
252      char **unresolved = NULL;
253      int ndepends;
254
255      ndepends = pkg_hash_fetch_unsatisfied_dependencies(conf, 
256                                                         pkg, depends, 
257                                                         &unresolved);
258
259      if (unresolved) {
260           opkg_message(conf, OPKG_ERROR,
261                        "%s: Cannot satisfy the following dependencies for %s:\n\t",
262                        conf->force_depends ? "Warning" : "ERROR", pkg->name);
263           while (*unresolved) {
264                opkg_message(conf, OPKG_ERROR, " %s", *unresolved);
265                unresolved++;
266           }
267           opkg_message(conf, OPKG_ERROR, "\n");
268           if (! conf->force_depends) {
269                opkg_message(conf, OPKG_INFO,
270                             "This could mean that your package list is out of date or that the packages\n"
271                             "mentioned above do not yet exist (try 'opkg update'). To proceed in spite\n"
272                             "of this problem try again with the '-force-depends' option.\n");
273                pkg_vec_free(depends);
274                return OPKG_PKG_DEPS_UNSATISFIED;
275           }
276      }
277
278      if (ndepends <= 0) {
279           pkg_vec_free(depends);
280           return 0;
281      }
282
283      for (i = 0; i < depends->len; i++) {
284           pkg_t *dep = depends->pkgs[i];
285           /* The package was uninstalled when we started, but another
286              dep earlier in this loop may have depended on it and pulled
287              it in, so check first. */
288           if ((dep->state_status != SS_INSTALLED)
289               && (dep->state_status != SS_UNPACKED)
290               && (dep->state_want != SW_INSTALL)) {
291
292                /* Mark packages as to-be-installed */
293                dep->state_want = SW_INSTALL;
294
295                /* Dependencies should be installed the same place as pkg */
296                if (dep->dest == NULL) {
297                     dep->dest = pkg->dest;
298                }
299
300                err = pkg_mark_dependencies_for_installation(conf, dep, pkgs_needed);
301                if (err) {
302                     pkg_vec_free(depends);
303                     return err;
304                }
305           }
306      }
307      if (pkgs_needed)
308           pkg_vec_insert(pkgs_needed, pkg);
309
310      pkg_vec_free(depends);
311
312      return 0;
313 }
314
315 int satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg)
316 {
317      int i, err;
318      pkg_vec_t *depends = pkg_vec_alloc();
319      pkg_t *dep;
320      char **unresolved = NULL;
321      int ndepends;
322
323      ndepends = pkg_hash_fetch_unsatisfied_dependencies(conf, 
324                                                         pkg, depends, 
325                                                         &unresolved);
326
327      if (unresolved) {
328           opkg_message(conf, OPKG_ERROR,
329                        "%s: Cannot satisfy the following dependencies for %s:\n\t",
330                        conf->force_depends ? "Warning" : "ERROR", pkg->name);
331           while (*unresolved) {
332                opkg_message(conf, OPKG_ERROR, " %s", *unresolved);
333                unresolved++;
334           }
335           opkg_message(conf, OPKG_ERROR, "\n");
336           if (! conf->force_depends) {
337                opkg_message(conf, OPKG_INFO,
338                             "This could mean that your package list is out of date or that the packages\n"
339                             "mentioned above do not yet exist (try 'opkg update'). To proceed in spite\n"
340                             "of this problem try again with the '-force-depends' option.\n");
341                pkg_vec_free(depends);
342                return OPKG_PKG_DEPS_UNSATISFIED;
343           }
344      }
345
346      if (ndepends <= 0) {
347           pkg_vec_free(depends);
348           return 0;
349      }
350
351      /* Mark packages as to-be-installed */
352      for (i=0; i < depends->len; i++) {
353           /* Dependencies should be installed the same place as pkg */
354           if (depends->pkgs[i]->dest == NULL) {
355                depends->pkgs[i]->dest = pkg->dest;
356           }
357           depends->pkgs[i]->state_want = SW_INSTALL;
358      }
359
360      for (i = 0; i < depends->len; i++) {
361           dep = depends->pkgs[i];
362           /* The package was uninstalled when we started, but another
363              dep earlier in this loop may have depended on it and pulled
364              it in, so check first. */
365           if ((dep->state_status != SS_INSTALLED)
366               && (dep->state_status != SS_UNPACKED)) {
367                opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
368                err = opkg_install_pkg(conf, dep,0);
369                /* mark this package as having been automatically installed to
370                 * satisfy a dependancy */
371                dep->auto_installed = 1;
372                if (err) {
373                     pkg_vec_free(depends);
374                     return err;
375                }
376           }
377      }
378
379      pkg_vec_free(depends);
380
381      return 0;
382 }
383
384
385 /* check all packages have their dependences satisfied, e.g., in case an upgraded package split */ 
386 int opkg_satisfy_all_dependences(opkg_conf_t *conf)
387 {
388      if (conf->nodeps == 0) {
389           int i;
390           pkg_vec_t *installed = pkg_vec_alloc();
391           pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
392           for (i = 0; i < installed->len; i++) {
393                pkg_t *pkg = installed->pkgs[i];
394                satisfy_dependencies_for(conf, pkg);
395           }
396           pkg_vec_free(installed);
397      }
398      return 0;
399 }
400
401
402 static int check_conflicts_for(opkg_conf_t *conf, pkg_t *pkg)
403 {
404      int i;
405      pkg_vec_t *conflicts = NULL;
406      int level;
407      const char *prefix;
408      if (conf->force_depends) {
409           level = OPKG_NOTICE;
410           prefix = "Warning";
411      } else {
412           level = OPKG_ERROR;
413           prefix = "ERROR";
414      }
415
416      if (!conf->force_depends)
417           conflicts = (pkg_vec_t *)pkg_hash_fetch_conflicts(&conf->pkg_hash, pkg);
418
419      if (conflicts) {
420           opkg_message(conf, level,
421                        "%s: The following packages conflict with %s:\n\t", prefix, pkg->name);
422           i = 0;
423           while (i < conflicts->len)
424                opkg_message(conf, level, " %s", conflicts->pkgs[i++]->name);
425           opkg_message(conf, level, "\n");
426           pkg_vec_free(conflicts);
427           return OPKG_PKG_DEPS_UNSATISFIED;
428      }
429      return 0;
430 }
431
432 static int update_file_ownership(opkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_pkg)
433 {
434      str_list_t *new_list = pkg_get_installed_files(new_pkg);
435      str_list_elt_t *iter;
436
437      for (iter = str_list_first(new_list); iter; iter = str_list_next(new_list, iter)) {
438           char *new_file = (char *)iter->data;
439           pkg_t *owner = file_hash_get_file_owner(conf, new_file);
440           if (!new_file)
441                opkg_message(conf, OPKG_ERROR, "Null new_file for new_pkg=%s\n", new_pkg->name);
442           if (!owner || (owner == old_pkg))
443                file_hash_set_file_owner(conf, new_file, new_pkg);
444      }
445      if (old_pkg) {
446           str_list_t *old_list = pkg_get_installed_files(old_pkg);
447           for (iter = str_list_first(old_list); iter; iter = str_list_next(old_list, iter)) {
448                char *old_file = (char *)iter->data;
449                pkg_t *owner = file_hash_get_file_owner(conf, old_file);
450                if (owner == old_pkg) {
451                     /* obsolete */
452                     hash_table_insert(&conf->obs_file_hash, old_file, old_pkg);
453                }
454           }
455           pkg_free_installed_files(old_pkg);
456      }
457      pkg_free_installed_files(new_pkg);
458      return 0;
459 }
460
461 static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg)
462 {
463     /* XXX: FEATURE: Anything else needed here? Maybe a check on free space? */
464
465     /* sma 6.20.02:  yup; here's the first bit */
466     /* 
467      * XXX: BUG easy for cworth
468      * 1) please point the call below to the correct current root destination
469      * 2) we need to resolve how to check the required space for a pending pkg, 
470      *    my diddling with the .opk file size below isn't going to cut it.
471      * 3) return a proper error code instead of 1
472      */
473      int comp_size, blocks_available;
474     
475      if (!conf->force_space && pkg->installed_size != NULL) {
476           blocks_available = get_available_blocks(conf->default_dest->root_dir);
477
478           comp_size = strtoul(pkg->installed_size, NULL, 0);
479           /* round up a blocks count without doing fancy-but-slow casting jazz */ 
480           comp_size = (int)((comp_size + 1023) / 1024);
481
482           if (comp_size >= blocks_available) {
483                opkg_message(conf, OPKG_ERROR,
484                             "Only have %d available blocks on filesystem %s, pkg %s needs %d\n", 
485                             blocks_available, conf->default_dest->root_dir, pkg->name, comp_size);
486                return ENOSPC;
487           }
488      }
489      return 0;
490 }
491
492 static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg)
493 {
494      int err;
495      char *conffiles_file_name;
496      char *root_dir;
497      FILE *conffiles_file;
498
499      sprintf_alloc(&pkg->tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir, pkg->name);
500
501      pkg->tmp_unpack_dir = mkdtemp(pkg->tmp_unpack_dir);
502      if (pkg->tmp_unpack_dir == NULL) {
503           opkg_message(conf, OPKG_ERROR,
504                        "%s: Failed to create temporary directory '%s': %s\n",
505                        __FUNCTION__, pkg->tmp_unpack_dir, strerror(errno));
506           return errno;
507      }
508
509      err = pkg_extract_control_files_to_dir(pkg, pkg->tmp_unpack_dir);
510      if (err) {
511           return err;
512      }
513
514      /* XXX: CLEANUP: There might be a cleaner place to read in the
515         conffiles. Seems like I should be able to get everything to go
516         through pkg_init_from_file. If so, maybe it would make sense to
517         move all of unpack_pkg_control_files to that function. */
518
519      /* Don't need to re-read conffiles if we already have it */
520      if (!nv_pair_list_empty(&pkg->conffiles)) {
521           return 0;
522      }
523
524      sprintf_alloc(&conffiles_file_name, "%s/conffiles", pkg->tmp_unpack_dir);
525      if (! file_exists(conffiles_file_name)) {
526           free(conffiles_file_name);
527           return 0;
528      }
529     
530      conffiles_file = fopen(conffiles_file_name, "r");
531      if (conffiles_file == NULL) {
532           fprintf(stderr, "%s: failed to open %s: %s\n",
533                   __FUNCTION__, conffiles_file_name, strerror(errno));
534           free(conffiles_file_name);
535           return errno;
536      }
537      free(conffiles_file_name);
538
539      while (1) {
540           char *cf_name;
541           char *cf_name_in_dest;
542
543           cf_name = file_read_line_alloc(conffiles_file);
544           if (cf_name == NULL) {
545                break;
546           }
547           str_chomp(cf_name);
548           if (cf_name[0] == '\0') {
549                continue;
550           }
551
552           /* Prepend dest->root_dir to conffile name.
553              Take pains to avoid multiple slashes. */
554           root_dir = pkg->dest->root_dir;
555           if (conf->offline_root)
556                /* skip the offline_root prefix */
557                root_dir = pkg->dest->root_dir + strlen(conf->offline_root);
558           sprintf_alloc(&cf_name_in_dest, "%s%s", root_dir,
559                         cf_name[0] == '/' ? (cf_name + 1) : cf_name);
560
561           /* Can't get an md5sum now, (file isn't extracted yet).
562              We'll wait until resolve_conffiles */
563           conffile_list_append(&pkg->conffiles, cf_name_in_dest, NULL);
564
565           free(cf_name);
566           free(cf_name_in_dest);
567      }
568
569      fclose(conffiles_file);
570
571      return 0;
572 }
573
574 static int pkg_remove_orphan_dependent(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) 
575 {
576     int i, j, found;
577     char *buf, *d_str;
578     pkg_t *p;
579     if (!old_pkg) 
580         return 0;
581     if (!pkg) {
582         fprintf(stderr, "pkg shall not be NULL here.  please send to the bugzilla!! [%s %d]\n", __FILE__, __LINE__);
583         return -1;
584     }
585     if (old_pkg->depends_count == 0) 
586         return 0;
587     for (i=0;i<old_pkg->depends_count;i++) {
588         found = 0;
589         for (j=0;j<pkg->depends_count;j++) {
590             if (!strcmp(old_pkg->depends_str[i], pkg->depends_str[j])) {
591                 found = 1;
592                 break;
593             }
594         }
595         if (found)
596             continue;
597         d_str = old_pkg->depends_str[i];
598         buf = calloc (1, strlen (d_str) + 1);
599         j=0;
600         while (d_str[j] != '\0' && d_str[j] != ' ') {
601             buf[j]=d_str[j];
602             ++j;
603         }
604         buf[j]='\0';
605         buf = realloc (buf, strlen (buf) + 1);
606         p = pkg_hash_fetch_installed_by_name (&conf->pkg_hash, buf);
607         if (!p) {
608             fprintf(stderr, "The pkg %s had been removed!!\n", buf);
609             free(buf);
610             continue;
611         }
612         if (p->auto_installed) {
613             int deps;
614             abstract_pkg_t **dependents;
615             deps = pkg_has_installed_dependents(conf, NULL, p, &dependents);
616             if (deps == 0) {
617                 opkg_message (conf, OPKG_NOTICE,"%s was autoinstalled but is now orphaned, remove it.\n", buf);
618                 opkg_remove_pkg(conf, p, 0);
619             } else 
620                 opkg_message (conf, OPKG_INFO, "%s was autoinstalled and is still required by %d installed packages\n", buf, deps);
621         }
622         free(buf);
623     }
624     return 0;
625 }
626
627 /* returns number of installed replacees */
628 int pkg_get_installed_replacees(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *installed_replacees)
629 {
630      abstract_pkg_t **replaces = pkg->replaces;
631      int replaces_count = pkg->replaces_count;
632      int i, j;
633      for (i = 0; i < replaces_count; i++) {
634           abstract_pkg_t *ab_pkg = replaces[i];
635           pkg_vec_t *pkg_vec = ab_pkg->pkgs;
636           if (pkg_vec) {
637                for (j = 0; j < pkg_vec->len; j++) {
638                     pkg_t *replacee = pkg_vec->pkgs[j];
639                     if (!pkg_conflicts(pkg, replacee))
640                          continue;
641                     if (replacee->state_status == SS_INSTALLED) {
642                          pkg_vec_insert(installed_replacees, replacee);
643                     }
644                }
645           }
646      }
647      return installed_replacees->len;
648 }
649
650 int pkg_remove_installed_replacees(opkg_conf_t *conf, pkg_vec_t *replacees)
651 {
652      int i;
653      int replaces_count = replacees->len;
654      for (i = 0; i < replaces_count; i++) {
655           pkg_t *replacee = replacees->pkgs[i];
656           int err;
657           replacee->state_flag |= SF_REPLACE; /* flag it so remove won't complain */
658           err = opkg_remove_pkg(conf, replacee,0);
659           if (err)
660                return err;
661      }
662      return 0;
663 }
664
665 /* to unwind the removal: make sure they are installed */
666 int pkg_remove_installed_replacees_unwind(opkg_conf_t *conf, pkg_vec_t *replacees)
667 {
668      int i, err;
669      int replaces_count = replacees->len;
670      for (i = 0; i < replaces_count; i++) {
671           pkg_t *replacee = replacees->pkgs[i];
672           if (replacee->state_status != SS_INSTALLED) {
673                opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
674                err = opkg_install_pkg(conf, replacee,0);
675                if (err)
676                     return err;
677           }
678      }
679      return 0;
680 }
681
682 int caught_sigint = 0;
683 static void opkg_install_pkg_sigint_handler(int sig)
684 {
685      caught_sigint = sig;
686 }
687
688 /* compares versions of pkg and old_pkg, returns 0 if OK to proceed with installation of pkg, 1 otherwise */
689 static int opkg_install_check_downgrade(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg, int message)
690 {         
691      if (old_pkg) {
692           char message_out[15];
693           char *old_version = pkg_version_str_alloc(old_pkg);
694           char *new_version = pkg_version_str_alloc(pkg);
695           int cmp = pkg_compare_versions(old_pkg, pkg);
696           int rc = 0;
697
698           memset(message_out,'\x0',15);
699           strncpy (message_out,"Upgrading ",strlen("Upgrading ")); 
700           if ( (conf->force_downgrade==1) && (cmp > 0) ){     /* We've been asked to allow downgrade  and version is precedent */
701              cmp = -1 ;                                       /* then we force opkg to downgrade */ 
702              strncpy (message_out,"Downgrading ",strlen("Downgrading "));         /* We need to use a value < 0 because in the 0 case we are asking to */
703                                                               /* reinstall, and some check could fail asking the "force-reinstall" option */
704           } 
705
706           if (cmp > 0) {
707                opkg_message(conf, OPKG_NOTICE,
708                             "Not downgrading package %s on %s from %s to %s.\n",
709                             old_pkg->name, old_pkg->dest->name, old_version, new_version);
710                rc = 1;
711           } else if (cmp < 0) {
712                opkg_message(conf, OPKG_NOTICE,
713                             "%s%s on %s from %s to %s...\n",
714                             message_out, pkg->name, old_pkg->dest->name, old_version, new_version);
715                pkg->dest = old_pkg->dest;
716                rc = 0;
717           } else /* cmp == 0 */ {
718                if (conf->force_reinstall) {
719                     opkg_message(conf, OPKG_NOTICE,
720                                  "Reinstalling %s (%s) on %s...\n",
721                                  pkg->name, new_version, old_pkg->dest->name);
722                     pkg->dest = old_pkg->dest;
723                     rc = 0;
724                } else {
725                     opkg_message(conf, OPKG_NOTICE,
726                                  "Not installing %s (%s) on %s -- already installed.\n",
727                                  pkg->name, new_version, old_pkg->dest->name);
728                     rc = 1;
729                }
730           } 
731           free(old_version);
732           free(new_version);
733           return rc;
734      } else {
735       char message_out[15] ;
736       memset(message_out,'\x0',15);
737       if ( message ) 
738           strncpy( message_out,"Upgrading ",strlen("Upgrading ") );
739       else
740           strncpy( message_out,"Installing ",strlen("Installing ") );
741           char *version = pkg_version_str_alloc(pkg);
742       
743           opkg_message(conf, OPKG_NOTICE,
744                        "%s%s (%s) to %s...\n", message_out,
745                        pkg->name, version, pkg->dest->name);
746           free(version);
747           return 0;
748      }
749 }
750
751 /**
752  *  @brief Really install a pkg_t 
753  */
754 int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
755 {
756      int err = 0;
757      int message = 0;
758      pkg_t *old_pkg = NULL;
759      pkg_vec_t *replacees;
760      abstract_pkg_t *ab_pkg = NULL;
761      int old_state_flag;
762      char* file_md5;
763      char *pkgid;
764     
765      if ( from_upgrade ) 
766         message = 1;            /* Coming from an upgrade, and should change the output message */
767
768      if (!pkg) {
769           opkg_message(conf, OPKG_ERROR,
770                        "INTERNAL ERROR: null pkg passed to opkg_install_pkg\n");
771           return OPKG_INSTALL_ERR_INTERNAL;
772      }
773
774      opkg_message(conf, OPKG_DEBUG2, "Function: %s calling pkg_arch_supported %s \n", __FUNCTION__, __FUNCTION__);
775
776      if (!pkg_arch_supported(conf, pkg)) {
777           opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
778                        pkg->architecture, pkg->name);
779           return OPKG_INSTALL_ERR_INTERNAL;
780      }
781      if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) {
782           err = satisfy_dependencies_for(conf, pkg);
783           if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
784
785           opkg_message(conf, OPKG_NOTICE,
786                        "Package %s is already installed in %s.\n", 
787                        pkg->name, pkg->dest->name);
788           return 0;
789      }
790
791      if (pkg->dest == NULL) {
792           pkg->dest = conf->default_dest;
793      }
794
795      old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
796
797      err = opkg_install_check_downgrade(conf, pkg, old_pkg, message);
798      if (err) { return OPKG_INSTALL_ERR_NO_DOWNGRADE; }
799
800      pkg->state_want = SW_INSTALL;
801      if (old_pkg){                          
802          old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependences */
803      }
804
805
806      /* Abhaya: conflicts check */
807      err = check_conflicts_for(conf, pkg);
808      if (err) { return OPKG_INSTALL_ERR_CONFLICTS; }
809     
810      /* this setup is to remove the upgrade scenario in the end when
811         installing pkg A, A deps B & B deps on A. So both B and A are
812         installed. Then A's installation is started resulting in an
813         uncecessary upgrade */ 
814      if (pkg->state_status == SS_INSTALLED
815          && conf->force_reinstall == 0) return 0;
816     
817      err = verify_pkg_installable(conf, pkg);
818      if (err) { return OPKG_INSTALL_ERR_NO_SPACE; }
819
820      if (pkg->local_filename == NULL) {
821           err = opkg_download_pkg(conf, pkg, conf->tmp_dir);
822           if (err) {
823                opkg_message(conf, OPKG_ERROR,
824                             "Failed to download %s. Perhaps you need to run 'opkg update'?\n",
825                             pkg->name);
826                return OPKG_INSTALL_ERR_DOWNLOAD;
827           }
828      }
829
830      /* check that the repository is valid */
831      #if HAVE_GPGME
832      char *list_file_name, *sig_file_name, *lists_dir;
833
834      /* check to ensure the package has come from a repository */
835      if (pkg->src)
836      {
837        sprintf_alloc (&lists_dir, "%s",
838                      (conf->restrict_to_default_dest)
839                       ? conf->default_dest->lists_dir
840                       : conf->lists_dir);
841        sprintf_alloc (&list_file_name, "%s/%s", lists_dir, pkg->src->name);
842        sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, pkg->src->name);
843
844        if (file_exists (sig_file_name))
845        {
846          if (opkg_verify_file (conf, list_file_name, sig_file_name))
847            return OPKG_INSTALL_ERR_SIGNATURE;
848        }
849
850        free (lists_dir);
851        free (list_file_name);
852        free (sig_file_name);
853      }
854      #endif
855
856      /* Check for md5 values */
857      if (pkg->md5sum)
858      {
859          file_md5 = file_md5sum_alloc(pkg->local_filename);
860          if (strcmp(file_md5, pkg->md5sum))
861          {
862               opkg_message(conf, OPKG_ERROR,
863                            "Package %s md5sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
864                            pkg->name);
865               free(file_md5);
866               return OPKG_INSTALL_ERR_MD5;
867          }
868          free(file_md5);
869      }
870
871      if (pkg->tmp_unpack_dir == NULL) {
872           unpack_pkg_control_files(conf, pkg);
873      }
874
875      /* We should update the filelist here, so that upgrades of packages that split will not fail. -Jamey 27-MAR-03 */
876 /* Pigi: check if it will pass from here when replacing. It seems to fail */
877 /* That's rather strange that files don't change owner. Investigate !!!!!!*/
878      err = update_file_ownership(conf, pkg, old_pkg);
879      if (err) { return OPKG_ERR_UNKNOWN; }
880
881      if (conf->nodeps == 0) {
882           err = satisfy_dependencies_for(conf, pkg);
883           if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
884      }
885
886      replacees = pkg_vec_alloc();
887      pkg_get_installed_replacees(conf, pkg, replacees);
888
889      sprintf_alloc (&pkgid, "%s;%s;%s;", pkg->name, pkg->version, pkg->architecture);
890      opkg_set_current_state (conf, OPKG_STATE_INSTALLING_PKG, pkgid);
891      free (pkgid);
892
893      /* this next section we do with SIGINT blocked to prevent inconsistency between opkg database and filesystem */
894      {
895           sigset_t newset, oldset;
896           sighandler_t old_handler = NULL;
897           int use_signal = 0;
898           caught_sigint = 0;
899           if (use_signal) {
900                old_handler = signal(SIGINT, opkg_install_pkg_sigint_handler);
901           } else {
902                sigemptyset(&newset);
903                sigaddset(&newset, SIGINT);
904                sigprocmask(SIG_BLOCK, &newset, &oldset);
905           }
906
907           opkg_state_changed++;
908           pkg->state_flag |= SF_FILELIST_CHANGED;
909
910           pkg_remove_orphan_dependent(conf, pkg, old_pkg);
911
912           /* XXX: BUG: we really should treat replacement more like an upgrade
913            *      Instead, we're going to remove the replacees 
914            */
915           err = pkg_remove_installed_replacees(conf, replacees);
916           if (err) goto UNWIND_REMOVE_INSTALLED_REPLACEES;
917
918           err = prerm_upgrade_old_pkg(conf, pkg, old_pkg);
919           if (err) goto UNWIND_PRERM_UPGRADE_OLD_PKG;
920
921           err = prerm_deconfigure_conflictors(conf, pkg, replacees);
922           if (err) goto UNWIND_PRERM_DECONFIGURE_CONFLICTORS;
923
924           err = preinst_configure(conf, pkg, old_pkg);
925           if (err) goto UNWIND_PREINST_CONFIGURE;
926
927           err = backup_modified_conffiles(conf, pkg, old_pkg);
928           if (err) goto UNWIND_BACKUP_MODIFIED_CONFFILES;
929
930           err = check_data_file_clashes(conf, pkg, old_pkg);
931           if (err) goto UNWIND_CHECK_DATA_FILE_CLASHES;
932
933           err = postrm_upgrade_old_pkg(conf, pkg, old_pkg);
934           if (err) goto UNWIND_POSTRM_UPGRADE_OLD_PKG;
935
936           if (conf->noaction) return 0;
937
938           /* point of no return: no unwinding after this */
939           if (old_pkg && !conf->force_reinstall) {
940                old_pkg->state_want = SW_DEINSTALL;
941
942                if (old_pkg->state_flag & SF_NOPRUNE) {
943                     opkg_message(conf, OPKG_INFO,
944                                  "  not removing obsolesced files because package marked noprune\n");
945                } else {
946                     opkg_message(conf, OPKG_INFO,
947                                  "  removing obsolesced files\n");
948                     remove_obsolesced_files(conf, pkg, old_pkg);
949                }
950                /* removing files from old package, to avoid ghost files */ 
951                remove_data_files_and_list(conf, old_pkg);
952 /* Pigi : It should be better to remove also maintainer and postrem scripts here, just in case*/
953                remove_maintainer_scripts_except_postrm(conf, old_pkg);
954                remove_postrm(conf, old_pkg);
955 /* Pigi */
956
957           }
958
959
960           opkg_message(conf, OPKG_INFO,
961                        "  installing maintainer scripts\n");
962           install_maintainer_scripts(conf, pkg, old_pkg);
963
964           /* the following just returns 0 */
965           remove_disappeared(conf, pkg);
966
967           opkg_message(conf, OPKG_INFO,
968                        "  installing data files\n");
969           install_data_files(conf, pkg);
970
971 /* read comments from function for detail but I will execute this here as all other tests are ok.*/
972           err = check_data_file_clashes_change(conf, pkg, old_pkg);
973
974           opkg_message(conf, OPKG_INFO,
975                        "  resolving conf files\n");
976           resolve_conffiles(conf, pkg);
977
978           pkg->state_status = SS_UNPACKED;
979           old_state_flag = pkg->state_flag;
980           pkg->state_flag &= ~SF_PREFER;
981           opkg_message(conf, OPKG_DEBUG, "   pkg=%s old_state_flag=%x state_flag=%x\n", pkg->name, old_state_flag, pkg->state_flag);
982
983           if (old_pkg && !conf->force_reinstall) {
984                old_pkg->state_status = SS_NOT_INSTALLED;
985           }
986
987           time(&pkg->installed_time);
988
989           opkg_message(conf, OPKG_INFO,
990                        "  cleanup temp files\n");
991           cleanup_temporary_files(conf, pkg);
992
993           ab_pkg = pkg->parent;
994           if (ab_pkg)
995                ab_pkg->state_status = pkg->state_status;
996
997           opkg_message(conf, OPKG_INFO, "Done.\n");
998
999           if (use_signal)
1000                signal(SIGINT, old_handler);
1001           else
1002                sigprocmask(SIG_UNBLOCK, &newset, &oldset);
1003           pkg_vec_free (replacees);
1004           return 0;
1005      
1006
1007      UNWIND_POSTRM_UPGRADE_OLD_PKG:
1008           postrm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
1009      UNWIND_CHECK_DATA_FILE_CLASHES:
1010           check_data_file_clashes_unwind(conf, pkg, old_pkg);
1011      UNWIND_BACKUP_MODIFIED_CONFFILES:
1012           backup_modified_conffiles_unwind(conf, pkg, old_pkg);
1013      UNWIND_PREINST_CONFIGURE:
1014           preinst_configure_unwind(conf, pkg, old_pkg);
1015      UNWIND_PRERM_DECONFIGURE_CONFLICTORS:
1016           prerm_deconfigure_conflictors_unwind(conf, pkg, replacees);
1017      UNWIND_PRERM_UPGRADE_OLD_PKG:
1018           prerm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
1019      UNWIND_REMOVE_INSTALLED_REPLACEES:
1020           pkg_remove_installed_replacees_unwind(conf, replacees);
1021
1022           opkg_message(conf, OPKG_INFO,
1023                        "  cleanup temp files\n");
1024           cleanup_temporary_files(conf, pkg);
1025
1026           opkg_message(conf, OPKG_INFO,
1027                        "Failed.\n");
1028           if (use_signal)
1029                signal(SIGINT, old_handler);
1030           else
1031                sigprocmask(SIG_UNBLOCK, &newset, &oldset);
1032
1033           pkg_vec_free (replacees);
1034           return OPKG_ERR_UNKNOWN;
1035      }
1036      opkg_set_current_state (conf, OPKG_STATE_NONE, NULL);
1037 }
1038
1039 static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1040 {
1041      /* DPKG_INCOMPATIBILITY:
1042         dpkg does some things here that we don't do yet. Do we care?
1043         
1044         1. If a version of the package is already installed, call
1045            old-prerm upgrade new-version
1046         2. If the script runs but exits with a non-zero exit status
1047            new-prerm failed-upgrade old-version
1048            Error unwind, for both the above cases:
1049            old-postinst abort-upgrade new-version
1050      */
1051      return 0;
1052 }
1053
1054 static int prerm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1055 {
1056      /* DPKG_INCOMPATIBILITY:
1057         dpkg does some things here that we don't do yet. Do we care?
1058         (See prerm_upgrade_old_package for details)
1059      */
1060      return 0;
1061 }
1062
1063 static int prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors)
1064 {
1065      /* DPKG_INCOMPATIBILITY:
1066         dpkg does some things here that we don't do yet. Do we care?
1067         2. If a 'conflicting' package is being removed at the same time:
1068                 1. If any packages depended on that conflicting package and
1069                    --auto-deconfigure is specified, call, for each such package:
1070                    deconfigured's-prerm deconfigure \
1071                    in-favour package-being-installed version \
1072                    removing conflicting-package version
1073                 Error unwind:
1074                    deconfigured's-postinst abort-deconfigure \
1075                    in-favour package-being-installed-but-failed version \
1076                    removing conflicting-package version
1077
1078                    The deconfigured packages are marked as requiring
1079                    configuration, so that if --install is used they will be
1080                    configured again if possible.
1081                 2. To prepare for removal of the conflicting package, call:
1082                    conflictor's-prerm remove in-favour package new-version
1083                 Error unwind:
1084                    conflictor's-postinst abort-remove in-favour package new-version
1085      */
1086      return 0;
1087 }
1088
1089 static int prerm_deconfigure_conflictors_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors)
1090 {
1091      /* DPKG_INCOMPATIBILITY: dpkg does some things here that we don't
1092         do yet. Do we care?  (See prerm_deconfigure_conflictors for
1093         details) */
1094      return 0;
1095 }
1096
1097 static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1098 {
1099      int err;
1100      char *preinst_args;
1101
1102      if (old_pkg) {
1103           char *old_version = pkg_version_str_alloc(old_pkg);
1104           sprintf_alloc(&preinst_args, "upgrade %s", old_version);
1105           free(old_version);
1106      } else if (pkg->state_status == SS_CONFIG_FILES) {
1107           char *pkg_version = pkg_version_str_alloc(pkg);
1108           sprintf_alloc(&preinst_args, "install %s", pkg_version);
1109           free(pkg_version);
1110      } else {
1111           preinst_args = strdup("install");
1112      }
1113
1114      err = pkg_run_script(conf, pkg, "preinst", preinst_args);
1115      if (err) {
1116           opkg_message(conf, OPKG_ERROR,
1117                        "Aborting installation of %s\n", pkg->name);
1118           return 1;
1119      }
1120
1121      free(preinst_args);
1122
1123      return 0;
1124 }
1125
1126 static int preinst_configure_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1127 {
1128      /* DPKG_INCOMPATIBILITY:
1129         dpkg does the following error unwind, should we?
1130         pkg->postrm abort-upgrade old-version
1131         OR pkg->postrm abort-install old-version
1132         OR pkg->postrm abort-install
1133      */
1134      return 0;
1135 }
1136
1137 static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1138 {
1139      int err;
1140      conffile_list_elt_t *iter;
1141      conffile_t *cf;
1142
1143      if (conf->noaction) return 0;
1144
1145      /* Backup all modified conffiles */
1146      if (old_pkg) {
1147           for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; iter = nv_pair_list_next(&old_pkg->conffiles, iter)) {
1148                char *cf_name;
1149                
1150                cf = iter->data;
1151                cf_name = root_filename_alloc(conf, cf->name);
1152
1153                /* Don't worry if the conffile is just plain gone */
1154                if (file_exists(cf_name) && conffile_has_been_modified(conf, cf)) {
1155                     err = backup_make_backup(conf, cf_name);
1156                     if (err) {
1157                          return err;
1158                     }
1159                }
1160                free(cf_name);
1161           }
1162      }
1163
1164      /* Backup all conffiles that were not conffiles in old_pkg */
1165      for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1166           char *cf_name;
1167           cf = (conffile_t *)iter->data;
1168           cf_name = root_filename_alloc(conf, cf->name);
1169           /* Ignore if this was a conffile in old_pkg as well */
1170           if (pkg_get_conffile(old_pkg, cf->name)) {
1171                continue;
1172           }
1173
1174           if (file_exists(cf_name) && (! backup_exists_for(cf_name))) {
1175                err = backup_make_backup(conf, cf_name);
1176                if (err) {
1177                     return err;
1178                }
1179           }
1180           free(cf_name);
1181      }
1182
1183      return 0;
1184 }
1185
1186 static int backup_modified_conffiles_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1187 {
1188      conffile_list_elt_t *iter;
1189
1190      if (old_pkg) {
1191           for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; iter = nv_pair_list_next(&old_pkg->conffiles, iter)) {
1192                backup_remove(((nv_pair_t *)iter->data)->name);
1193           }
1194      }
1195
1196      for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1197           backup_remove(((nv_pair_t *)iter->data)->name);
1198      }
1199
1200      return 0;
1201 }
1202
1203
1204 static int check_data_file_clashes(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1205 {
1206      /* DPKG_INCOMPATIBILITY:
1207         opkg takes a slightly different approach than dpkg at this
1208         point.  dpkg installs each file in the new package while
1209         creating a backup for any file that is replaced, (so that it
1210         can unwind if necessary).  To avoid complexity and redundant
1211         storage, opkg doesn't do any installation until later, (at the
1212         point at which dpkg removes the backups.
1213         
1214         But, we do have to check for data file clashes, since after
1215         installing a package with a file clash, removing either of the
1216         packages involved in the clash has the potential to break the
1217         other package.
1218      */
1219      str_list_t *files_list;
1220      str_list_elt_t *iter;
1221
1222      int clashes = 0;
1223
1224      files_list = pkg_get_installed_files(pkg);
1225      for (iter = str_list_first(files_list); iter; iter = str_list_next(files_list, iter)) {
1226           char *root_filename;
1227           char *filename = (char *) iter->data;
1228           root_filename = root_filename_alloc(conf, filename);
1229           if (file_exists(root_filename) && (! file_is_dir(root_filename))) {
1230                pkg_t *owner;
1231                pkg_t *obs;
1232                /* Pre-existing conffiles are OK */
1233                /* @@@@ should have way to check that it is a conffile -Jamey */
1234                if (backup_exists_for(root_filename)) {
1235                     continue;
1236                }
1237
1238                /* Pre-existing files are OK if force-overwrite was asserted. */ 
1239                if (conf->force_overwrite) {
1240                     /* but we need to change who owns this file */
1241                     file_hash_set_file_owner(conf, filename, pkg);
1242                     continue;
1243                }
1244
1245                owner = file_hash_get_file_owner(conf, filename);
1246
1247                /* Pre-existing files are OK if owned by the pkg being upgraded. */
1248                if (owner && old_pkg) {
1249                     if (strcmp(owner->name, old_pkg->name) == 0) {
1250                          continue;
1251                     }
1252                }
1253
1254                /* Pre-existing files are OK if owned by a package replaced by new pkg. */
1255                if (owner) {
1256                     opkg_message(conf, OPKG_DEBUG2, "Checking for replaces for %s in package %s\n", filename, owner->name);
1257                     if (pkg_replaces(pkg, owner)) {
1258                          continue;
1259                     }
1260 /* If the file that would be installed is owned by the same package, ( as per a reinstall or similar )
1261    then it's ok to overwrite. */
1262                     if (strcmp(owner->name,pkg->name)==0){
1263                          opkg_message(conf, OPKG_INFO, "Replacing pre-existing file %s owned by package %s\n", filename, owner->name);
1264                          continue;
1265                     }
1266                }
1267
1268                /* Pre-existing files are OK if they are obsolete */
1269                obs = hash_table_get(&conf->obs_file_hash, filename);
1270                if (obs) {
1271                     opkg_message(conf, OPKG_INFO, "Pre-exiting file %s is obsolete.  obs_pkg=%s\n", filename, obs->name);
1272                     continue;
1273                }
1274
1275                /* We have found a clash. */
1276                opkg_message(conf, OPKG_ERROR,
1277                             "Package %s wants to install file %s\n"
1278                             "\tBut that file is already provided by package ",
1279                             pkg->name, filename);
1280                if (owner) {
1281                     opkg_message(conf, OPKG_ERROR,
1282                                  "%s\n", owner->name);
1283                } else {
1284                     opkg_message(conf, OPKG_ERROR,
1285                                  "<no package>\nPlease move this file out of the way and try again.\n");
1286                }
1287                clashes++;
1288           }
1289           free(root_filename);
1290      }
1291      pkg_free_installed_files(pkg);
1292
1293      return clashes;
1294 }
1295
1296 static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1297 {
1298     /* Basically that's the worst hack I could do to be able to change ownership of
1299        file list, but, being that we have no way to unwind the mods, due to structure
1300        of hash table, probably is the quickest hack too, whishing it would not slow-up thing too much.
1301        What we do here is change the ownership of file in hash if a replace ( or similar events
1302        happens )
1303        Only the action that are needed to change name should be considered.
1304        @@@ To change after 1.0 release.
1305      */
1306      str_list_t *files_list;
1307      str_list_elt_t *iter;
1308
1309      int clashes = 0;
1310
1311      files_list = pkg_get_installed_files(pkg);
1312      for (iter = str_list_first(files_list); iter; iter = str_list_next(files_list, iter)) {
1313           char *root_filename;
1314           char *filename = (char *) iter->data;
1315           root_filename = root_filename_alloc(conf, filename);
1316           if (file_exists(root_filename) && (! file_is_dir(root_filename))) {
1317                pkg_t *owner;
1318
1319                if (conf->force_overwrite) {
1320                     /* but we need to change who owns this file */
1321                     file_hash_set_file_owner(conf, filename, pkg);
1322                     continue;
1323                }
1324
1325                owner = file_hash_get_file_owner(conf, filename);
1326
1327                /* Pre-existing files are OK if owned by a package replaced by new pkg. */
1328                if (owner) {
1329                     if (pkg_replaces(pkg, owner)) {
1330 /* It's now time to change the owner of that file. 
1331    It has been "replaced" from the new "Replaces", then I need to inform lists file about that.  */
1332                          opkg_message(conf, OPKG_INFO, "Replacing pre-existing file %s owned by package %s\n", filename, owner->name);
1333                          file_hash_set_file_owner(conf, filename, pkg);
1334                          continue;
1335                     }
1336                }
1337
1338           }
1339           free(root_filename);
1340      }
1341      pkg_free_installed_files(pkg);
1342
1343      return clashes;
1344 }
1345
1346 static int check_data_file_clashes_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1347 {
1348      /* Nothing to do since check_data_file_clashes doesn't change state */
1349      return 0;
1350 }
1351
1352 static int postrm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1353 {
1354      /* DPKG_INCOMPATIBILITY: dpkg does the following here, should we?
1355         1. If the package is being upgraded, call
1356            old-postrm upgrade new-version
1357         2. If this fails, attempt:
1358            new-postrm failed-upgrade old-version
1359         Error unwind, for both cases:
1360            old-preinst abort-upgrade new-version    */
1361      return 0;
1362 }
1363
1364 static int postrm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1365 {
1366      /* DPKG_INCOMPATIBILITY:
1367         dpkg does some things here that we don't do yet. Do we care?
1368         (See postrm_upgrade_old_pkg for details)
1369      */
1370     return 0;
1371 }
1372
1373 static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1374 {
1375      int err;
1376      str_list_t *old_files;
1377      str_list_elt_t *of;
1378      str_list_t *new_files;
1379      str_list_elt_t *nf;
1380      hash_table_t new_files_table;
1381
1382      if (old_pkg == NULL) {
1383           return 0;
1384      }
1385
1386      old_files = pkg_get_installed_files(old_pkg);
1387      new_files = pkg_get_installed_files(pkg);
1388
1389      new_files_table.entries = NULL;
1390      hash_table_init("new_files" , &new_files_table, 20);
1391      for (nf = str_list_first(new_files); nf; nf = str_list_next(new_files, nf)) {
1392          if (nf && nf->data)
1393             hash_table_insert(&new_files_table, nf->data, nf->data);
1394      }
1395
1396      for (of = str_list_first(old_files); of; of = str_list_next(old_files, of)) {
1397           pkg_t *owner;
1398           char *old, *new;
1399           old = (char *)of->data;
1400           new = (char *) hash_table_get (&new_files_table, old);
1401           if (new)
1402                continue;
1403
1404           if (file_is_dir(old)) {
1405                continue;
1406           }
1407           owner = file_hash_get_file_owner(conf, old);
1408           if (owner != old_pkg) {
1409                /* in case obsolete file no longer belongs to old_pkg */
1410                continue;
1411           }
1412  
1413           /* old file is obsolete */
1414           opkg_message(conf, OPKG_INFO,
1415                        "    removing obsolete file %s\n", old);
1416           if (!conf->noaction) {
1417                err = unlink(old);
1418                if (err) {
1419                     opkg_message(conf, OPKG_ERROR, "    Warning: remove %s failed: %s\n", old,
1420                                  strerror(errno));
1421                }
1422           }
1423      }
1424
1425      hash_table_deinit(&new_files_table);
1426      pkg_free_installed_files(old_pkg);
1427      pkg_free_installed_files(pkg);
1428
1429      return 0;
1430 }
1431
1432 static int remove_obsolete_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1433 {
1434      int i;
1435      int err = 0;
1436      char *globpattern;
1437      glob_t globbuf;
1438      if (0) {
1439           if (!pkg->dest) {
1440                opkg_message(conf, OPKG_ERROR, "%s: no dest for package %s\n", __FUNCTION__, pkg->name);
1441                return -1;
1442           }
1443           sprintf_alloc(&globpattern, "%s/%s.*", pkg->dest->info_dir, pkg->name);
1444           err = glob(globpattern, 0, NULL, &globbuf);
1445           free(globpattern);
1446           if (err) {
1447                return err;
1448           }
1449           /* XXXX this should perhaps only remove the ones that are not overwritten in new package.  Jamey 11/11/2003 */
1450           for (i = 0; i < globbuf.gl_pathc; i++) {
1451                opkg_message(conf, OPKG_DEBUG, "Removing control file %s from old_pkg %s\n",
1452                             globbuf.gl_pathv[i], old_pkg->name);
1453                if (!conf->noaction)
1454                     unlink(globbuf.gl_pathv[i]);
1455           }
1456           globfree(&globbuf);
1457      }
1458      return err;
1459 }
1460
1461 static int install_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
1462 {
1463      int ret;
1464      char *prefix;
1465
1466      if (old_pkg)
1467           remove_obsolete_maintainer_scripts(conf, pkg, old_pkg);
1468      sprintf_alloc(&prefix, "%s.", pkg->name);
1469      ret = pkg_extract_control_files_to_dir_with_prefix(pkg,
1470                                                         pkg->dest->info_dir,
1471                                                         prefix);
1472      free(prefix);
1473      return ret;
1474 }
1475
1476 static int remove_disappeared(opkg_conf_t *conf, pkg_t *pkg)
1477 {
1478      /* DPKG_INCOMPATIBILITY:
1479         This is a fairly sophisticated dpkg operation. Shall we
1480         skip it? */
1481      
1482      /* Any packages all of whose files have been overwritten during the
1483         installation, and which aren't required for dependencies, are
1484         considered to have been removed. For each such package
1485         1. disappearer's-postrm disappear overwriter overwriter-version
1486         2. The package's maintainer scripts are removed
1487         3. It is noted in the status database as being in a sane state,
1488            namely not installed (any conffiles it may have are ignored,
1489            rather than being removed by dpkg). Note that disappearing
1490            packages do not have their prerm called, because dpkg doesn't
1491            know in advance that the package is going to vanish.
1492      */
1493      return 0;
1494 }
1495
1496 static int install_data_files(opkg_conf_t *conf, pkg_t *pkg)
1497 {
1498      int err;
1499
1500      /* opkg takes a slightly different approach to data file backups
1501         than dpkg. Rather than removing backups at this point, we
1502         actually do the data file installation now. See comments in
1503         check_data_file_clashes() for more details. */
1504     
1505      opkg_message(conf, OPKG_INFO,
1506                   "    extracting data files to %s\n", pkg->dest->root_dir);
1507      err = pkg_extract_data_files_to_dir(pkg, pkg->dest->root_dir);
1508      if (err) {
1509           return err;
1510      }
1511
1512      /* XXX: BUG or FEATURE : We are actually loosing the Essential flag,
1513         so we can't save ourself from removing important packages
1514         At this point we (should) have extracted the .control file, so it
1515         would be a good idea to reload the data in it, and set the Essential 
1516         state in *pkg. From now on the Essential is back in status file and
1517         we can protect again.
1518         We should operate this way:
1519         fopen the file ( pkg->dest->root_dir/pkg->name.control )
1520         check for "Essential" in it 
1521         set the value in pkg->essential.
1522         This new routine could be useful also for every other flag
1523         Pigi: 16/03/2004 */
1524      set_flags_from_control(conf, pkg) ;
1525      
1526      opkg_message(conf, OPKG_DEBUG, "    Calling pkg_write_filelist from %s\n", __FUNCTION__);
1527      err = pkg_write_filelist(conf, pkg);
1528      if (err)
1529           return err;
1530
1531      /* XXX: FEATURE: opkg should identify any files which existed
1532         before installation and which were overwritten, (see
1533         check_data_file_clashes()). What it must do is remove any such
1534         files from the filelist of the old package which provided the
1535         file. Otherwise, if the old package were removed at some point
1536         it would break the new package. Removing the new package will
1537         also break the old one, but this cannot be helped since the old
1538         package's file has already been deleted. This is the importance
1539         of check_data_file_clashes(), and only allowing opkg to install
1540         a clashing package with a user force. */
1541
1542      return 0;
1543 }
1544
1545 static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg)
1546 {
1547      conffile_list_elt_t *iter;
1548      conffile_t *cf;
1549      char *cf_backup;
1550
1551     char *md5sum;
1552
1553     
1554      if (conf->noaction) return 0;
1555
1556      for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
1557           char *root_filename;
1558           cf = (conffile_t *)iter->data;
1559           root_filename = root_filename_alloc(conf, cf->name);
1560
1561           /* Might need to initialize the md5sum for each conffile */
1562           if (cf->value == NULL) {
1563                cf->value = file_md5sum_alloc(root_filename);
1564           }
1565
1566           if (!file_exists(root_filename)) {
1567                free(root_filename);
1568                continue;
1569           }
1570
1571           cf_backup = backup_filename_alloc(root_filename);
1572
1573
1574           if (file_exists(cf_backup)) {
1575  /* Let's compute md5 to test if files are changed */
1576               md5sum = file_md5sum_alloc(cf_backup);
1577                if (strcmp( cf->value,md5sum) != 0 ) {
1578                   if (conf->force_defaults
1579                       || user_prefers_old_conffile(cf->name, cf_backup) ) {
1580                        rename(cf_backup, root_filename);
1581                   }
1582                }
1583                unlink(cf_backup);
1584                free(md5sum);
1585           }
1586
1587           free(cf_backup);
1588           free(root_filename);
1589      }
1590
1591      return 0;
1592 }
1593
1594 static int user_prefers_old_conffile(const char *file_name, const char *backup)
1595 {
1596      char *response;
1597      const char *short_file_name;
1598
1599      short_file_name = strrchr(file_name, '/');
1600      if (short_file_name) {
1601           short_file_name++;
1602      } else {
1603           short_file_name = file_name;
1604      }
1605
1606      while (1) {
1607           response = get_user_response("    Configuration file '%s'\n"
1608                                        "    ==> File on system created by you or by a script.\n"
1609                                        "    ==> File also in package provided by package maintainer.\n"
1610                                        "       What would you like to do about it ?  Your options are:\n"
1611                                        "        Y or I  : install the package maintainer's version\n"
1612                                        "        N or O  : keep your currently-installed version\n"
1613                                        "          D     : show the differences between the versions (if diff is installed)\n"
1614                                        "     The default action is to keep your current version.\n"
1615                                        "    *** %s (Y/I/N/O/D) [default=N] ? ", file_name, short_file_name);
1616           if (strcmp(response, "y") == 0
1617               || strcmp(response, "i") == 0
1618               || strcmp(response, "yes") == 0) {
1619                free(response);
1620                return 0;
1621           }
1622
1623           if (strcmp(response, "d") == 0) {
1624                char *cmd;
1625
1626                free(response);
1627                /* XXX: BUG rewrite to use exec or busybox's internal diff */
1628                sprintf_alloc(&cmd, "diff -u %s %s", backup, file_name);
1629                xsystem(cmd);
1630                free(cmd);
1631                printf("    [Press ENTER to continue]\n");
1632                response = file_read_line_alloc(stdin);
1633                free(response);
1634                continue;
1635           }
1636
1637           free(response);
1638           return 1;
1639      }
1640 }
1641
1642 /* XXX: CLEANUP: I'd like to move all of the code for
1643    creating/cleaning pkg->tmp_unpack_dir directly into pkg.c. (Then,
1644    it would make sense to cleanup pkg->tmp_unpack_dir directly from
1645    pkg_deinit for example). */
1646 static int cleanup_temporary_files(opkg_conf_t *conf, pkg_t *pkg)
1647 {
1648      DIR *tmp_dir;
1649      struct dirent *dirent;
1650      char *tmp_file;
1651
1652 #ifdef OPKG_DEBUG_NO_TMP_CLEANUP
1653 #error
1654      opkg_message(conf, OPKG_DEBUG,
1655                   "%s: Not cleaning up %s since opkg compiled with OPKG_DEBUG_NO_TMP_CLEANUP\n",
1656                   __FUNCTION__, pkg->tmp_unpack_dir);
1657      return 0;
1658 #endif
1659
1660      if (pkg->tmp_unpack_dir && file_is_dir(pkg->tmp_unpack_dir)) {
1661           tmp_dir = opendir(pkg->tmp_unpack_dir);
1662           if (tmp_dir) {
1663                while (1) {
1664                     dirent = readdir(tmp_dir);
1665                     if (dirent == NULL) {
1666                          break;
1667                     }
1668                     sprintf_alloc(&tmp_file, "%s/%s",
1669                                   pkg->tmp_unpack_dir, dirent->d_name);
1670                     if (! file_is_dir(tmp_file)) {
1671                          unlink(tmp_file);
1672                     }
1673                     free(tmp_file);
1674                }
1675                closedir(tmp_dir);
1676                rmdir(pkg->tmp_unpack_dir);
1677                free(pkg->tmp_unpack_dir);
1678                pkg->tmp_unpack_dir = NULL;
1679           }
1680      }
1681
1682      opkg_message(conf, OPKG_INFO, "cleanup_temporary_files: pkg=%s local_filename=%s tmp_dir=%s\n",
1683                   pkg->name, pkg->local_filename, conf->tmp_dir);
1684      if (pkg->local_filename && strncmp(pkg->local_filename, conf->tmp_dir, strlen(conf->tmp_dir)) == 0) {
1685           unlink(pkg->local_filename);
1686           free(pkg->local_filename);
1687           pkg->local_filename = NULL;
1688      }
1689
1690      return 0;
1691 }
1692
1693 static char *backup_filename_alloc(const char *file_name)
1694 {
1695      char *backup;
1696
1697      sprintf_alloc(&backup, "%s%s", file_name, OPKG_BACKUP_SUFFIX);
1698
1699      return backup;
1700 }
1701
1702 int backup_make_backup(opkg_conf_t *conf, const char *file_name)
1703 {
1704      int err;
1705      char *backup;
1706     
1707      backup = backup_filename_alloc(file_name);
1708      err = file_copy(file_name, backup);
1709      if (err) {
1710           opkg_message(conf, OPKG_ERROR,
1711                        "%s: Failed to copy %s to %s\n",
1712                        __FUNCTION__, file_name, backup);
1713      }
1714
1715      free(backup);
1716
1717      return err;
1718 }
1719
1720 static int backup_exists_for(const char *file_name)
1721 {
1722      int ret;
1723      char *backup;
1724
1725      backup = backup_filename_alloc(file_name);
1726
1727      ret = file_exists(backup);
1728
1729      free(backup);
1730
1731      return ret;
1732 }
1733
1734 static int backup_remove(const char *file_name)
1735 {
1736      char *backup;
1737
1738      backup = backup_filename_alloc(file_name);
1739      unlink(backup);
1740      free(backup);
1741
1742      return 0;
1743 }
1744