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