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