term/terminfo/searcher.rs
1// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! ncurses-compatible database discovery
12//!
13//! Does not support hashed database, only filesystem!
14
15use std::env;
16use std::fs;
17use std::path::PathBuf;
18
19/// Return path to database entry for `term`
20pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
21 let mut dirs_to_search = Vec::new();
22 let first_char = match term.chars().next() {
23 Some(c) => c,
24 None => return None,
25 };
26
27 // Find search directory
28 // The terminfo manual says:
29 //
30 // > If the environment variable TERMINFO is set, it is interpreted
31 // > as the pathname of a directory containing the compiled description
32 // > you are working on. Only that directory is searched.
33 //
34 // However, the ncurses manual says:
35 //
36 // > If the environment variable TERMINFO is defined, any program using
37 // > curses checks for a local terminal definition before checking in
38 // > the standard place.
39 //
40 // Given that ncurses is the defacto standard, we follow the ncurses manual.
41 if let Some(dir) = env::var_os("TERMINFO") {
42 dirs_to_search.push(PathBuf::from(dir));
43 }
44
45 if let Ok(dirs) = env::var("TERMINFO_DIRS") {
46 for i in dirs.split(':') {
47 if i == "" {
48 dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
49 } else {
50 dirs_to_search.push(PathBuf::from(i));
51 }
52 }
53 } else {
54 // Found nothing in TERMINFO_DIRS, use the default paths:
55 // According to /etc/terminfo/README, after looking at
56 // ~/.terminfo, ncurses will search /etc/terminfo, then
57 // /lib/terminfo, and eventually /usr/share/terminfo.
58 // On Haiku the database can be found at /boot/system/data/terminfo
59 if let Some(mut homedir) = env::home_dir() {
60 homedir.push(".terminfo");
61 dirs_to_search.push(homedir)
62 }
63
64 dirs_to_search.push(PathBuf::from("/etc/terminfo"));
65 dirs_to_search.push(PathBuf::from("/lib/terminfo"));
66 dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
67 dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
68 }
69
70 // Look for the terminal in all of the search directories
71 for mut p in dirs_to_search {
72 if fs::metadata(&p).is_ok() {
73 p.push(&first_char.to_string());
74 p.push(&term);
75 if fs::metadata(&p).is_ok() {
76 return Some(p);
77 }
78 p.pop();
79 p.pop();
80
81 // on some installations the dir is named after the hex of the char
82 // (e.g. OS X)
83 p.push(&format!("{:x}", first_char as usize));
84 p.push(term);
85 if fs::metadata(&p).is_ok() {
86 return Some(p);
87 }
88 }
89 }
90 None
91}