Beispiel #1
0
/**
 * @brief Remove a package from the filesystem.
 *
 * @param handle the context handle
 * @param oldpkg package to remove
 * @param newpkg package to replace \a oldpkg (optional)
 * @param targ_count current index within the transaction (1-based)
 * @param pkg_count the number of packages affected by the transaction
 *
 * @return 0
 */
int _alpm_remove_single_package(alpm_handle_t *handle,
		alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg,
		size_t targ_count, size_t pkg_count)
{
	const char *pkgname = oldpkg->name;
	const char *pkgver = oldpkg->version;

	if(newpkg) {
		_alpm_log(handle, ALPM_LOG_DEBUG, "removing old package first (%s-%s)\n",
				pkgname, pkgver);
	} else {
		EVENT(handle, ALPM_EVENT_REMOVE_START, oldpkg, NULL);
		_alpm_log(handle, ALPM_LOG_DEBUG, "removing package %s-%s\n",
				pkgname, pkgver);

		/* run the pre-remove scriptlet if it exists  */
		if(alpm_pkg_has_scriptlet(oldpkg) &&
				!(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
			char *scriptlet = _alpm_local_db_pkgpath(handle->db_local,
					oldpkg, "install");
			_alpm_runscriptlet(handle, scriptlet, "pre_remove", pkgver, NULL, 0);
			free(scriptlet);
		}
	}

	if(!(handle->trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
		/* TODO check returned errors if any */
		remove_package_files(handle, oldpkg, newpkg, targ_count, pkg_count);
	}

	/* run the post-remove script if it exists  */
	if(!newpkg && alpm_pkg_has_scriptlet(oldpkg) &&
			!(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
		char *scriptlet = _alpm_local_db_pkgpath(handle->db_local,
				oldpkg, "install");
		_alpm_runscriptlet(handle, scriptlet, "post_remove", pkgver, NULL, 0);
		free(scriptlet);
	}

	if(!newpkg) {
		EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL);
	}

	/* remove the package from the database */
	_alpm_log(handle, ALPM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
	if(_alpm_local_db_remove(handle->db_local, oldpkg) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
				pkgname, pkgver);
	}
	/* remove the package from the cache */
	if(_alpm_db_remove_pkgfromcache(handle->db_local, oldpkg) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not remove entry '%s' from cache\n"),
				pkgname);
	}

	/* TODO: useful return values */
	return 0;
}
Beispiel #2
0
static int print_pkg(alpm_pkg_t *pkg, const char *format) {
  const char *f, *end;
  char fmt[64], buf[64];
  int len, out = 0;

  end = format + strlen(format);

  for (f = format; f < end; f++) {
    len = 0;
    if (*f == '%') {
      len = strspn(f + 1 + len, printf_flags);
      len += strspn(f + 1 + len, digits);
      snprintf(fmt, len + 3, "%ss", f);
      fmt[len + 1] = 's';
      f += len + 1;
      switch (*f) {
        /* simple attributes */
        case 'f': /* filename */
          out += printf(fmt, alpm_pkg_get_filename(pkg));
          break;
        case 'n': /* package name */
          out += printf(fmt, alpm_pkg_get_name(pkg));
          break;
        case 'v': /* version */
          out += printf(fmt, alpm_pkg_get_version(pkg));
          break;
        case 'd': /* description */
          out += printf(fmt, alpm_pkg_get_desc(pkg));
          break;
        case 'u': /* project url */
          out += printf(fmt, alpm_pkg_get_url(pkg));
          break;
        case 'p': /* packager name */
          out += printf(fmt, alpm_pkg_get_packager(pkg));
          break;
        case 's': /* md5sum */
          out += printf(fmt, alpm_pkg_get_md5sum(pkg));
          break;
        case 'a': /* architecutre */
          out += printf(fmt, alpm_pkg_get_arch(pkg));
          break;
        case 'i': /* has install scriptlet? */
          out += printf(fmt, alpm_pkg_has_scriptlet(pkg) ? "yes" : "no");
          break;
        case 'r': /* repo */
          out += printf(fmt, alpm_db_get_name(alpm_pkg_get_db(pkg)));
          break;
        case 'w': /* install reason */
          out += printf(fmt, alpm_pkg_get_reason(pkg) ? "dependency" : "explicit");
          break;
        case '!': /* result number */
          snprintf(buf, sizeof(buf), "%d", opt_pkgcounter++);
          out += printf(fmt, buf);
          break;
        case 'g': /* base64 gpg sig */
          out += printf(fmt, alpm_pkg_get_base64_sig(pkg));
          break;
        case 'h': /* sha256sum */
          out += printf(fmt, alpm_pkg_get_sha256sum(pkg));
          break;

        /* times */
        case 'b': /* build date */
          out += print_time(alpm_pkg_get_builddate(pkg));
          break;
        case 'l': /* install date */
          out += print_time(alpm_pkg_get_installdate(pkg));
          break;

        /* sizes */
        case 'k': /* download size */
          out += printf(fmt, size_to_string(alpm_pkg_get_size(pkg)));
          break;
        case 'm': /* install size */
          out += printf(fmt, size_to_string(alpm_pkg_get_isize(pkg)));
          break;

        /* lists */
        case 'F': /* files */
          out += print_filelist(alpm_pkg_get_files(pkg));
          break;
        case 'N': /* requiredby */
          out += print_list(alpm_pkg_compute_requiredby(pkg), NULL);
          break;
        case 'L': /* licenses */
          out += print_list(alpm_pkg_get_licenses(pkg), NULL);
          break;
        case 'G': /* groups */
          out += print_list(alpm_pkg_get_groups(pkg), NULL);
          break;
        case 'E': /* depends (shortdeps) */
          out += print_list(alpm_pkg_get_depends(pkg), (extractfn)alpm_dep_get_name);
          break;
        case 'D': /* depends */
          out += print_list(alpm_pkg_get_depends(pkg), (extractfn)alpm_dep_compute_string);
          break;
        case 'O': /* optdepends */
          out += print_list(alpm_pkg_get_optdepends(pkg), (extractfn)format_optdep);
          break;
        case 'o': /* optdepends (shortdeps) */
          out += print_list(alpm_pkg_get_optdepends(pkg), (extractfn)alpm_dep_get_name);
          break;
        case 'C': /* conflicts */
          out += print_list(alpm_pkg_get_conflicts(pkg), (extractfn)alpm_dep_get_name);
          break;
        case 'S': /* provides (shortdeps) */
          out += print_list(alpm_pkg_get_provides(pkg), (extractfn)alpm_dep_get_name);
          break;
        case 'P': /* provides */
          out += print_list(alpm_pkg_get_provides(pkg), (extractfn)alpm_dep_compute_string);
          break;
        case 'R': /* replaces */
          out += print_list(alpm_pkg_get_replaces(pkg), (extractfn)alpm_dep_get_name);
          break;
        case 'B': /* backup */
          out += print_list(alpm_pkg_get_backup(pkg), alpm_backup_get_name);
          break;
        case 'V': /* package validation */
          out += print_allocated_list(get_validation_method(pkg), NULL);
          break;
        case 'M': /* modified */
          out += print_allocated_list(get_modified_files(pkg), NULL);
          break;
        case '%':
          fputc('%', stdout);
          out++;
          break;
        default:
          fputc('?', stdout);
          out++;
          break;
      }
    } else if (*f == '\\') {
      char esc[3] = { f[0], f[1], '\0' };
      out += print_escaped(esc);
      ++f;
    } else {
      fputc(*f, stdout);
      out++;
    }
  }

  /* only print a delimeter if any package data was outputted */
  if (out > 0) {
    print_escaped(opt_delim);
  }

  return !out;
}
Beispiel #3
0
static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
		struct archive_entry *entry, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg)
{
	const char *entryname = archive_entry_pathname(entry);
	mode_t entrymode = archive_entry_mode(entry);
	alpm_backup_t *backup = _alpm_needbackup(entryname, newpkg);
	char filename[PATH_MAX]; /* the actual file we're extracting */
	int needbackup = 0, notouch = 0;
	const char *hash_orig = NULL;
	int isnewfile = 0, errors = 0;
	struct stat lsbuf;
	size_t filename_len;

	if(*entryname == '.') {
		return extract_db_file(handle, archive, entry, newpkg, entryname);
	}

	if (!alpm_filelist_contains(&newpkg->files, entryname)) {
		_alpm_log(handle, ALPM_LOG_WARNING,
				_("file not found in file list for package %s. skipping extraction of %s\n"),
				newpkg->name, entryname);
		return 0;
	}

	/* build the new entryname relative to handle->root */
	filename_len = snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
	if(filename_len >= PATH_MAX) {
		_alpm_log(handle, ALPM_LOG_ERROR,
				_("unable to extract %s%s: path too long"), handle->root, entryname);
		return 1;
	}

	/* if a file is in NoExtract then we never extract it */
	if(_alpm_fnmatch_patterns(handle->noextract, entryname) == 0) {
		_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract,"
				" skipping extraction of %s\n",
				entryname, filename);
		archive_read_data_skip(archive);
		return 0;
	}

	/* Check for file existence. This is one of the more crucial parts
	 * to get 'right'. Here are the possibilities, with the filesystem
	 * on the left and the package on the top:
	 * (F=file, N=node, S=symlink, D=dir)
	 *               |  F/N  |   D
	 *  non-existent |   1   |   2
	 *  F/N          |   3   |   4
	 *  D            |   5   |   6
	 *
	 *  1,2- extract, no magic necessary. lstat (llstat) will fail here.
	 *  3,4- conflict checks should have caught this. either overwrite
	 *      or backup the file.
	 *  5- file replacing directory- don't allow it.
	 *  6- skip extraction, dir already exists.
	 */

	isnewfile = llstat(filename, &lsbuf) != 0;
	if(isnewfile) {
		/* cases 1,2: file doesn't exist, skip all backup checks */
	} else if(S_ISDIR(lsbuf.st_mode) && S_ISDIR(entrymode)) {
#if 0
		uid_t entryuid = archive_entry_uid(entry);
		gid_t entrygid = archive_entry_gid(entry);
#endif

		/* case 6: existing dir, ignore it */
		if(lsbuf.st_mode != entrymode) {
			/* if filesystem perms are different than pkg perms, warn user */
			mode_t mask = 07777;
			_alpm_log(handle, ALPM_LOG_WARNING, _("directory permissions differ on %s\n"
					"filesystem: %o  package: %o\n"), filename, lsbuf.st_mode & mask,
					entrymode & mask);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: directory permissions differ on %s\n"
					"filesystem: %o  package: %o\n", filename, lsbuf.st_mode & mask,
					entrymode & mask);
		}
#ifndef __MSYS__

#if 0
		/* Disable this warning until our user management in packages has improved.
		   Currently many packages have to create users in post_install and chown the
		   directories. These all resulted in "false-positive" warnings. */

		if((entryuid != lsbuf.st_uid) || (entrygid != lsbuf.st_gid)) {
			_alpm_log(handle, ALPM_LOG_WARNING, _("directory ownership differs on %s\n"
					"filesystem: %u:%u  package: %u:%u\n"), filename,
					lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: directory ownership differs on %s\n"
					"filesystem: %u:%u  package: %u:%u\n", filename,
					lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
		}
#endif

#endif
		_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
				filename);
		archive_read_data_skip(archive);
		return 0;
	} else if(S_ISDIR(lsbuf.st_mode)) {
		/* case 5: trying to overwrite dir with file, don't allow it */
		_alpm_log(handle, ALPM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
				filename);
		archive_read_data_skip(archive);
		return 1;
	} else if(S_ISDIR(entrymode)) {
		/* case 4: trying to overwrite file with dir */
		_alpm_log(handle, ALPM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
				filename);
	} else {
		/* case 3: trying to overwrite file with file */
		/* if file is in NoUpgrade, don't touch it */
		if(_alpm_fnmatch_patterns(handle->noupgrade, entryname) == 0) {
			notouch = 1;
		} else {
			alpm_backup_t *oldbackup;
			if(oldpkg && (oldbackup = _alpm_needbackup(entryname, oldpkg))) {
				hash_orig = oldbackup->hash;
				needbackup = 1;
			} else if(backup) {
				/* allow adding backup files retroactively */
				needbackup = 1;
			}
		}
	}

	if(notouch || needbackup) {
		if(filename_len + strlen(".pacnew") >= PATH_MAX) {
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("unable to extract %s.pacnew: path too long"), filename);
			return 1;
		}
		strcpy(filename + filename_len, ".pacnew");
		isnewfile = (llstat(filename, &lsbuf) != 0 && errno == ENOENT);
	}

	_alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
	if(perform_extraction(handle, archive, entry, filename)) {
		errors++;
		return errors;
	}

	if(backup) {
		FREE(backup->hash);
		backup->hash = alpm_compute_md5sum(filename);
	}

	if(notouch) {
		alpm_event_pacnew_created_t event = {
			.type = ALPM_EVENT_PACNEW_CREATED,
			.from_noupgrade = 1,
			.oldpkg = oldpkg,
			.newpkg = newpkg,
			.file = filename
		};
		/* "remove" the .pacnew suffix */
		filename[filename_len] = '\0';
		EVENT(handle, &event);
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"warning: %s installed as %s.pacnew\n", filename, filename);
	} else if(needbackup) {
		char *hash_local = NULL, *hash_pkg = NULL;
		char origfile[PATH_MAX] = "";

		strncat(origfile, filename, filename_len);

		hash_local = alpm_compute_md5sum(origfile);
		hash_pkg = backup ? backup->hash : alpm_compute_md5sum(filename);

		_alpm_log(handle, ALPM_LOG_DEBUG, "checking hashes for %s\n", origfile);
		_alpm_log(handle, ALPM_LOG_DEBUG, "current:  %s\n", hash_local);
		_alpm_log(handle, ALPM_LOG_DEBUG, "new:      %s\n", hash_pkg);
		_alpm_log(handle, ALPM_LOG_DEBUG, "original: %s\n", hash_orig);

		if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) == 0) {
			/* local and new files are the same, updating anyway to get
			 * correct timestamps */
			_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
					origfile);
			if(try_rename(handle, filename, origfile)) {
				errors++;
			}
		} else if(hash_orig && hash_pkg && strcmp(hash_orig, hash_pkg) == 0) {
			/* original and new files are the same, leave the local version alone,
			 * including any user changes */
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"action: leaving existing file in place\n");
			if(isnewfile) {
				unlink(filename);
			}
		} else if(hash_orig && hash_local && strcmp(hash_orig, hash_local) == 0) {
			/* installed file has NOT been changed by user,
			 * update to the new version */
			_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
					origfile);
			if(try_rename(handle, filename, origfile)) {
				errors++;
			}
		} else {
			/* none of the three files matched another,  leave the unpacked
			 * file alongside the local file */
			alpm_event_pacnew_created_t event = {
				.type = ALPM_EVENT_PACNEW_CREATED,
				.from_noupgrade = 0,
				.oldpkg = oldpkg,
				.newpkg = newpkg,
				.file = origfile
			};
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"action: keeping current file and installing"
					" new one with .pacnew ending\n");
			EVENT(handle, &event);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: %s installed as %s\n", origfile, filename);
		}

		free(hash_local);
		if(!backup) {
			free(hash_pkg);
		}
	}
	return errors;
}

static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
		size_t pkg_current, size_t pkg_count)
{
	int i, ret = 0, errors = 0;
	int is_upgrade = 0;
	alpm_pkg_t *oldpkg = NULL;
	alpm_db_t *db = handle->db_local;
	alpm_trans_t *trans = handle->trans;
	alpm_progress_t progress = ALPM_PROGRESS_ADD_START;
	alpm_event_package_operation_t event;
	const char *log_msg = "adding";
	const char *pkgfile;

	ASSERT(trans != NULL, return -1);

	/* see if this is an upgrade. if so, remove the old package first */
	if((oldpkg = newpkg->oldpkg)) {
		int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
		if(cmp < 0) {
			log_msg = "downgrading";
			progress = ALPM_PROGRESS_DOWNGRADE_START;
			event.operation = ALPM_PACKAGE_DOWNGRADE;
		} else if(cmp == 0) {
			log_msg = "reinstalling";
			progress = ALPM_PROGRESS_REINSTALL_START;
			event.operation = ALPM_PACKAGE_REINSTALL;
		} else {
			log_msg = "upgrading";
			progress = ALPM_PROGRESS_UPGRADE_START;
			event.operation = ALPM_PACKAGE_UPGRADE;
		}
		is_upgrade = 1;

		/* copy over the install reason */
		newpkg->reason = alpm_pkg_get_reason(oldpkg);
	} else {
		event.operation = ALPM_PACKAGE_INSTALL;
	}

	event.type = ALPM_EVENT_PACKAGE_OPERATION_START;
	event.oldpkg = oldpkg;
	event.newpkg = newpkg;
	EVENT(handle, &event);

	pkgfile = newpkg->origin_data.file;

	_alpm_log(handle, ALPM_LOG_DEBUG, "%s package %s-%s\n",
			log_msg, newpkg->name, newpkg->version);
		/* pre_install/pre_upgrade scriptlet */
	if(alpm_pkg_has_scriptlet(newpkg) &&
			!(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
		const char *scriptlet_name = is_upgrade ? "pre_upgrade" : "pre_install";

		_alpm_runscriptlet(handle, pkgfile, scriptlet_name,
				newpkg->version, oldpkg ? oldpkg->version : NULL, 1);
	}

	/* we override any pre-set reason if we have alldeps or allexplicit set */
	if(trans->flags & ALPM_TRANS_FLAG_ALLDEPS) {
		newpkg->reason = ALPM_PKG_REASON_DEPEND;
	} else if(trans->flags & ALPM_TRANS_FLAG_ALLEXPLICIT) {
		newpkg->reason = ALPM_PKG_REASON_EXPLICIT;
	}

	if(oldpkg) {
		/* set up fake remove transaction */
		if(_alpm_remove_single_package(handle, oldpkg, newpkg, 0, 0) == -1) {
			handle->pm_errno = ALPM_ERR_TRANS_ABORT;
			ret = -1;
			goto cleanup;
		}
	}

	/* prepare directory for database entries so permission are correct after
	   changelog/install script installation */
	if(_alpm_local_db_prepare(db, newpkg)) {
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"error: could not create database entry %s-%s\n",
				newpkg->name, newpkg->version);
		handle->pm_errno = ALPM_ERR_DB_WRITE;
		ret = -1;
		goto cleanup;
	}

	if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
		struct archive *archive;
		struct archive_entry *entry;
		struct stat buf;
		int fd, cwdfd;

		_alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n");

		fd = _alpm_open_archive(db->handle, pkgfile, &buf,
				&archive, ALPM_ERR_PKG_OPEN);
		if(fd < 0) {
			ret = -1;
			goto cleanup;
		}

		/* save the cwd so we can restore it later */
		OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
		if(cwdfd < 0) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
		}

		/* libarchive requires this for extracting hard links */
		if(chdir(handle->root) != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
					handle->root, strerror(errno));
			_alpm_archive_read_free(archive);
			close(fd);
			ret = -1;
			goto cleanup;
		}

		/* call PROGRESS once with 0 percent, as we sort-of skip that here */
		PROGRESS(handle, progress, newpkg->name, 0, pkg_count, pkg_current);

		for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
			int percent;

			if(newpkg->size != 0) {
				/* Using compressed size for calculations here, as newpkg->isize is not
				 * exact when it comes to comparing to the ACTUAL uncompressed size
				 * (missing metadata sizes) */
				int64_t pos = _alpm_archive_compressed_ftell(archive);
				percent = (pos * 100) / newpkg->size;
				if(percent >= 100) {
					percent = 100;
				}
			} else {
				percent = 0;
			}

			PROGRESS(handle, progress, newpkg->name, percent, pkg_count, pkg_current);

			/* extract the next file from the archive */
			errors += extract_single_file(handle, archive, entry, newpkg, oldpkg);
		}
		_alpm_archive_read_free(archive);
		close(fd);

		/* restore the old cwd if we have it */
		if(cwdfd >= 0) {
			if(fchdir(cwdfd) != 0) {
				_alpm_log(handle, ALPM_LOG_ERROR,
						_("could not restore working directory (%s)\n"), strerror(errno));
			}
			close(cwdfd);
		}

		if(errors) {
			ret = -1;
			if(is_upgrade) {
				_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
						newpkg->name);
				alpm_logaction(handle, ALPM_CALLER_PREFIX,
						"error: problem occurred while upgrading %s\n",
						newpkg->name);
			} else {
				_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"),
						newpkg->name);
				alpm_logaction(handle, ALPM_CALLER_PREFIX,
						"error: problem occurred while installing %s\n",
						newpkg->name);
			}
		}
	}

	/* make an install date (in UTC) */
	newpkg->installdate = time(NULL);

	_alpm_log(handle, ALPM_LOG_DEBUG, "updating database\n");
	_alpm_log(handle, ALPM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);

	if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not update database entry %s-%s\n"),
				newpkg->name, newpkg->version);
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"error: could not update database entry %s-%s\n",
				newpkg->name, newpkg->version);
		handle->pm_errno = ALPM_ERR_DB_WRITE;
		ret = -1;
		goto cleanup;
	}

	if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not add entry '%s' in cache\n"),
				newpkg->name);
	}

	PROGRESS(handle, progress, newpkg->name, 100, pkg_count, pkg_current);

	switch(event.operation) {
		case ALPM_PACKAGE_INSTALL:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "installed %s (%s)\n",
					newpkg->name, newpkg->version);
			break;
		case ALPM_PACKAGE_DOWNGRADE:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "downgraded %s (%s -> %s)\n",
					newpkg->name, oldpkg->version, newpkg->version);
			break;
		case ALPM_PACKAGE_REINSTALL:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "reinstalled %s (%s)\n",
					newpkg->name, newpkg->version);
			break;
		case ALPM_PACKAGE_UPGRADE:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "upgraded %s (%s -> %s)\n",
					newpkg->name, oldpkg->version, newpkg->version);
			break;
		default:
			/* we should never reach here */
			break;
	}

	/* run the post-install script if it exists */
	if(alpm_pkg_has_scriptlet(newpkg)
			&& !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
		char *scriptlet = _alpm_local_db_pkgpath(db, newpkg, "install");
		const char *scriptlet_name = is_upgrade ? "post_upgrade" : "post_install";

		_alpm_runscriptlet(handle, scriptlet, scriptlet_name,
				newpkg->version, oldpkg ? oldpkg->version : NULL, 0);
		free(scriptlet);
	}

	event.type = ALPM_EVENT_PACKAGE_OPERATION_DONE;
	EVENT(handle, &event);

cleanup:
	return ret;
}
Beispiel #4
0
void pacman_pkgdump(pmpkg_t *pkg, enum pkgfrom_t from)
{
	static const char *datefmt = "%a %d %b %Y %I:%M:%S %p %Z";

	alpm_list_t *i, *results = NULL;
	pmdb_t *db;
	pmdepend_t *dep;
	pmpkgreason_t reason;

	int has_script;
	time_t inst_time;
	struct tm tm_st;

	char installdate[60];
	char builddate[60];

	db = alpm_pkg_get_db(pkg);
	if (!db) {
		return;
	}

	memset(&tm_st, 0, sizeof(struct tm));
	inst_time = alpm_pkg_get_builddate(pkg);
	localtime_r(&inst_time, &tm_st);
	strftime(builddate, 60, datefmt, &tm_st);

	/* Local pkg specific */
	if (from == PKG_FROM_LOCAL) {
		has_script = alpm_pkg_has_scriptlet(pkg);
		reason = alpm_pkg_get_reason(pkg);

		memset(&tm_st, 0, sizeof(struct tm));
		inst_time = alpm_pkg_get_installdate(pkg);
		localtime_r(&inst_time, &tm_st);
		strftime(installdate, 60, datefmt, &tm_st);
	}

	if (from == PKG_FROM_SYNC) {
		printf("%s%s ", color.bold, REPO);
		const char *repo = alpm_db_get_name(db);
		if (!strcmp(repo, "core")) {
			printf("%s", color.bred);
		} else if (!strcmp(repo, "extra")) {
			printf("%s", color.bgreen);
		} else {
			printf("%s", color.bmag);
		}

		printf("%s%s\n", repo, color.nocolor);
	}

	printf("%s%s%s %s%s%s\n", color.bold, NAME, color.nocolor,
		   color.bold, alpm_pkg_get_name(pkg), color.nocolor);
	printf("%s%s %s%s%s\n", color.bold, VERSION, color.bgreen,
		   alpm_pkg_get_version(pkg), color.nocolor);
	printf("%s%s %s%s%s\n", color.bold, URL, color.bcyan,
		   alpm_pkg_get_url(pkg), color.nocolor);

	print_list_prefix(alpm_pkg_get_licenses(pkg), LICENSES);
	print_list_prefix(alpm_pkg_get_groups(pkg), GROUPS);
	print_list_prefix(alpm_pkg_get_provides(pkg), PROVIDES);

	print_list_deps(alpm_pkg_get_depends(pkg), DEPS);
	print_list_break(alpm_pkg_get_optdepends(pkg), OPTDEPS);

	if (from == PKG_FROM_LOCAL) {
		results = alpm_pkg_compute_requiredby(pkg);
		print_list_prefix(results, REQBY);
	}

	print_list_prefix(alpm_pkg_get_conflicts(pkg), CONFLICTS);
	print_list_prefix(alpm_pkg_get_replaces(pkg), REPLACES);

	if (from == PKG_FROM_SYNC) {
		humanize_size(alpm_pkg_get_size(pkg), DLSZ);
	}

	humanize_size(alpm_pkg_get_isize(pkg), INSTSZ);
	printf("%s%s%s %s\n", color.bold, PKGER, color.nocolor,
		   alpm_pkg_get_packager(pkg));
	printf("%s%s%s %s\n", color.bold, ARCH, color.nocolor, alpm_pkg_get_arch(pkg));
	printf("%s%s%s %s\n", color.bold, BDATE, color.nocolor, builddate);

	if (from == PKG_FROM_LOCAL) {
		printf("%s%s%s %s\n", color.bold, IDATE, color.nocolor, installdate);

		printf("%s%s%s ", color.bold, REASON, color.nocolor);
		switch (reason) {
		case PM_PKG_REASON_EXPLICIT:
			printf("Explicitly installed");
			break;
		case PM_PKG_REASON_DEPEND:
			printf("Installed as a dependency for another package");
			break;
		default:
			printf("Unknown");
			break;
		}

		printf("\n");
		printf("%s%s%s %s\n", color.bold, SCRIPT, color.nocolor,
			   has_script ? "Yes" : "No");
	}

	if (from == PKG_FROM_SYNC) {
		printf("%s%s%s %s\n", color.bold, MD5SUM, color.nocolor,
			   alpm_pkg_get_md5sum(pkg));
	}

	printf("%s%s%s %s\n", color.bold, DESC, color.nocolor, alpm_pkg_get_desc(pkg));
	FREELIST(results);
}
Beispiel #5
0
/**
 * Display the details of a package.
 * Extra information entails 'required by' info for sync packages and backup
 * files info for local packages.
 * @param pkg package to display information for
 * @param from the type of package we are dealing with
 * @param extra should we show extra information
 */
void dump_pkg_full(alpm_pkg_t *pkg, int extra)
{
    unsigned short cols;
    time_t bdate, idate;
    alpm_pkgfrom_t from;
    double size;
    char bdatestr[50] = "", idatestr[50] = "";
    const char *label, *reason;
    alpm_list_t *validation = NULL, *requiredby = NULL, *optionalfor = NULL;

    from = alpm_pkg_get_origin(pkg);

    /* set variables here, do all output below */
    bdate = (time_t)alpm_pkg_get_builddate(pkg);
    if(bdate) {
        strftime(bdatestr, 50, "%c", localtime(&bdate));
    }
    idate = (time_t)alpm_pkg_get_installdate(pkg);
    if(idate) {
        strftime(idatestr, 50, "%c", localtime(&idate));
    }

    switch(alpm_pkg_get_reason(pkg)) {
    case ALPM_PKG_REASON_EXPLICIT:
        reason = _("Explicitly installed");
        break;
    case ALPM_PKG_REASON_DEPEND:
        reason = _("Installed as a dependency for another package");
        break;
    default:
        reason = _("Unknown");
        break;
    }

    alpm_pkgvalidation_t v = alpm_pkg_get_validation(pkg);
    if(v) {
        if(v & ALPM_PKG_VALIDATION_NONE) {
            validation = alpm_list_add(validation, _("None"));
        } else {
            if(v & ALPM_PKG_VALIDATION_MD5SUM) {
                validation = alpm_list_add(validation, _("MD5 Sum"));
            }
            if(v & ALPM_PKG_VALIDATION_SHA256SUM) {
                validation = alpm_list_add(validation, _("SHA256 Sum"));
            }
            if(v & ALPM_PKG_VALIDATION_SIGNATURE) {
                validation = alpm_list_add(validation, _("Signature"));
            }
        }
    } else {
        validation = alpm_list_add(validation, _("Unknown"));
    }

    if(extra || from == ALPM_PKG_FROM_LOCALDB) {
        /* compute this here so we don't get a pause in the middle of output */
        requiredby = alpm_pkg_compute_requiredby(pkg);
        optionalfor = alpm_pkg_compute_optionalfor(pkg);
    }

    cols = getcols(fileno(stdout));

    /* actual output */
    if(from == ALPM_PKG_FROM_SYNCDB) {
        string_display(_("Repository     :"),
                       alpm_db_get_name(alpm_pkg_get_db(pkg)), cols);
    }
    string_display(_("Name           :"), alpm_pkg_get_name(pkg), cols);
    string_display(_("Version        :"), alpm_pkg_get_version(pkg), cols);
    string_display(_("Description    :"), alpm_pkg_get_desc(pkg), cols);
    string_display(_("Architecture   :"), alpm_pkg_get_arch(pkg), cols);
    string_display(_("URL            :"), alpm_pkg_get_url(pkg), cols);
    list_display(_("Licenses       :"), alpm_pkg_get_licenses(pkg), cols);
    list_display(_("Groups         :"), alpm_pkg_get_groups(pkg), cols);
    deplist_display(_("Provides       :"), alpm_pkg_get_provides(pkg), cols);
    deplist_display(_("Depends On     :"), alpm_pkg_get_depends(pkg), cols);
    optdeplist_display(pkg, cols);

    if(extra || from == ALPM_PKG_FROM_LOCALDB) {
        list_display(_("Required By    :"), requiredby, cols);
        list_display(_("Optional For   :"), optionalfor, cols);
    }
    deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols);
    deplist_display(_("Replaces       :"), alpm_pkg_get_replaces(pkg), cols);

    size = humanize_size(alpm_pkg_get_size(pkg), '\0', 2, &label);
    if(from == ALPM_PKG_FROM_SYNCDB) {
        printf("%s%s%s %6.2f %s\n", config->colstr.title, _("Download Size  :"),
               config->colstr.nocolor, size, label);
    } else if(from == ALPM_PKG_FROM_FILE) {
        printf("%s%s%s %6.2f %s\n", config->colstr.title, _("Compressed Size:"),
               config->colstr.nocolor, size, label);
    } else {
        // autodetect size for "Installed Size"
        label = "\0";
    }

    size = humanize_size(alpm_pkg_get_isize(pkg), label[0], 2, &label);
    printf("%s%s%s %6.2f %s\n", config->colstr.title, _("Installed Size :"),
           config->colstr.nocolor, size, label);

    string_display(_("Packager       :"), alpm_pkg_get_packager(pkg), cols);
    string_display(_("Build Date     :"), bdatestr, cols);
    if(from == ALPM_PKG_FROM_LOCALDB) {
        string_display(_("Install Date   :"), idatestr, cols);
        string_display(_("Install Reason :"), reason, cols);
    }
    if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) {
        string_display(_("Install Script :"),
                       alpm_pkg_has_scriptlet(pkg) ?  _("Yes") : _("No"), cols);
    }

    if(from == ALPM_PKG_FROM_SYNCDB && extra) {
        const char *base64_sig = alpm_pkg_get_base64_sig(pkg);
        alpm_list_t *keys = NULL;
        if(base64_sig) {
            unsigned char *decoded_sigdata = NULL;
            size_t data_len;
            alpm_decode_signature(base64_sig, &decoded_sigdata, &data_len);
            alpm_extract_keyid(config->handle, alpm_pkg_get_name(pkg),
                               decoded_sigdata, data_len, &keys);
        } else {
            keys = alpm_list_add(keys, _("None"));
        }

        string_display(_("MD5 Sum        :"), alpm_pkg_get_md5sum(pkg), cols);
        string_display(_("SHA256 Sum     :"), alpm_pkg_get_sha256sum(pkg), cols);
        list_display(_("Signatures     :"), keys, cols);
    } else {
        list_display(_("Validated By   :"), validation, cols);
    }

    if(from == ALPM_PKG_FROM_FILE) {
        alpm_siglist_t siglist;
        int err = alpm_pkg_check_pgp_signature(pkg, &siglist);
        if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) {
            string_display(_("Signatures     :"), _("None"), cols);
        } else if(err) {
            string_display(_("Signatures     :"),
                           alpm_strerror(alpm_errno(config->handle)), cols);
        } else {
            signature_display(_("Signatures     :"), &siglist, cols);
        }
        alpm_siglist_cleanup(&siglist);
    }

    /* Print additional package info if info flag passed more than once */
    if(from == ALPM_PKG_FROM_LOCALDB && extra) {
        dump_pkg_backups(pkg);
    }

    /* final newline to separate packages */
    printf("\n");

    FREELIST(requiredby);
    alpm_list_free(validation);
}
Beispiel #6
0
static PyObject* pyalpm_pkg_has_scriptlet(AlpmPackage *self, void *closure) {
  CHECK_IF_INITIALIZED();
  return PyBool_FromLong(alpm_pkg_has_scriptlet(self->c_data));
}