forked from tools/pkgutils
156 lines
4.8 KiB
C++
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;
|
|
}
|