1use crate::idl;
3use crate::norm::Normalizer;
4use crate::osrf::conf;
5use crate::osrf::conf::LogFile;
6use crate::osrf::logging;
7use crate::osrf::sclient::HostSettings;
8use crate::Client;
9use crate::EgResult;
10use daemonize;
11use std::env;
12use std::fs::File;
13
14const DEFAULT_OSRF_CONFIG: &str = "/openils/conf/opensrf_core.xml";
15const DEFAULT_IDL_PATH: &str = "/openils/conf/fm_IDL.xml";
16
17#[derive(Default)]
18pub struct InitOptions {
19 pub skip_logging: bool,
22
23 pub skip_host_settings: bool,
25
26 pub appname: Option<String>,
28}
29
30impl InitOptions {
31 pub fn new() -> InitOptions {
32 Default::default()
33 }
34}
35
36pub fn init() -> EgResult<Client> {
40 with_options(&InitOptions::new())
41}
42
43fn maybe_daemonize() -> EgResult<()> {
46 let pid_file = match env::var("OSRF_PID_FILE") {
48 Ok(f) => f,
49 Err(_) => return Ok(()),
50 };
51
52 let out_file = match env::var("OSRF_STDERR_FILE") {
53 Ok(f) => f.to_string(),
54 Err(_) => format!("{pid_file}.stderr"),
55 };
56
57 let stdout_file =
59 File::create(&out_file).map_err(|e| format!("Cannot create stderr file: {e}"))?;
60
61 let stderr_file =
62 File::create(out_file).map_err(|e| format!("Cannot create stderr file: {e}"))?;
63
64 let daemon = daemonize::Daemonize::new()
65 .pid_file(pid_file)
66 .chown_pid_file(true) .working_directory("/tmp") .stdout(stdout_file)
69 .stderr(stderr_file);
70
71 daemon
72 .start()
73 .map_err(|e| format!("Cannot daemonize:, {e}").into())
74}
75
76pub fn osrf_init(options: &InitOptions) -> EgResult<Client> {
79 maybe_daemonize()?;
80
81 let builder = if let Ok(fname) = env::var("OSRF_CONFIG") {
82 conf::ConfigBuilder::from_file(&fname)?
83 } else {
84 conf::ConfigBuilder::from_file(DEFAULT_OSRF_CONFIG)?
85 };
86
87 let mut config = builder.build()?;
88
89 if env::var("OSRF_LOCALHOST").is_ok() {
90 config.set_hostname("localhost");
91 } else if let Ok(v) = env::var("OSRF_HOSTNAME") {
92 config.set_hostname(&v);
93 }
94
95 if env::var("OSRF_LOG_STDOUT").is_ok() {
96 config
97 .client_mut()
98 .logging_mut()
99 .set_log_file(LogFile::Stdout);
100 }
101
102 if let Ok(level) = env::var("OSRF_LOG_LEVEL") {
107 config.client_mut().logging_mut().set_log_level(&level);
108 if let Some(gateway) = config.gateway_mut() {
109 gateway.logging_mut().set_log_level(&level);
110 }
111 for router in config.routers_mut() {
112 router.client_mut().logging_mut().set_log_level(&level);
113 }
114 }
115
116 if let Ok(facility) = env::var("OSRF_LOG_FACILITY") {
117 config
118 .client_mut()
119 .logging_mut()
120 .set_syslog_facility(&facility)?;
121 if let Some(gateway) = config.gateway_mut() {
122 gateway.logging_mut().set_syslog_facility(&facility)?;
123 }
124 for router in config.routers_mut() {
125 router
126 .client_mut()
127 .logging_mut()
128 .set_syslog_facility(&facility)?;
129 }
130 }
131
132 if let Ok(username) = env::var("OSRF_BUS_USERNAME") {
133 config.client_mut().set_username(&username);
134 if let Some(gateway) = config.gateway_mut() {
135 gateway.set_username(&username);
136 }
137 for router in config.routers_mut() {
138 router.client_mut().set_username(&username);
139 }
140 }
141
142 if let Ok(password) = env::var("OSRF_BUS_PASSWORD") {
143 config.client_mut().set_password(&password);
144 if let Some(gateway) = config.gateway_mut() {
145 gateway.set_password(&password);
146 }
147 for router in config.routers_mut() {
148 router.client_mut().set_password(&password);
149 }
150 }
151
152 if !options.skip_logging {
153 let mut logger = logging::Logger::new(config.client().logging())?;
154 if let Some(name) = options.appname.as_ref() {
155 logger.set_application(name);
156 }
157 logger
158 .init()
159 .map_err(|e| format!("Error initializing logger: {e}"))?;
160 }
161
162 config.store()?;
164
165 let client = Client::connect()?;
166
167 if !options.skip_host_settings {
172 HostSettings::load(&client)?;
173 }
174
175 Ok(client)
176}
177
178pub fn with_options(options: &InitOptions) -> EgResult<Client> {
179 let client = osrf_init(options)?;
180
181 Normalizer::init();
183
184 load_idl()?;
185
186 Ok(client)
187}
188
189pub fn load_idl() -> EgResult<()> {
191 if let Ok(v) = env::var("EG_IDL_FILE") {
192 return idl::Parser::load_file(&v);
193 }
194
195 if HostSettings::is_loaded() {
196 if let Some(fname) = HostSettings::get("/IDL")?.as_str() {
197 return idl::Parser::load_file(fname);
198 }
199 }
200
201 idl::Parser::load_file(DEFAULT_IDL_PATH)
202}