| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- using Invercargill;
- namespace Usm {
- public class ResourceFinder {
- public Paths paths { get; set; }
- public ResourceFinder(Paths? paths = null) {
- this.paths = paths ?? new Paths();
- }
- public bool has_resource(ResourceRef resource_ref) {
- return locate_resource(resource_ref) != null;
- }
- public string? locate_resource(ResourceRef resource_ref) {
- switch (resource_ref.resource_type) {
- case ResourceType.ROOT_PATH:
- return locate_rootpath(resource_ref);
- case ResourceType.PATH:
- return locate_path(resource_ref);
- case ResourceType.OPTIONAL:
- return locate_opt(resource_ref);
- case ResourceType.RESOURCE:
- return locate_res(resource_ref);
- case ResourceType.CONFIGURATION:
- return locate_cfg(resource_ref);
- case ResourceType.BINARY:
- return locate_bin(resource_ref);
- case ResourceType.SUPER_BINARY:
- return locate_sbin(resource_ref);
- case ResourceType.LIBRARY:
- return locate_lib(resource_ref);
- case ResourceType.LIBRARY_EXECUTABLE:
- return locate_libexec(resource_ref);
- case ResourceType.LIBRARY_RESOURCE:
- return locate_libres(resource_ref);
- case ResourceType.CANONICAL_LIBRARY:
- return locate_canonlib(resource_ref);
- case ResourceType.CANONICAL_LIBRARY_RESOURCE:
- return locate_canonlibres(resource_ref);
- case ResourceType.GIO_MODULE:
- return locate_gio(resource_ref);
- case ResourceType.INFO_PAGE:
- return locate_info(resource_ref);
- case ResourceType.MANUAL_PAGE:
- return locate_man(resource_ref);
- case ResourceType.LOCALE:
- return locate_locale(resource_ref);
- case ResourceType.APPLICATION:
- return locate_app(resource_ref);
- case ResourceType.INCLUDE:
- return locate_inc(resource_ref);
- case ResourceType.PKG_CONFIG:
- return locate_pc(resource_ref);
- case ResourceType.VALA_API:
- return locate_vapi(resource_ref);
- case ResourceType.GOBJECT_IR:
- return locate_gir(resource_ref);
- case ResourceType.TYPELIB:
- return locate_typelib(resource_ref);
- case ResourceType.TAG:
- return locate_tag(resource_ref);
- default:
- assert_not_reached();
- }
- }
- private string? locate_tag(ResourceRef resource) {
- if(Tag.read(resource.resource) != null) {
- return paths.get_tag_file_path(resource.resource);
- }
- return null;
- }
- private string? locate_lib(ResourceRef resource) {
- var via_ldconfig = locate_lib_ldconfig(resource);
- if(via_ldconfig != null) {
- return via_ldconfig;
- }
- // musl systems have no `ldconfig -p` output to consult: fall
- // back to the conventional library directories
- foreach(var directory in new string[] { "/lib", "/usr/lib", "/lib64", "/usr/lib64" }) {
- var file = File.new_build_filename(directory, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_lib_ldconfig(ResourceRef resource) {
- try {
- var proc = new Subprocess.newv(new string[] { "ldconfig", "-p" },
- SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_SILENCE);
- var pipe = new DataInputStream(proc.get_stdout_pipe());
- string line = null;
- while((line = pipe.read_line()) != null) {
- if(line.has_prefix("\t")) {
- var name = line.substring(1).split(" ", 2)[0];
- if(resource.resource == name) {
- return line.substring(1).split("=>", 2)[1].chomp().chug();
- }
- }
- }
- proc.wait_check();
- }
- catch(Error e) {
- // busybox/musl ldconfig doesn't support -p; the fallback in
- // locate_lib handles it — suppress the noise
- }
- return null;
- }
- private string? locate_canonlib(ResourceRef resource) {
- try {
- var proc = new Subprocess.newv(new string[] { "ldconfig", "-p" },
- SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_SILENCE);
- var pipe = new DataInputStream(proc.get_stdout_pipe());
- string line = null;
- while((line = pipe.read_line()) != null) {
- if(line.has_prefix("\t")) {
- var name = line.substring(1).split(" ", 2)[0];
- // Only return true for libraries found in the canonical lib directory (e.g. not in /lib64)
- if(resource.resource == name && (name.has_prefix("/usr/lib") || name.has_prefix("/lib"))) {
- return line.substring(1).split("=>", 2)[1].chomp().chug();
- }
- }
- }
- proc.wait_check();
- }
- catch(Error e) {
- warning(@"Error checking for resource $resource: $(e.message)");
- }
- return null;
- }
- private string? locate_bin(ResourceRef resource) {
- var env_paths = Environment.get_variable("PATH").split(":");
- foreach (var path in env_paths) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_path(ResourceRef resource) {
- var file = File.new_build_filename(paths.destination, paths.prefix, resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_rootpath(ResourceRef resource) {
- var file = File.new_build_filename(paths.destination, resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_res(ResourceRef resource) {
- var file = File.new_build_filename(paths.destination, paths.prefix, paths.data, resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_opt(ResourceRef resource) {
- var file = File.new_build_filename(paths.destination, "opt", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_cfg(ResourceRef resource) {
- var file = File.new_build_filename(paths.destination, paths.sys_config, resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_libres(ResourceRef resource) {
- var search = new string[] { "/usr/lib", "/usr/lib64", "/lib", "/lib64" };
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_canonlibres(ResourceRef resource) {
- var search = new string[] { "/usr/lib", "/lib" };
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_gio(ResourceRef resource) {
- var search = Iterate.these("/usr/lib64/gio/modules", "/usr/lib/gio/modules");
- // Debian-style multiarch keeps GIO modules in
- // /usr/lib/<triple>/gio/modules, which no fixed path covers:
- // enumerate whatever multiarch directories exist
- try {
- foreach(var entry in Iterate.directory("/usr/lib")) {
- if(entry.contains("-linux-")) {
- search = search.concat(Wrap.array(new string[] { @"/usr/lib/$entry/gio/modules" }));
- }
- }
- }
- catch(FileError e) {
- }
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_app(ResourceRef resource) {
- var file = File.new_build_filename("/usr/share/applications", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_inc(ResourceRef resource) {
- var file = File.new_build_filename("/usr/include", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_sbin(ResourceRef resource) {
- var search = new string[] { "/usr/sbin", "/sbin" };
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_libexec(ResourceRef resource) {
- var file = File.new_build_filename("/usr/libexec", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_info(ResourceRef resource) {
- var file = File.new_build_filename("/usr/share/info", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_man(ResourceRef resource) {
- var file = File.new_build_filename("/usr/share/man", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_locale(ResourceRef resource) {
- var file = File.new_build_filename("/usr/share/locale", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_vapi(ResourceRef resource) {
- var search = new string[] { "/usr/share/vala/vapi", "/usr/share/vala-0.56/vapi" };
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_pc(ResourceRef resource) {
- var search = Iterate.these("/usr/lib/pkgconfig", "/usr/lib64/pkgconfig", "/usr/share/pkgconfig");
- // Debian-style multiarch keeps pkg-config files in
- // /usr/lib/<triple>/pkgconfig, which no fixed path covers:
- // enumerate whatever multiarch directories exist
- try {
- foreach(var entry in Iterate.directory("/usr/lib")) {
- if(entry.contains("-linux-")) {
- search = search.concat(Wrap.array(new string[] { @"/usr/lib/$entry/pkgconfig" }));
- }
- }
- }
- catch(FileError e) {
- }
- var env = Environment.get_variable("PKG_CONFIG_PATH");
- if(env != null) {
- search = search.concat(Wrap.array(env.split(":")));
- }
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- private string? locate_gir(ResourceRef resource) {
- var file = File.new_build_filename("/usr/share/gir", resource.resource);
- return file.query_exists() ? file.get_path() : null;
- }
- private string? locate_typelib(ResourceRef resource) {
- var search = new string[] { "/usr/lib64/girepository-1.0", "/usr/lib/girepository-1.0", "/lib64/girepository-1.0", "/lib/girepository-1.0" };
- foreach (var path in search) {
- var file = File.new_build_filename(paths.destination, path, resource.resource);
- if(file.query_exists()) {
- return file.get_path();
- }
- }
- return null;
- }
- }
- }
|