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