ipkg_install.c

来自「this is the pkg installer for linux」· C语言 代码 · 共 1,943 行 · 第 1/5 页

C
1,943
字号
     if (pkg->dest == NULL) {	  pkg->dest = conf->default_dest;     }     old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);     err = ipkg_install_check_downgrade(conf, pkg, old_pkg, message);     if (err) { return err; }     pkg->state_want = SW_INSTALL;     if (old_pkg){                                   old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependences */     }     /* Abhaya: conflicts check */     err = check_conflicts_for(conf, pkg);     if (err) { return err; }         /* this setup is to remove the upgrade scenario in the end when	installing pkg A, A deps B & B deps on A. So both B and A are	installed. Then A's installation is started resulting in an	uncecessary upgrade */      if (pkg->state_status == SS_INSTALLED	 && conf->force_reinstall == 0) return 0;         err = verify_pkg_installable(conf, pkg);     if (err) { return err; }     if (pkg->local_filename == NULL) {	  err = ipkg_download_pkg(conf, pkg, conf->tmp_dir);	  if (err) {	       ipkg_message(conf, IPKG_ERROR,			    "Failed to download %s. Perhaps you need to run 'ipkg update'?\n",			    pkg->name);	       return err;	  }     }/* Check for md5 values */     if (pkg->md5sum)     {         file_md5 = file_md5sum_alloc(pkg->local_filename);         if (strcmp(file_md5, pkg->md5sum))         {              ipkg_message(conf, IPKG_ERROR,                           "Package %s md5sum mismatch. Either the ipkg or the package index are corrupt. Try 'ipkg update'.\n",                           pkg->name);              free(file_md5);              return err;         }         free(file_md5);     }     if (pkg->tmp_unpack_dir == NULL) {	  unpack_pkg_control_files(conf, pkg);     }     /* We should update the filelist here, so that upgrades of packages that split will not fail. -Jamey 27-MAR-03 *//* Pigi: check if it will pass from here when replacing. It seems to fail *//* That's rather strange that files don't change owner. Investigate !!!!!!*/     err = update_file_ownership(conf, pkg, old_pkg);     if (err) { return err; }     if (conf->nodeps == 0) {	  err = satisfy_dependencies_for(conf, pkg);	  if (err) { return err; }     }     replacees = pkg_vec_alloc();     pkg_get_installed_replacees(conf, pkg, replacees);     /* this next section we do with SIGINT blocked to prevent inconsistency between ipkg database and filesystem */     {	  sigset_t newset, oldset;	  sighandler_t old_handler = NULL;	  int use_signal = 0;	  caught_sigint = 0;	  if (use_signal) {	       old_handler = signal(SIGINT, ipkg_install_pkg_sigint_handler);	  } else {	       sigemptyset(&newset);	       sigaddset(&newset, SIGINT);	       sigprocmask(SIG_BLOCK, &newset, &oldset);	  }	  ipkg_state_changed++;	  pkg->state_flag |= SF_FILELIST_CHANGED;	  /* XXX: BUG: we really should treat replacement more like an upgrade	   *      Instead, we're going to remove the replacees 	   */	  err = pkg_remove_installed_replacees(conf, replacees);	  if (err) goto UNWIND_REMOVE_INSTALLED_REPLACEES;	  err = prerm_upgrade_old_pkg(conf, pkg, old_pkg);	  if (err) goto UNWIND_PRERM_UPGRADE_OLD_PKG;	  err = prerm_deconfigure_conflictors(conf, pkg, replacees);	  if (err) goto UNWIND_PRERM_DECONFIGURE_CONFLICTORS;	  err = preinst_configure(conf, pkg, old_pkg);	  if (err) goto UNWIND_PREINST_CONFIGURE;	  err = backup_modified_conffiles(conf, pkg, old_pkg);	  if (err) goto UNWIND_BACKUP_MODIFIED_CONFFILES;	  err = check_data_file_clashes(conf, pkg, old_pkg);	  if (err) goto UNWIND_CHECK_DATA_FILE_CLASHES;	  err = postrm_upgrade_old_pkg(conf, pkg, old_pkg);	  if (err) goto UNWIND_POSTRM_UPGRADE_OLD_PKG;	  if (conf->noaction) return 0;	  /* point of no return: no unwinding after this */	  if (old_pkg && !conf->force_reinstall) {	       old_pkg->state_want = SW_DEINSTALL;	       if (old_pkg->state_flag & SF_NOPRUNE) {		    ipkg_message(conf, IPKG_INFO,				 "  not removing obsolesced files because package marked noprune\n");	       } else {		    ipkg_message(conf, IPKG_INFO,				 "  removing obsolesced files\n");		    remove_obsolesced_files(conf, pkg, old_pkg);	       }               /* removing files from old package, to avoid ghost files */                remove_data_files_and_list(conf, old_pkg);/* Pigi : It should be better to remove also maintainer and postrem scripts here, just in case*/               remove_maintainer_scripts_except_postrm(conf, old_pkg);               remove_postrm(conf, old_pkg);/* Pigi */	  }	  ipkg_message(conf, IPKG_INFO,		       "  installing maintainer scripts\n");	  install_maintainer_scripts(conf, pkg, old_pkg);	  /* the following just returns 0 */	  remove_disappeared(conf, pkg);	  ipkg_message(conf, IPKG_INFO,		       "  installing data files\n");	  install_data_files(conf, pkg);/* read comments from function for detail but I will execute this here as all other tests are ok.*/	  err = check_data_file_clashes_change(conf, pkg, old_pkg);	  ipkg_message(conf, IPKG_INFO,		       "  resolving conf files\n");	  resolve_conffiles(conf, pkg);	  pkg->state_status = SS_UNPACKED;	  old_state_flag = pkg->state_flag;	  pkg->state_flag &= ~SF_PREFER;	  ipkg_message(conf, IPKG_DEBUG, "   pkg=%s old_state_flag=%x state_flag=%x\n", pkg->name, old_state_flag, pkg->state_flag);	  if (old_pkg && !conf->force_reinstall) {	       old_pkg->state_status = SS_NOT_INSTALLED;	  }	  time(&pkg->installed_time);	  ipkg_message(conf, IPKG_INFO,		       "  cleanup temp files\n");	  cleanup_temporary_files(conf, pkg);	  ab_pkg = pkg->parent;	  if (ab_pkg)	       ab_pkg->state_status = pkg->state_status;	  ipkg_message(conf, IPKG_INFO, "Done.\n");	  if (use_signal)	       signal(SIGINT, old_handler);	  else	       sigprocmask(SIG_UNBLOCK, &newset, &oldset);	  return 0;          UNWIND_POSTRM_UPGRADE_OLD_PKG:	  postrm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);     UNWIND_CHECK_DATA_FILE_CLASHES:	  check_data_file_clashes_unwind(conf, pkg, old_pkg);     UNWIND_BACKUP_MODIFIED_CONFFILES:	  backup_modified_conffiles_unwind(conf, pkg, old_pkg);     UNWIND_PREINST_CONFIGURE:	  preinst_configure_unwind(conf, pkg, old_pkg);     UNWIND_PRERM_DECONFIGURE_CONFLICTORS:	  prerm_deconfigure_conflictors_unwind(conf, pkg, replacees);     UNWIND_PRERM_UPGRADE_OLD_PKG:	  prerm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);     UNWIND_REMOVE_INSTALLED_REPLACEES:	  pkg_remove_installed_replacees_unwind(conf, replacees);	  ipkg_message(conf, IPKG_INFO,		       "  cleanup temp files\n");	  cleanup_temporary_files(conf, pkg);	  ipkg_message(conf, IPKG_INFO,		       "Failed.\n");	  if (use_signal)	       signal(SIGINT, old_handler);	  else	       sigprocmask(SIG_UNBLOCK, &newset, &oldset);	  return err;     }}static int prerm_upgrade_old_pkg(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     /* DPKG_INCOMPATIBILITY:	dpkg does some things here that we don't do yet. Do we care?		1. If a version of the package is already installed, call	   old-prerm upgrade new-version	2. If the script runs but exits with a non-zero exit status	   new-prerm failed-upgrade old-version	   Error unwind, for both the above cases:	   old-postinst abort-upgrade new-version     */     return 0;}static int prerm_upgrade_old_pkg_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     /* DPKG_INCOMPATIBILITY:	dpkg does some things here that we don't do yet. Do we care?	(See prerm_upgrade_old_package for details)     */     return 0;}static int prerm_deconfigure_conflictors(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors){     /* DPKG_INCOMPATIBILITY:	dpkg does some things here that we don't do yet. Do we care?	2. If a 'conflicting' package is being removed at the same time:		1. If any packages depended on that conflicting package and		   --auto-deconfigure is specified, call, for each such package:		   deconfigured's-prerm deconfigure \		   in-favour package-being-installed version \		   removing conflicting-package version		Error unwind:		   deconfigured's-postinst abort-deconfigure \		   in-favour package-being-installed-but-failed version \		   removing conflicting-package version		   The deconfigured packages are marked as requiring		   configuration, so that if --install is used they will be		   configured again if possible.		2. To prepare for removal of the conflicting package, call:		   conflictor's-prerm remove in-favour package new-version		Error unwind:		   conflictor's-postinst abort-remove in-favour package new-version     */     return 0;}static int prerm_deconfigure_conflictors_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors){     /* DPKG_INCOMPATIBILITY: dpkg does some things here that we don't	do yet. Do we care?  (See prerm_deconfigure_conflictors for	details) */     return 0;}static int preinst_configure(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     int err;     char *preinst_args;     if (old_pkg) {	  char *old_version = pkg_version_str_alloc(old_pkg);	  sprintf_alloc(&preinst_args, "upgrade %s", old_version);	  free(old_version);     } else if (pkg->state_status == SS_CONFIG_FILES) {	  char *pkg_version = pkg_version_str_alloc(pkg);	  sprintf_alloc(&preinst_args, "install %s", pkg_version);	  free(pkg_version);     } else {	  preinst_args = strdup("install");     }     err = pkg_run_script(conf, pkg, "preinst", preinst_args);     if (err) {	  ipkg_message(conf, IPKG_ERROR,		       "Aborting installation of %s\n", pkg->name);	  return 1;     }     free(preinst_args);     return 0;}static int preinst_configure_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     /* DPKG_INCOMPATIBILITY:	dpkg does the following error unwind, should we?	pkg->postrm abort-upgrade old-version	OR pkg->postrm abort-install old-version	OR pkg->postrm abort-install     */     return 0;}static int backup_modified_conffiles(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     int err;     conffile_list_elt_t *iter;     conffile_t *cf;     if (conf->noaction) return 0;     /* Backup all modified conffiles */     if (old_pkg) {	  for (iter = old_pkg->conffiles.head; iter; iter = iter->next) {	       char *cf_name;	       	       cf = iter->data;	       cf_name = root_filename_alloc(conf, cf->name);	       /* Don't worry if the conffile is just plain gone */	       if (file_exists(cf_name) && conffile_has_been_modified(conf, cf)) {		    err = backup_make_backup(conf, cf_name);		    if (err) {			 return err;		    }	       }	       free(cf_name);	  }     }     /* Backup all conffiles that were not conffiles in old_pkg */     for (iter = pkg->conffiles.head; iter; iter = iter->next) {	  char *cf_name;	  cf = iter->data;	  cf_name = root_filename_alloc(conf, cf->name);	  /* Ignore if this was a conffile in old_pkg as well */	  if (pkg_get_conffile(old_pkg, cf->name)) {	       continue;	  }	  if (file_exists(cf_name) && (! backup_exists_for(cf_name))) {	       err = backup_make_backup(conf, cf_name);	       if (err) {		    return err;	       }	  }	  free(cf_name);     }     return 0;}static int backup_modified_conffiles_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     conffile_list_elt_t *iter;     if (old_pkg) {	  for (iter = old_pkg->conffiles.head; iter; iter = iter->next) {	       backup_remove(iter->data->name);	  }     }     for (iter = pkg->conffiles.head; iter; iter = iter->next) {	  backup_remove(iter->data->name);     }     return 0;}static int check_data_file_clashes(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg){     /* DPKG_INCOMPATIBILITY:	ipkg takes a slightly different approach than dpkg at this	point.  dpkg installs each file in the new package while	creating a backup for any file that is replaced, (so that it	can unwind if necessary).  To avoid complexity and redundant	storage, ipkg doesn't do any installation until later, (at the	point at which dpkg removes the backups.	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?