Commit | Line | Data |
---|---|---|
a0a63413 JB |
1 | // |
2 | // pkgutils | |
3 | // | |
4 | // Copyright (c) 2000-2005 Per Liden | |
5 | // Copyright (c) 2006-2007 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 | } |