summaryrefslogtreecommitdiff
path: root/pkginfo.cc
blob: b06b9b24a51337d16c7f61d08bc07b3b9c49cec8 (plain)
    1 //
    2 //  pkgutils
    3 // 
    4 //  Copyright (c) 2000-2005 Per Liden
    5 //  Copyright (c) 2006-2021 by CRUX team (http://crux.nu)
    6 // 
    7 //  This program is free software; you can redistribute it and/or modify
    8 //  it under the terms of the GNU General Public License as published by
    9 //  the Free Software Foundation; either version 2 of the License, or
   10 //  (at your option) any later version.
   11 //
   12 //  This program is distributed in the hope that it will be useful,
   13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 //  GNU General Public License for more details.
   16 //
   17 //  You should have received a copy of the GNU General Public License
   18 //  along with this program; if not, write to the Free Software
   19 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
   20 //  USA.
   21 //
   22 
   23 #include "pkginfo.h"
   24 #include <iterator>
   25 #include <vector>
   26 #include <iomanip>
   27 #include <sys/types.h>
   28 #include <regex.h>
   29 
   30 void pkginfo::run(int argc, char** argv)
   31 {
   32 	//
   33 	// Check command line options
   34 	//
   35 	int o_footprint_mode = 0;
   36 	int o_installed_mode = 0;
   37 	int o_list_mode = 0;
   38 	int o_owner_mode = 0;
   39 	string o_root;
   40 	string o_arg;
   41 
   42 	for (int i = 1; i < argc; ++i) {
   43 		string option(argv[i]);
   44 		if (option == "-r" || option == "--root") {
   45 			assert_argument(argv, argc, i);
   46 			o_root = argv[i + 1];
   47 			i++;
   48 		} else if (option == "-i" || option == "--installed") {
   49 			o_installed_mode += 1;
   50 		} else if (option == "-l" || option == "--list") {
   51 			assert_argument(argv, argc, i);
   52 			o_list_mode += 1;
   53 			o_arg = argv[i + 1];
   54 			i++;
   55 		} else if (option == "-o" || option == "--owner") {
   56 			assert_argument(argv, argc, i);
   57 			o_owner_mode += 1;
   58 			o_arg = argv[i + 1];
   59 			i++;
   60 		} else if (option == "-f" || option == "--footprint") {
   61 			assert_argument(argv, argc, i);
   62 			o_footprint_mode += 1;
   63 			o_arg = argv[i + 1];
   64 			i++;
   65 		} else {
   66 			throw runtime_error("invalid option " + option);
   67 		}
   68 	}
   69 
   70 	if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode == 0)
   71 		throw runtime_error("option missing");
   72 
   73 	if (o_footprint_mode + o_installed_mode + o_list_mode + o_owner_mode > 1)
   74 		throw runtime_error("too many options");
   75 
   76 	if (o_footprint_mode) {
   77 		//
   78 		// Make footprint
   79 		//
   80 		pkg_footprint(o_arg);
   81 	} else {
   82 		//
   83 		// Modes that require the database to be opened
   84 		//
   85 		{
   86 			db_lock lock(o_root, false);
   87 			db_open(o_root);
   88 		}
   89 
   90 		if (o_installed_mode) {
   91 			//
   92 			// List installed packages
   93 			//
   94 			for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i)
   95 				cout << i->first << ' ' << i->second.version << endl;
   96 		} else if (o_list_mode) {
   97 			//
   98 			// List package or file contents
   99 			//
  100 			if (db_find_pkg(o_arg)) {
  101 				copy(packages[o_arg].files.begin(), packages[o_arg].files.end(), ostream_iterator<string>(cout, "\n"));
  102 			} else if (file_exists(o_arg)) {
  103 				pair<string, pkginfo_t> package = pkg_open(o_arg);
  104 				copy(package.second.files.begin(), package.second.files.end(), ostream_iterator<string>(cout, "\n"));
  105 			} else {
  106 				throw runtime_error(o_arg + " is neither an installed package nor a package file");
  107 			}
  108 		} else {
  109 			//
  110 			// List owner(s) of file or directory
  111 			//
  112 			regex_t preg;
  113 			if (regcomp(&preg, o_arg.c_str(), REG_EXTENDED | REG_NOSUB))
  114 				throw runtime_error("error compiling regular expression '" + o_arg + "', aborting");
  115 
  116 			vector<pair<string, string> > result;
  117 			result.push_back(pair<string, string>("Package", "File"));
  118 			unsigned int width = result.begin()->first.length(); // Width of "Package"
  119 			
  120 			for (packages_t::const_iterator i = packages.begin(); i != packages.end(); ++i) {
  121 				for (set<string>::const_iterator j = i->second.files.begin(); j != i->second.files.end(); ++j) {
  122 					const string file('/' + *j);
  123 					if (!regexec(&preg, file.c_str(), 0, 0, 0)) {
  124 						result.push_back(pair<string, string>(i->first, *j));
  125 						if (i->first.length() > width)
  126 							width = i->first.length();
  127 					}
  128 				}
  129 			}
  130 			
  131 			regfree(&preg);
  132 			
  133 			if (result.size() > 1) {
  134 				for (vector<pair<string, string> >::const_iterator i = result.begin(); i != result.end(); ++i) {
  135 					cout << left << setw(width + 2) << i->first << i->second << endl;
  136 				}
  137 			} else {
  138 				cout << utilname << ": no owner(s) found" << endl;
  139 			}
  140 		}
  141 	}
  142 }
  143 
  144 void pkginfo::print_help() const
  145 {
  146 	cout << "usage: " << utilname << " [options]" << endl
  147 	     << "options:" << endl
  148 	     << "  -i, --installed             list installed packages" << endl
  149 	     << "  -l, --list <package|file>   list files in <package> or <file>" << endl
  150 	     << "  -o, --owner <pattern>       list owner(s) of file(s) matching <pattern>" << endl
  151 	     << "  -f, --footprint <file>      print footprint for <file>" << endl
  152 	     << "  -r, --root <path>           specify alternative installation root" << endl
  153 	     << "  -v, --version               print version and exit" << endl
  154 	     << "  -h, --help                  print help and exit" << endl;
  155 }

Generated by cgit