blob: 26b14b341934f423b1008467c5e08bc10d0bc6af [file] [log] [blame]
Upstreamcc2ee171970-01-12 13:46:40 +00001/**
2 * @file locate_images.cpp
3 * Command-line helper
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12#include "file_manip.h"
13#include "locate_images.h"
14
15#include <cerrno>
16#include <iostream>
17#include <sstream>
18#include <cstdlib>
19
20using namespace std;
21
22
23void extra_images::populate(vector<string> const & paths)
24{
25 vector<string>::const_iterator cit = paths.begin();
26 vector<string>::const_iterator end = paths.end();
27 for (; cit != end; ++cit) {
28 string const path = op_realpath(*cit);
29 list<string> file_list;
30 create_file_list(file_list, path, "*", true);
31 list<string>::const_iterator lit = file_list.begin();
32 list<string>::const_iterator lend = file_list.end();
33 for (; lit != lend; ++lit) {
34 value_type v(op_basename(*lit), op_dirname(*lit));
35 images.insert(v);
36 }
37 }
38}
39
40
41vector<string> const extra_images::find(string const & name) const
42{
43 extra_images::matcher match(name);
44 return find(match);
45}
46
47
48vector<string> const
49extra_images::find(extra_images::matcher const & match) const
50{
51 vector<string> matches;
52
53 const_iterator cit = images.begin();
54 const_iterator end = images.end();
55
56 for (; cit != end; ++cit) {
57 if (match(cit->first))
58 matches.push_back(cit->second + '/' + cit->first);
59 }
60
61 return matches;
62}
63
64
65namespace {
66
67/**
68 * Function object for matching a module filename, which
69 * has its own special mangling rules in 2.6 kernels.
70 */
71struct module_matcher : public extra_images::matcher {
72public:
73 explicit module_matcher(string const & s)
74 : extra_images::matcher(s) {}
75
76 virtual bool operator()(string const & candidate) const {
77 if (candidate.length() != value.length())
78 return false;
79
80 for (string::size_type i = 0 ; i < value.length() ; ++i) {
81 if (value[i] == candidate[i])
82 continue;
83 if (value[i] == '_' &&
84 (candidate[i] == ',' || candidate[i] == '-'))
85 continue;
86 return false;
87 }
88
89 return true;
90 }
91};
92
93} // anon namespace
94
95
96string const find_image_path(string const & archive_path,
97 string const & image_name,
98 extra_images const & extra_images,
99 image_error & error)
100{
101 error = image_ok;
102
103 string const image = op_realpath(archive_path + image_name);
104
105 // simplest case
106 if (op_file_readable(image)) {
107 error = image_ok;
108 return image_name;
109 }
110
111 if (errno == EACCES) {
112 error = image_unreadable;
113 return image_name;
114 }
115
116 string const base = op_basename(image);
117
118 vector<string> result = extra_images.find(base);
119
120 // not found, try a module search
121 if (result.empty())
122 result = extra_images.find(module_matcher(base + ".ko"));
123
124 if (result.empty()) {
125 error = image_not_found;
126 return image_name;
127 }
128
129 if (result.size() > 1) {
130 error = image_multiple_match;
131 return image_name;
132 }
133
134 return result[0];
135}