mod.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. use std::fs::File;
  2. use std::io::{self, BufRead};
  3. use std::sync::{Arc, Mutex};
  4. use crate::error::parse_error::ParseErrorType;
  5. use crate::manager::UnitManager;
  6. use crate::unit::timer::TimerUnitAttr;
  7. use crate::unit::{BaseUnit, Unit};
  8. use crate::DRAGON_REACH_UNIT_DIR;
  9. use crate::{
  10. error::parse_error::ParseError,
  11. unit::{service::ServiceUnitAttr, BaseUnitAttr, InstallUnitAttr, UnitType},
  12. };
  13. use hashbrown::HashMap;
  14. use lazy_static::lazy_static;
  15. use self::parse_service::ServiceParser;
  16. use self::parse_target::TargetParser;
  17. use self::parse_timer::TimerParser;
  18. use self::parse_util::UnitParseUtil;
  19. pub mod graph;
  20. pub mod parse_service;
  21. pub mod parse_target;
  22. pub mod parse_timer;
  23. pub mod parse_util;
  24. //对应Unit段类型
  25. #[derive(PartialEq, Clone, Copy)]
  26. pub enum Segment {
  27. None,
  28. Unit,
  29. Install,
  30. Service,
  31. Timer,
  32. }
  33. lazy_static! {
  34. pub static ref UNIT_SUFFIX: HashMap<&'static str, UnitType> = {
  35. let mut table = HashMap::new();
  36. table.insert("automount", UnitType::Automount);
  37. table.insert("device", UnitType::Device);
  38. table.insert("mount", UnitType::Mount);
  39. table.insert("path", UnitType::Path);
  40. table.insert("scope", UnitType::Scope);
  41. table.insert("service", UnitType::Service);
  42. table.insert("slice", UnitType::Automount);//疑似copy错了,稍后修改
  43. table.insert("automount", UnitType::Slice);//
  44. table.insert("socket", UnitType::Socket);
  45. table.insert("swap", UnitType::Swap);
  46. table.insert("target", UnitType::Target);
  47. table.insert("timer", UnitType::Timer);
  48. table
  49. };
  50. pub static ref SEGMENT_TABLE: HashMap<&'static str, Segment> = {
  51. let mut table = HashMap::new();
  52. table.insert("[Unit]", Segment::Unit);
  53. table.insert("[Install]", Segment::Install);
  54. table.insert("[Service]", Segment::Service);
  55. table.insert("[Timer]", Segment::Timer);
  56. // 后续再添加需求的具体字段
  57. table
  58. };
  59. pub static ref INSTALL_UNIT_ATTR_TABLE: HashMap<&'static str, InstallUnitAttr> = {
  60. let mut unit_attr_table = HashMap::new();
  61. unit_attr_table.insert("WantedBy", InstallUnitAttr::WantedBy);
  62. unit_attr_table.insert("RequiredBy", InstallUnitAttr::RequiredBy);
  63. unit_attr_table.insert("Also", InstallUnitAttr::Also);
  64. unit_attr_table.insert("Alias", InstallUnitAttr::Alias);
  65. unit_attr_table
  66. };
  67. pub static ref SERVICE_UNIT_ATTR_TABLE: HashMap<&'static str, ServiceUnitAttr> = {
  68. let mut unit_attr_table = HashMap::new();
  69. unit_attr_table.insert("Type", ServiceUnitAttr::Type);
  70. unit_attr_table.insert("RemainAfterExit", ServiceUnitAttr::RemainAfterExit);
  71. unit_attr_table.insert("ExecStart", ServiceUnitAttr::ExecStart);
  72. unit_attr_table.insert("ExecStartPre", ServiceUnitAttr::ExecStartPre);
  73. unit_attr_table.insert("ExecStartPos", ServiceUnitAttr::ExecStartPos);
  74. unit_attr_table.insert("ExecReload", ServiceUnitAttr::ExecReload);
  75. unit_attr_table.insert("ExecStop", ServiceUnitAttr::ExecStop);
  76. unit_attr_table.insert("ExecStopPost", ServiceUnitAttr::ExecStopPost);
  77. unit_attr_table.insert("RestartSec", ServiceUnitAttr::RestartSec);
  78. unit_attr_table.insert("Restart", ServiceUnitAttr::Restart);
  79. unit_attr_table.insert("TimeoutStartSec", ServiceUnitAttr::TimeoutStartSec);
  80. unit_attr_table.insert("TimeoutStopSec", ServiceUnitAttr::TimeoutStopSec);
  81. unit_attr_table.insert("Environment", ServiceUnitAttr::Environment);
  82. unit_attr_table.insert("EnvironmentFile", ServiceUnitAttr::EnvironmentFile);
  83. unit_attr_table.insert("Nice", ServiceUnitAttr::Nice);
  84. unit_attr_table.insert("WorkingDirectory", ServiceUnitAttr::WorkingDirectory);
  85. unit_attr_table.insert("RootDirectory", ServiceUnitAttr::RootDirectory);
  86. unit_attr_table.insert("User", ServiceUnitAttr::User);
  87. unit_attr_table.insert("Group", ServiceUnitAttr::Group);
  88. unit_attr_table.insert("MountFlags", ServiceUnitAttr::MountFlags);
  89. unit_attr_table
  90. };
  91. pub static ref BASE_UNIT_ATTR_TABLE: HashMap<&'static str, BaseUnitAttr> = {
  92. let mut unit_attr_table = HashMap::new();
  93. unit_attr_table.insert("Description", BaseUnitAttr::Description);
  94. unit_attr_table.insert("Documentation", BaseUnitAttr::Documentation);
  95. unit_attr_table.insert("Requires", BaseUnitAttr::Requires);
  96. unit_attr_table.insert("Wants", BaseUnitAttr::Wants);
  97. unit_attr_table.insert("After", BaseUnitAttr::After);
  98. unit_attr_table.insert("Before", BaseUnitAttr::Before);
  99. unit_attr_table.insert("Binds To", BaseUnitAttr::BindsTo);
  100. unit_attr_table.insert("Part Of", BaseUnitAttr::PartOf);
  101. unit_attr_table.insert("OnFailure", BaseUnitAttr::OnFailure);
  102. unit_attr_table.insert("Conflicts", BaseUnitAttr::Conflicts);
  103. unit_attr_table
  104. };
  105. pub static ref BASE_IEC: HashMap<&'static str, u64> = {
  106. let mut table = HashMap::new();
  107. table.insert(
  108. "E",
  109. 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64,
  110. );
  111. table.insert("P", 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64);
  112. table.insert("T", 1024u64 * 1024u64 * 1024u64 * 1024u64);
  113. table.insert("G", 1024u64 * 1024u64 * 1024u64);
  114. table.insert("M", 1024u64 * 1024u64);
  115. table.insert("K", 1024u64);
  116. table.insert("B", 1u64);
  117. table.insert("", 1u64);
  118. table
  119. };
  120. pub static ref BASE_SI: HashMap<&'static str, u64> = {
  121. let mut table = HashMap::new();
  122. table.insert(
  123. "E",
  124. 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64,
  125. );
  126. table.insert("P", 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64);
  127. table.insert("T", 1000u64 * 1000u64 * 1000u64 * 1000u64);
  128. table.insert("G", 1000u64 * 1000u64 * 1000u64);
  129. table.insert("M", 1000u64 * 1000u64);
  130. table.insert("K", 1000u64);
  131. table.insert("B", 1u64);
  132. table.insert("", 1u64);
  133. table
  134. };
  135. pub static ref SEC_UNIT_TABLE: HashMap<&'static str, u64> = {
  136. let mut table = HashMap::new();
  137. table.insert("h", 60 * 60 * 1000 * 1000 * 1000);
  138. table.insert("min", 60 * 1000 * 1000 * 1000);
  139. table.insert("m", 60 * 1000 * 1000 * 1000);
  140. table.insert("s", 1000 * 1000 * 1000);
  141. table.insert("", 1000 * 1000 * 1000);
  142. table.insert("ms", 1000 * 1000);
  143. table.insert("us", 1000);
  144. table.insert("ns", 1);
  145. table
  146. };
  147. pub static ref TIMER_UNIT_ATTR_TABLE: HashMap<&'static str, TimerUnitAttr> = {
  148. let mut map = HashMap::new();
  149. // map.insert("State", TimerUnitAttr::State);
  150. // map.insert("Result", TimerUnitAttr::Result);
  151. map.insert("OnActiveSec", TimerUnitAttr::OnActiveSec);
  152. map.insert("OnBootSec", TimerUnitAttr::OnBootSec);
  153. map.insert("OnStartupSec", TimerUnitAttr::OnStartUpSec);
  154. map.insert("OnUnitActiveSec", TimerUnitAttr::OnUnitActiveSec);
  155. map.insert("OnUnitInactiveSec", TimerUnitAttr::OnUnitInactiveSec);
  156. map.insert("OnCalendar", TimerUnitAttr::OnCalendar);
  157. map.insert("AccuracySec", TimerUnitAttr::AccuarcySec);
  158. map.insert("RandomizedDelaySec", TimerUnitAttr::RandomizedDelaySec);
  159. map.insert("FixedRandomDelay", TimerUnitAttr::FixedRandomDelay);
  160. map.insert("OnClockChange", TimerUnitAttr::OnClockChange);
  161. map.insert("OnTimezoneChange", TimerUnitAttr::OnTimeZoneChange);
  162. map.insert("Unit", TimerUnitAttr::Unit);
  163. map.insert("Persistent", TimerUnitAttr::Persistent);
  164. map.insert("WakeSystem", TimerUnitAttr::WakeSystem);
  165. map.insert("RemainAfterElapse", TimerUnitAttr::RemainAfterElapse);
  166. map
  167. };
  168. }
  169. //用于解析Unit共有段的方法
  170. pub struct UnitParser;
  171. impl UnitParser {
  172. /// @brief 从path获取到BufReader,此方法将会检验文件类型
  173. ///
  174. /// 如果指定UnitType,则进行文件名检查
  175. ///
  176. /// @param path 需解析的文件路径
  177. ///
  178. /// @param unit_type 指定Unit类型
  179. ///
  180. /// @return 成功则返回对应BufReader,否则返回Err
  181. pub fn get_reader(path: &str, unit_type: UnitType) -> Result<io::BufReader<File>, ParseError> {
  182. //判断是否为路径,若不为路径则到定向到默认unit文件夹
  183. let mut realpath = path.to_string();
  184. if !path.contains('/') {
  185. realpath = format!("{}{}", DRAGON_REACH_UNIT_DIR, &path).to_string();
  186. }
  187. let path = realpath.as_str();
  188. // 如果指定UnitType,则进行文件名检查,不然直接返回reader
  189. if unit_type != UnitType::Unknown {
  190. let suffix = match path.rfind('.') {
  191. Some(idx) => &path[idx + 1..],
  192. None => {
  193. return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
  194. }
  195. };
  196. let u_type = UNIT_SUFFIX.get(suffix);
  197. if u_type.is_none() {
  198. return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
  199. }
  200. if *(u_type.unwrap()) != unit_type {
  201. return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
  202. }
  203. }
  204. let file = match File::open(path) {
  205. Ok(file) => file,
  206. Err(_) => {
  207. return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
  208. }
  209. };
  210. return Ok(io::BufReader::new(file));
  211. }
  212. pub fn from_path(path: &str) -> Result<usize, ParseError> {
  213. let unit_type = UnitParseUtil::parse_type(&path);
  214. match unit_type {
  215. UnitType::Service => ServiceParser::parse(path),
  216. UnitType::Target => TargetParser::parse(path),
  217. UnitType::Timer => TimerParser::parse(path), //新实现的timer_unit
  218. _ => Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0)),
  219. }
  220. }
  221. /// @brief 将path路径的文件解析为unit_type类型的Unit
  222. ///
  223. /// 该方法解析每个Unit共有的段(Unit,Install),其余独有的段属性将会交付T类型的Unit去解析
  224. ///
  225. /// @param path 需解析的文件路径
  226. ///
  227. /// @param unit_type 指定Unit类型
  228. ///
  229. /// @return 解析成功则返回Ok(Arc<T>),否则返回Err
  230. pub fn parse<T: Unit + Default + Clone + 'static>(
  231. path: &str,
  232. unit_type: UnitType,
  233. ) -> Result<usize, ParseError> {
  234. let name = match path.rfind("/") {
  235. Some(size) => String::from(&path[size..]),
  236. None => String::from(path),
  237. };
  238. // 如果该文件已解析过,则直接返回id
  239. if UnitManager::contains_name(&name) {
  240. let unit = UnitManager::get_unit_with_name(&name).unwrap();
  241. let unit = unit.lock().unwrap();
  242. return Ok(unit.unit_id());
  243. }
  244. let mut unit: T = T::default();
  245. let mut unit_base = BaseUnit::default();
  246. //设置unit类型标记
  247. unit_base.set_unit_type(unit_type);
  248. let reader = UnitParser::get_reader(path, unit_type)?;
  249. //用于记录当前段的类型
  250. let mut segment = Segment::None;
  251. //用于处理多行对应一个属性的情况
  252. let _last_attr = ServiceUnitAttr::None;
  253. //一行一行向下解析
  254. let lines = reader
  255. .lines()
  256. .map(|line| line.unwrap())
  257. .collect::<Vec<String>>();
  258. let mut i = 0;
  259. while i < lines.len() {
  260. let line = &lines[i];
  261. //空行跳过
  262. if line.chars().all(char::is_whitespace) {
  263. i += 1;
  264. continue;
  265. }
  266. //注释跳过
  267. if line.starts_with('#') {
  268. i += 1;
  269. continue;
  270. }
  271. let mut line = line.trim();
  272. let segment_flag = SEGMENT_TABLE.get(&line);
  273. if !segment_flag.is_none() {
  274. //如果当前行匹配到的为段名,则切换段类型继续匹配下一行
  275. segment = *segment_flag.unwrap();
  276. i += 1;
  277. continue;
  278. }
  279. if segment == Segment::None {
  280. //未找到段名则不能继续匹配
  281. return Err(ParseError::new(
  282. ParseErrorType::ESyntaxError,
  283. path.to_string(),
  284. i + 1,
  285. ));
  286. }
  287. //下面进行属性匹配
  288. //合并多行为一个属性的情况
  289. //最后一个字符为\,代表换行,将多行转换为一行统一解析
  290. let mut templine = String::new();
  291. if lines[i].ends_with('\\') {
  292. while lines[i].ends_with('\\') {
  293. let temp = &lines[i][..lines[i].len() - 1];
  294. templine = format!("{} {}", templine, temp);
  295. i += 1;
  296. }
  297. templine = format!("{} {}", templine, lines[i]);
  298. line = templine.as_str();
  299. i += 1;
  300. }
  301. //=号分割后第一个元素为属性,后面的均为值
  302. let (attr_str, val_str) = match line.find('=') {
  303. Some(idx) => (line[..idx].trim(), line[idx + 1..].trim()),
  304. None => {
  305. return Err(ParseError::new(
  306. ParseErrorType::ESyntaxError,
  307. path.to_string(),
  308. i + 1,
  309. ));
  310. }
  311. };
  312. //首先匹配所有unit文件都有的unit段和install段
  313. if BASE_UNIT_ATTR_TABLE.get(attr_str).is_some() {
  314. //匹配Unit字段
  315. if segment != Segment::Unit {
  316. return Err(ParseError::new(
  317. ParseErrorType::EINVAL,
  318. path.to_string(),
  319. i + 1,
  320. ));
  321. }
  322. if let Err(e) = unit_base
  323. .set_unit_part_attr(BASE_UNIT_ATTR_TABLE.get(attr_str).unwrap(), val_str)
  324. {
  325. let mut e = e.clone();
  326. e.set_file(path);
  327. e.set_linenum(i + 1);
  328. return Err(e);
  329. }
  330. } else if INSTALL_UNIT_ATTR_TABLE.get(attr_str).is_some() {
  331. //匹配Install字段
  332. if segment != Segment::Install {
  333. return Err(ParseError::new(
  334. ParseErrorType::EINVAL,
  335. path.to_string(),
  336. i + 1,
  337. ));
  338. }
  339. if let Err(e) = unit_base
  340. .set_install_part_attr(INSTALL_UNIT_ATTR_TABLE.get(attr_str).unwrap(), val_str)
  341. {
  342. let mut e = e.clone();
  343. e.set_file(path);
  344. e.set_linenum(i + 1);
  345. return Err(e);
  346. }
  347. } else {
  348. if let Err(e) = unit.set_attr(segment, attr_str, val_str) {
  349. let mut e = e.clone();
  350. e.set_file(path);
  351. e.set_linenum(i + 1);
  352. return Err(e);
  353. }
  354. }
  355. i += 1;
  356. }
  357. unit.set_unit_base(unit_base);
  358. unit.set_unit_name(name.clone());
  359. let id = unit.set_unit_id();
  360. unit.init();
  361. let dret: Arc<Mutex<dyn Unit>> = Arc::new(Mutex::new(unit));
  362. UnitManager::insert_unit_with_id(id, dret);
  363. UnitManager::insert_into_name_table(&name, id);
  364. return Ok(id);
  365. }
  366. }