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