test/term/terminfo/
searcher.rs

1//! ncurses-compatible database discovery.
2//!
3//! Does not support hashed database, only filesystem!
4
5use std::path::PathBuf;
6use std::{env, fs};
7
8#[cfg(test)]
9mod tests;
10
11/// Returns path to database entry for `term`
12#[allow(deprecated)]
13pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
14    let mut dirs_to_search = Vec::new();
15    let first_char = term.chars().next()?;
16
17    // Find search directory
18    if let Some(dir) = env::var_os("TERMINFO") {
19        dirs_to_search.push(PathBuf::from(dir));
20    }
21
22    if let Ok(dirs) = env::var("TERMINFO_DIRS") {
23        for i in dirs.split(':') {
24            if i.is_empty() {
25                dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
26            } else {
27                dirs_to_search.push(PathBuf::from(i));
28            }
29        }
30    } else {
31        // Found nothing in TERMINFO_DIRS, use the default paths:
32        // According to /etc/terminfo/README, after looking at
33        // ~/.terminfo, ncurses will search /etc/terminfo, then
34        // /lib/terminfo, and eventually /usr/share/terminfo.
35        // On Haiku the database can be found at /boot/system/data/terminfo
36        if let Some(mut homedir) = env::home_dir() {
37            homedir.push(".terminfo");
38            dirs_to_search.push(homedir)
39        }
40
41        dirs_to_search.push(PathBuf::from("/etc/terminfo"));
42        dirs_to_search.push(PathBuf::from("/lib/terminfo"));
43        dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
44        dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
45    }
46
47    // Look for the terminal in all of the search directories
48    for mut p in dirs_to_search {
49        if fs::metadata(&p).is_ok() {
50            p.push(&first_char.to_string());
51            p.push(term);
52            if fs::metadata(&p).is_ok() {
53                return Some(p);
54            }
55            p.pop();
56            p.pop();
57
58            // on some installations the dir is named after the hex of the char
59            // (e.g., macOS)
60            p.push(&format!("{:x}", first_char as usize));
61            p.push(term);
62            if fs::metadata(&p).is_ok() {
63                return Some(p);
64            }
65        }
66    }
67    None
68}