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