locate_images.cpp revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/**
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}
136