ResourceRef.vala 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using Invercargill;
  2. using Invercargill.Convert;
  3. namespace Usm {
  4. public enum ResourceType {
  5. RESOURCE,
  6. BINARY,
  7. SUPER_BINARY,
  8. LIBRARY,
  9. LIBRARY_EXECUTABLE,
  10. LIBRARY_RESOURCE,
  11. INFO_PAGE,
  12. MANUAL_PAGE,
  13. LOCALE,
  14. APPLICATION,
  15. INCLUDE,
  16. PKG_CONFIG,
  17. VALA_API;
  18. public string to_string() {
  19. switch (this) {
  20. case ResourceType.RESOURCE:
  21. return "res";
  22. case ResourceType.BINARY:
  23. return "bin";
  24. case ResourceType.SUPER_BINARY:
  25. return "sbin";
  26. case ResourceType.LIBRARY:
  27. return "lib";
  28. case ResourceType.LIBRARY_EXECUTABLE:
  29. return "libexec";
  30. case ResourceType.LIBRARY_RESOURCE:
  31. return "libres";
  32. case ResourceType.INFO_PAGE:
  33. return "info";
  34. case ResourceType.MANUAL_PAGE:
  35. return "man";
  36. case ResourceType.LOCALE:
  37. return "locale";
  38. case ResourceType.APPLICATION:
  39. return "app";
  40. case ResourceType.INCLUDE:
  41. return "inc";
  42. case ResourceType.PKG_CONFIG:
  43. return "pc";
  44. case ResourceType.VALA_API:
  45. return "vapi";
  46. default:
  47. assert_not_reached();
  48. }
  49. }
  50. public static ResourceType from_string(string str) throws ManifestError {
  51. switch (str) {
  52. case "res":
  53. return ResourceType.RESOURCE;
  54. case "bin":
  55. return ResourceType.BINARY;
  56. case "sbin":
  57. return ResourceType.SUPER_BINARY;
  58. case "lib":
  59. return ResourceType.LIBRARY;
  60. case "libexec":
  61. return ResourceType.LIBRARY_EXECUTABLE;
  62. case "libres":
  63. return ResourceType.LIBRARY_RESOURCE;
  64. case "info":
  65. return ResourceType.INFO_PAGE;
  66. case "man":
  67. return ResourceType.MANUAL_PAGE;
  68. case "locale":
  69. return ResourceType.LOCALE;
  70. case "app":
  71. return ResourceType.APPLICATION;
  72. case "inc":
  73. return ResourceType.INCLUDE;
  74. case "pc":
  75. return ResourceType.PKG_CONFIG;
  76. case "vapi":
  77. return ResourceType.VALA_API;
  78. default:
  79. throw new ManifestError.INVALID_RESOURCE_TYPE(@"Unknown resource type \"$str\".");
  80. }
  81. }
  82. }
  83. public class ResourceRef : Hashable, Equatable<ResourceRef> {
  84. public string resource { get; set; }
  85. public ResourceType resource_type { get; set; }
  86. public ResourceRef(string str) throws ManifestError {
  87. var parts = str.split(":", 2);
  88. resource_type = ResourceType.from_string(parts[0]);
  89. resource = parts[1];
  90. }
  91. public uint hash_code() {
  92. return to_string().hash();
  93. }
  94. public bool equals(ResourceRef other) {
  95. return this == other || (this.resource == other.resource && this.resource_type == other.resource_type);
  96. }
  97. public string to_string() {
  98. return @"$resource_type:$resource";
  99. }
  100. public bool is_satisfied() {
  101. switch (resource_type) {
  102. case ResourceType.RESOURCE:
  103. return check_res();
  104. case ResourceType.BINARY:
  105. return check_bin();
  106. case ResourceType.SUPER_BINARY:
  107. return check_sbin();
  108. case ResourceType.LIBRARY:
  109. return check_lib();
  110. case ResourceType.LIBRARY_EXECUTABLE:
  111. return check_libexec();
  112. case ResourceType.LIBRARY_RESOURCE:
  113. return check_libres();
  114. case ResourceType.INFO_PAGE:
  115. return check_info();
  116. case ResourceType.MANUAL_PAGE:
  117. return check_man();
  118. case ResourceType.LOCALE:
  119. return check_locale();
  120. case ResourceType.APPLICATION:
  121. return check_app();
  122. case ResourceType.INCLUDE:
  123. return check_inc();
  124. case ResourceType.PKG_CONFIG:
  125. return check_pc();
  126. case ResourceType.VALA_API:
  127. return check_vapi();
  128. default:
  129. assert_not_reached();
  130. }
  131. }
  132. private bool check_lib() {
  133. try {
  134. var proc = new Subprocess.newv(new string[] { "ldconfig", "-p" }, SubprocessFlags.STDOUT_PIPE);
  135. var pipe = new DataInputStream(proc.get_stdout_pipe());
  136. string line = null;
  137. while((line = pipe.read_line()) != null) {
  138. if(line.has_prefix("\t")) {
  139. var name = line.substring(1).split(" ", 2)[0];
  140. if(resource == name) {
  141. return true;
  142. }
  143. }
  144. }
  145. proc.wait_check();
  146. }
  147. catch(Error e) {
  148. warning(@"Error checking for resource $this: $(e.message)");
  149. }
  150. return false;
  151. }
  152. private bool check_bin() {
  153. var paths = Environment.get_variable("PATH").split(":");
  154. foreach (var path in paths) {
  155. var file = File.new_build_filename(path, resource);
  156. if(file.query_exists()) {
  157. return true;
  158. }
  159. }
  160. return false;
  161. }
  162. private bool check_res() {
  163. var file = File.new_build_filename("/", resource);
  164. return file.query_exists();
  165. }
  166. private bool check_libres() {
  167. var paths = new string[] { "/usr/lib", "/usr/lib64", "/lib", "/lib64" };
  168. foreach (var path in paths) {
  169. var file = File.new_build_filename(path, resource);
  170. if(file.query_exists()) {
  171. return true;
  172. }
  173. }
  174. return false;
  175. }
  176. private bool check_app() {
  177. var file = File.new_build_filename("/usr/share/applications", resource);
  178. return file.query_exists();
  179. }
  180. private bool check_inc() {
  181. var file = File.new_build_filename("/usr/include", resource);
  182. return file.query_exists();
  183. }
  184. private bool check_sbin() {
  185. var paths = new string[] { "/usr/sbin", "/sbin" };
  186. foreach (var path in paths) {
  187. var file = File.new_build_filename(path, resource);
  188. if(file.query_exists()) {
  189. return true;
  190. }
  191. }
  192. return false;
  193. }
  194. private bool check_libexec() {
  195. var file = File.new_build_filename("/usr/libexec", resource);
  196. return file.query_exists();
  197. }
  198. private bool check_info() {
  199. var file = File.new_build_filename("/usr/share/info", resource);
  200. return file.query_exists();
  201. }
  202. private bool check_man() {
  203. var file = File.new_build_filename("/usr/share/man", resource);
  204. return file.query_exists();
  205. }
  206. private bool check_locale() {
  207. var file = File.new_build_filename("/usr/share/locale", resource);
  208. return file.query_exists();
  209. }
  210. private bool check_vapi() {
  211. var paths = new string[] { "/usr/share/vala/vapi", "/usr/share/vala-0.56/vapi" };
  212. foreach (var path in paths) {
  213. var file = File.new_build_filename(path, resource);
  214. if(file.query_exists()) {
  215. return true;
  216. }
  217. }
  218. return false;
  219. }
  220. private bool check_pc() {
  221. var paths = ate(new string[] { "/usr/lib/pkgconfig", "/usr/lib64/pkgconfig", "/usr/share/pkgconfig" });
  222. var env = Environment.get_variable("PKG_CONFIG_PATH");
  223. if(env != null) {
  224. paths = paths.concat(ate(env.split(":")));
  225. }
  226. foreach (var path in paths) {
  227. var file = File.new_build_filename(path, resource);
  228. if(file.query_exists()) {
  229. return true;
  230. }
  231. }
  232. return false;
  233. }
  234. }
  235. }