pkgutils/pkginfo.cc

156 lines
4.8 KiB
C++

//
// pkgutils
//
// Copyright (c) 2000-2005 Per Liden
// Copyright (c) 2006-2021 by CRUX team (http://crux.nu)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
#include "pkginfo.h"
#include <iterator>
#include <vector>
#include <iomanip>
#include <sys/types.h>
#include <regex.h>
void pkginfo::run(int argc, char** argv)
{
//
// Check command line options
//
int o_footprint_mode = 0;
int o_installed_mode = 0;
int o_list_mode = 0;
int o_owner_mode = 0;
string o_root;
string o_arg;
for (int i = 1; i < argc; ++i) {
string option(argv[i]);
if (option == "-r" || option == "--root") {
assert_argument(argv, argc, i);
o_root = argv[i + 1];
i++;
} else if (option == "-i" || option == "--installed") {
o_installed_mode += 1;
} else if (option == "-l" || option == "--list") {
assert_argument(argv, argc, i);
o_list_mode += 1;
o_arg = argv[i + 1];
i++;
} else if (option == "-o" || option == "--owner") {
assert_argument(argv, argc, i);
o_owner_mode += 1;
o_arg = argv[i + 1];
i++;
} else if (option == "-f" || option == "--footprint") {
assert_argument(argv, argc, i);
o_footprint_mode += 1;
o_arg = argv[i + 1];
i++;
} else {
throw runtime_error("invalid option " + option);
}
}
if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode == 0)
throw runtime_error("option missing");
if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode > 1)
throw runtime_error("too many options");
if (o_footprint_mode) {
//
// Make footprint
//
pkg_footprint(o_arg);
} else {
//
// Modes that require the database to be opened
//
{
db_lock lock(o_root, false);
db_open(o_root);
}
if (o_installed_mode) {
//
// List installed packages
//
for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i)
cout << i->first << ' ' << i->second.version << endl;
} else if (o_list_mode) {
//
// List package or file contents
//
if (db_find_pkg(o_arg)) {
copy(packages[o_arg].files.begin(), packages[o_arg].files.end(), ostream_iterator<string>(cout, "\n"));
} else if (file_exists(o_arg)) {
pair<string, pkginfo_t> package = pkg_open(o_arg);
copy(package.second.files.begin(), package.second.files.end(), ostream_iterator<string>(cout, "\n"));
} else {
throw runtime_error(o_arg + " is neither an installed package nor a package file");
}
} else {
//
// List owner(s) of file or directory
//
regex_t preg;
if (regcomp(&preg, o_arg.c_str(), REG_EXTENDED | REG_NOSUB))
throw runtime_error("error compiling regular expression '" + o_arg + "', aborting");
vector<pair<string, string> > result;
result.push_back(pair<string, string>("Package", "File"));
unsigned int width = result.begin()->first.length(); // Width of "Package"
for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) {
for (set<string>::const_iterator j = i->second.files.begin(); j != i->second.files.end(); ++j) {
const string file('/' + *j);
if (!regexec(&preg, file.c_str(), 0, 0, 0)) {
result.push_back(pair<string, string>(i->first, *j));
if (i->first.length() > width)
width = i->first.length();
}
}
}
regfree(&preg);
if (result.size() > 1) {
for (vector<pair<string, string> >::const_iterator i = result.begin(); i != result.end(); ++i) {
cout << left << setw(width + 2) << i->first << i->second << endl;
}
} else {
cout << utilname << ": no owner(s) found" << endl;
}
}
}
}
void pkginfo::print_help() const
{
cout << "usage: " << utilname << " [options]" << endl
<< "options:" << endl
<< " -i, --installed list installed packages" << endl
<< " -l, --list <package|file> list files in <package> or <file>" << endl
<< " -o, --owner <pattern> list owner(s) of file(s) matching <pattern>" << endl
<< " -f, --footprint <file> print footprint for <file>" << endl
<< " -r, --root <path> specify alternative installation root" << endl
<< " -v, --version print version and exit" << endl
<< " -h, --help print help and exit" << endl;
}