blob: 26b14b341934f423b1008467c5e08bc10d0bc6af [file] [log] [blame]
/**
* @file locate_images.cpp
* Command-line helper
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author Philippe Elie
* @author John Levon
*/
#include "file_manip.h"
#include "locate_images.h"
#include <cerrno>
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
void extra_images::populate(vector<string> const & paths)
{
vector<string>::const_iterator cit = paths.begin();
vector<string>::const_iterator end = paths.end();
for (; cit != end; ++cit) {
string const path = op_realpath(*cit);
list<string> file_list;
create_file_list(file_list, path, "*", true);
list<string>::const_iterator lit = file_list.begin();
list<string>::const_iterator lend = file_list.end();
for (; lit != lend; ++lit) {
value_type v(op_basename(*lit), op_dirname(*lit));
images.insert(v);
}
}
}
vector<string> const extra_images::find(string const & name) const
{
extra_images::matcher match(name);
return find(match);
}
vector<string> const
extra_images::find(extra_images::matcher const & match) const
{
vector<string> matches;
const_iterator cit = images.begin();
const_iterator end = images.end();
for (; cit != end; ++cit) {
if (match(cit->first))
matches.push_back(cit->second + '/' + cit->first);
}
return matches;
}
namespace {
/**
* Function object for matching a module filename, which
* has its own special mangling rules in 2.6 kernels.
*/
struct module_matcher : public extra_images::matcher {
public:
explicit module_matcher(string const & s)
: extra_images::matcher(s) {}
virtual bool operator()(string const & candidate) const {
if (candidate.length() != value.length())
return false;
for (string::size_type i = 0 ; i < value.length() ; ++i) {
if (value[i] == candidate[i])
continue;
if (value[i] == '_' &&
(candidate[i] == ',' || candidate[i] == '-'))
continue;
return false;
}
return true;
}
};
} // anon namespace
string const find_image_path(string const & archive_path,
string const & image_name,
extra_images const & extra_images,
image_error & error)
{
error = image_ok;
string const image = op_realpath(archive_path + image_name);
// simplest case
if (op_file_readable(image)) {
error = image_ok;
return image_name;
}
if (errno == EACCES) {
error = image_unreadable;
return image_name;
}
string const base = op_basename(image);
vector<string> result = extra_images.find(base);
// not found, try a module search
if (result.empty())
result = extra_images.find(module_matcher(base + ".ko"));
if (result.empty()) {
error = image_not_found;
return image_name;
}
if (result.size() > 1) {
error = image_multiple_match;
return image_name;
}
return result[0];
}