heuristics.cc
1 /* 2 * heuristics.cc 3 * 4 * 5 */ 6 7 #include "version.h" 8 #include "sysfs.h" 9 #include "jedec.h" 10 #include "osutils.h" 11 12 #include <stdlib.h> 13 #include <regex.h> 14 15 __ID("@(#) $Id$"); 16 17 string guessBusInfo(const string & info) 18 { 19 // NVMe: "nvme"host"n"namespace 20 if(matches(info, "^nvme[0-9]+n[0-9]+$")) 21 { 22 string s = info; 23 size_t n = s.rfind("n"); 24 s[n] = ':'; 25 return "nvme@" + s.substr(4, string::npos); 26 } 27 28 // SD/MMC: "mmc"host:address 29 if(matches(info, "^mmc[0-9]+(:[[:xdigit:]]+)+$")) 30 { 31 return "mmc@" + info.substr(3, string::npos); 32 } 33 34 // 2.6-style PCI 35 if(matches(info,"^[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]\\.[[:xdigit:]]$")) 36 { 37 return "pci@" + info; 38 } 39 // 2.4-style PCI 40 if(matches(info,"^[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]\\.[[:xdigit:]]$")) 41 { 42 return "pci@0000:" + info; 43 } 44 45 // USB: host-port[.port]:config.interface 46 if(matches(info, "^[0-9]+-[0-9]+(\\.[0-9]+)*:[0-9]+\\.[0-9]+$")) 47 { 48 size_t colon = info.rfind(":"); 49 size_t dash = info.find("-"); 50 51 return "usb@" + info.substr(0, dash) + ":" + info.substr(dash+1, colon-dash-1); 52 } 53 54 if(matches(info, "^[[:xdigit:]]+-[0-9]+$")) // Firewire: guid-function 55 { 56 size_t dash = info.find("-"); 57 58 return "firewire@" + info.substr(0, dash); 59 } 60 61 #if 1 62 //#ifdef __hppa__ 63 if(matches(info, "^[0-9]+(:[0-9]+)*$")) // PA-RISC: x:y:z:t corresponds to /x/y/z/t 64 { 65 string result = "parisc@"; 66 67 for(unsigned i=0; i<info.length(); i++) 68 if(info[i] == ':') 69 result += '/'; 70 else 71 result += info[i]; 72 return result; 73 } 74 #endif 75 return ""; 76 } 77 78 79 static string guessParentBusInfo(const hwNode & child) 80 { 81 string sysfs_path = sysfs_finddevice(child.getLogicalName()); 82 vector < string > path; 83 string result = ""; 84 85 if(sysfs_path == "") return ""; 86 87 splitlines(sysfs_path, path, '/'); 88 89 if(path.size()>1) 90 path.pop_back(); 91 else 92 return ""; 93 94 while((result=="") && (path.size()>1)) 95 { 96 result = guessBusInfo(path[path.size()-1]); 97 path.pop_back(); 98 } 99 return result; 100 } 101 102 103 hwNode * guessParent(const hwNode & child, hwNode & base) 104 { 105 return base.findChildByBusInfo(guessParentBusInfo(child)); 106 } 107 108 static const char *disk_manufacturers[] = 109 { 110 "^ST(?!I\\ ).+", "Seagate", 111 "^STI\\ .+", "SimpleTech", 112 "^D...-.+", "IBM", 113 "^IBM.+", "IBM", 114 "^HITACHI.+", "Hitachi", 115 "^IC.+", "Hitachi", 116 "^HTS.+", "Hitachi", 117 "^FUJITSU.+", "Fujitsu", 118 "^MP.+", "Fujitsu", 119 "^TOSHIBA.+", "Toshiba", 120 "^MK.+", "Toshiba", 121 "^MAXTOR.+", "Maxtor", 122 "^Pioneer.+", "Pioneer", 123 "^PHILIPS.+", "Philips", 124 "^QUANTUM.+", "Quantum", 125 "FIREBALL.+", "Quantum", 126 "^WDC.+", "Western Digital", 127 "WD.+", "Western Digital", 128 "^VBOX.+", "VirtualBox", 129 NULL, NULL 130 }; 131 132 bool guessVendor(hwNode & device) 133 { 134 int i = 0; 135 bool result = false; 136 137 138 device.setVendor(jedec_resolve(device.getVendor())); 139 140 if(device.getVendor() != "") 141 return false; 142 143 144 if(device.getClass() == hw::disk) 145 while (disk_manufacturers[i]) 146 { 147 if (matches(device.getProduct().c_str(), disk_manufacturers[i], REG_ICASE)) 148 { 149 device.setVendor(disk_manufacturers[i + 1]); 150 result = true; 151 } 152 i += 2; 153 } 154 155 return result; 156 } 157 158 159 static string parsehex(const string & s) 160 { 161 unsigned int i = 0; 162 string result = ""; 163 164 if(matches(s,"^0x[[:xdigit:]][[:xdigit:]]+$")) 165 { 166 for(i=2; i<s.length(); i+=2) 167 { 168 string c = s.substr(i,2); 169 static char code[2]; 170 171 code[0] = strtol(c.c_str(), NULL, 16); 172 code[1] = '\0'; 173 174 if(code[0] < ' ') return s; 175 result += string(code); 176 } 177 } 178 else 179 return s; 180 181 return result; 182 } 183 184 bool guessProduct(hwNode & device) 185 { 186 string product = device.getProduct(); 187 188 if(product == "") 189 return false; 190 191 device.setProduct(parsehex(product)); 192 193 return true; 194 } 195