170 lines
3.4 KiB
C++
170 lines
3.4 KiB
C++
//=======================================================================
|
|
// pkg.cc
|
|
//-----------------------------------------------------------------------
|
|
// This file is part of the package porg
|
|
// Copyright (C) 2015 David Ricart
|
|
// For more information visit http://porg.sourceforge.net
|
|
//=======================================================================
|
|
|
|
#include "config.h"
|
|
#include "pkg.h"
|
|
#include "out.h"
|
|
#include "opt.h"
|
|
#include "db.h"
|
|
#include "main.h" // g_exit_status
|
|
#include "porg/common.h" // in_paths(), strip_trailing()
|
|
#include "porg/file.h"
|
|
#include <string>
|
|
#include <iomanip>
|
|
|
|
using std::string;
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::set;
|
|
using std::setw;
|
|
using namespace Porg;
|
|
|
|
static void remove_parent_dir(string const& path);
|
|
|
|
|
|
Pkg::Pkg(string const& name_)
|
|
:
|
|
BasePkg(name_)
|
|
{
|
|
read_log();
|
|
}
|
|
|
|
|
|
void Pkg::print_info() const
|
|
{
|
|
cout
|
|
<< string(m_name.size() + 2, '-') << endl
|
|
<< " " << m_name << " " << endl
|
|
<< string(m_name.size() + 2, '-') << endl
|
|
<< "Name: " << m_base_name << endl
|
|
<< "Version: " << m_version << endl
|
|
<< "Summary: " << m_summary << endl
|
|
<< "Author: " << m_author << endl
|
|
<< "License: " << m_license << endl
|
|
<< "URL: " << m_url << endl << endl
|
|
<< description_str() << endl << endl;
|
|
}
|
|
|
|
|
|
void Pkg::append(set<string> const& files_)
|
|
{
|
|
bool appended(false);
|
|
|
|
for (set<string>::const_iterator f(files_.begin()); f != files_.end(); ++f) {
|
|
if (!find_file(*f)) {
|
|
log_file(*f);
|
|
appended = true;
|
|
}
|
|
}
|
|
|
|
if (appended)
|
|
write_log();
|
|
}
|
|
|
|
|
|
void Pkg::unlog() const
|
|
{
|
|
try
|
|
{
|
|
BasePkg::unlog();
|
|
Out::vrb("Package '" + m_name + "' removed from database");
|
|
}
|
|
catch (Error const& x)
|
|
{
|
|
Out::vrb(x.what());
|
|
}
|
|
}
|
|
|
|
|
|
void Pkg::list(int size_w, int nfiles_w) const
|
|
{
|
|
if (Opt::print_sizes())
|
|
cout << setw(size_w) << fmt_size(m_size) << " ";
|
|
|
|
if (Opt::print_nfiles())
|
|
cout << setw(nfiles_w) << m_nfiles << " ";
|
|
|
|
if (Opt::print_date())
|
|
cout << fmt_date(m_date, Opt::print_hour()) << " ";
|
|
|
|
if (!Opt::print_no_pkg_name())
|
|
cout << m_name;
|
|
|
|
cout << endl;
|
|
}
|
|
|
|
|
|
void Pkg::list_files(int size_w)
|
|
{
|
|
assert(size_w > 0);
|
|
|
|
sort_files(Opt::sort_type(), Opt::reverse_sort());
|
|
|
|
if (!Opt::print_no_pkg_name())
|
|
cout << m_name << ":" << endl;
|
|
|
|
for (const_iter f(m_files.begin()); f != m_files.end(); ++f) {
|
|
|
|
if (Opt::print_sizes())
|
|
cout << setw(size_w) << fmt_size((*f)->size()) << " ";
|
|
|
|
cout << (*f)->name();
|
|
|
|
if (Opt::print_symlinks() && (*f)->is_symlink())
|
|
cout << " -> " << (*f)->ln_name();
|
|
|
|
cout << endl;
|
|
}
|
|
}
|
|
|
|
|
|
void Pkg::remove(DB const& db)
|
|
{
|
|
for (iter f(m_files.begin()); f != m_files.end(); ++f) {
|
|
|
|
// skip excluded
|
|
if (in_paths((*f)->name(), Opt::remove_skip()))
|
|
Out::vrb((*f)->name() + ": excluded");
|
|
|
|
// skip shared files
|
|
else if (is_shared(*f, db))
|
|
Out::vrb((*f)->name() + ": shared");
|
|
|
|
// remove file
|
|
else if (!unlink((*f)->name().c_str())) {
|
|
Out::vrb("Removed '" + (*f)->name());
|
|
remove_parent_dir((*f)->name());
|
|
}
|
|
|
|
// an error occurred
|
|
else if (errno != ENOENT) {
|
|
Out::vrb("Failed to remove '" + (*f)->name() + "'", errno);
|
|
g_exit_status = EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (g_exit_status == EXIT_SUCCESS)
|
|
unlog();
|
|
}
|
|
|
|
|
|
static void remove_parent_dir(string const& path)
|
|
{
|
|
string dir(strip_trailing(path, '/'));
|
|
string::size_type i;
|
|
|
|
if ((i = dir.rfind('/')) != string::npos) {
|
|
dir.erase(i);
|
|
if (rmdir(dir.c_str()) == 0) {
|
|
Out::vrb("Removed directory '" + dir + "'");
|
|
remove_parent_dir(dir);
|
|
}
|
|
}
|
|
}
|
|
|